Skip to content

Commit

Permalink
Standardize variable declaration (#743)
Browse files Browse the repository at this point in the history
We use <span> to declare variables in include and global variables.

<span> variables are difficult to differentiate from actual <span>
tag uses. Furthermore, in places where this differentiation is
important (e.g. pages where <span>s are extremely common), we are
forced to use <variable> tags, rather than <span> tags. This results in
two different (and confusing) ways of declaring variables.

Let's standardize all variable declaration to use <variable> instead
of <span>.

The processing of <span> variables are currently left intact, but
they are deprecated and should be removed in a subsequent release.
  • Loading branch information
jamos-tay authored and yamgent committed Mar 7, 2019
1 parent 246e60d commit c6845fc
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 78 deletions.
30 changes: 15 additions & 15 deletions docs/_markbind/variables.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<span id="showBaseUrlCode">
<variable name="showBaseUrlCode">
<code>{<span></span>{ baseUrl }}</code>
</span>
</variable>

<span id="showBaseUrlText">{<span></span>{ baseUrl }}</span>
<variable name="showBaseUrlText">{<span></span>{ baseUrl }}</variable>

<span id="markbind_blue">#00B0F0</span>
<variable name="markbind_blue">#00B0F0</variable>

<span id="icon_arrow_down">:fas-arrow-down:</span>
<span id="icon_arrow_right">:fas-arrow-right:</span>
<span id="icon_check_blue"><font color="{{ markbind_blue }}">:fas-check-circle:</font></span>
<span id="icon_bulb_blue"><font color="{{ markbind_blue }}">:fas-lightbulb:</font></span>
<span id="icon_dislike">:fas-thumbs-down:</span>
<span id="icon_example"><big><span class='badge badge-pill badge-light' style="background-color: #d9d9d9; color: #737373; position:relative; left:-10px">Example:</span></big></span>
<span id="icon_examples"><big><span class='badge badge-pill badge-light' style="background-color: #d9d9d9; color: #737373; position:relative; left:-10px">Examples:</span></big></span>
<span id="icon_info">:fas-info-circle:</span>
<span id="icon_ticked">:far-check-square:</span>
<variable name="icon_arrow_down">:fas-arrow-down:</variable>
<variable name="icon_arrow_right">:fas-arrow-right:</variable>
<variable name="icon_check_blue"><font color="{{ markbind_blue }}">:fas-check-circle:</font></variable>
<variable name="icon_bulb_blue"><font color="{{ markbind_blue }}">:fas-lightbulb:</font></variable>
<variable name="icon_dislike">:fas-thumbs-down:</variable>
<variable name="icon_example"><big><span class='badge badge-pill badge-light' style="background-color: #d9d9d9; color: #737373; position:relative; left:-10px">Example:</span></big></variable>
<variable name="icon_examples"><big><span class='badge badge-pill badge-light' style="background-color: #d9d9d9; color: #737373; position:relative; left:-10px">Examples:</span></big></variable>
<variable name="icon_info">:fas-info-circle:</variable>
<variable name="icon_ticked">:far-check-square:</variable>

<span id="link_live_preview">[live preview]({{ baseUrl }}/userGuide/glossary.html#live-preview)</span>
<variable name="link_live_preview">[live preview]({{ baseUrl }}/userGuide/glossary.html#live-preview)</variable>

<span id="tooltip_root_directory"><tooltip content="The directory that contains all the project files. It is also the directory in which the `site.json` configuration file is located.">root directory</tooltip></span>
<variable name="tooltip_root_directory"><tooltip content="The directory that contains all the project files. It is also the directory in which the `site.json` configuration file is located.">root directory</tooltip></variable>

6 changes: 3 additions & 3 deletions docs/userGuide/syntax/includes.mbdf
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ In other words, **`<include>` interprets the reused code relative to the origina

```html
<include src="article.md">
<span id="title">My Title</span>
<span id="author">John Doe</span>
<variable name="title">My Title</variable>
<variable name="author">John Doe</variable>
</include>
```

Expand Down Expand Up @@ -259,7 +259,7 @@ It needs to be used as follows:

```markdown
<include src="foo.md#bar" boilerplate inline trim>
<span id="x">5</span>
<variable name="x">5</variable>
</include>
```
</span>
32 changes: 16 additions & 16 deletions docs/userGuide/syntax/variables.mbdf
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@

### Global Variables

**Global variables are to be defined in the `_markbind/variables.md` file.** Each variable must have an `id` and the value can be any MarkBind-compliant code fragment. The `id` should not contain `-` and `.`. For example, `search-option` and `search.options` are not allowed.
**Global variables are to be defined in the `_markbind/variables.md` file.** Each variable must have an `name` and the value can be any MarkBind-compliant code fragment. The `name` should not contain `-` and `.`. For example, `search-option` and `search.options` are not allowed.

<div class="indented">

{{ icon_example }} Here's how you can define two variables `year` and `options`:

```html
<span id="year">2018</span>
<variable name="year">2018</variable>

<span id="options">
<variable name="options">
* yes
* no
* maybe
</span>
</variable>
```
</div>

Expand Down Expand Up @@ -111,15 +111,15 @@ Note: These variables will not be applied to [`<include>` files]({{ baseUrl }}/u
<div class="indented">

{{ icon_example }} This variable uses a built-in variable:<br>
<code>\<span id="time">{<span></span>{ timestamp }}\</span></code>
`<variable name="time">`<code>{<span></span>{ timestamp }}</code>`</variable>`

Here, the second variable will be assigned the contents of the first variable.<br>
<code>\<span id="first">This is the first variable.\</span></code><br>
<code>\<span id="second">{<span></span>{ first }}\</span></code><br>
`<variable name="first">`<code>This is the first variable.</code>`</variable>`<br>
`<variable name="second">`<code>{<span></span>{ first }}</code>`</variable>`<br>

This will not work, as the `fourth` variable is declared _below_ the line that refers to it.<br>
<code>\<span id="third">{<span></span>{ fourth }}\</span></code> :x:<br>
<code>\<span id="fourth">This is the fourth variable.\</span></code>
`<variable name="third">`<code>{<span></span>{ fourth }}</code>`</variable>` :x:<br>
`<variable name="fourth">`<code>This is the fourth variable.</code>`</variable>`
</div>

Note that if the variable being referenced contains HTML tags, MarkBind may escape the tags and render it literally.
Expand All @@ -128,9 +128,9 @@ Note that if the variable being referenced contains HTML tags, MarkBind may esca

{{ icon_example }} If we declare the variables as follows,<br>

<code>\<span id="note">\<span style="color: blue">Note: \</span>\</span></code><br>
<code>\<span id="note_2">{<span></span>{ note }}\</span></code><br>
<code>\<span id="const_note">{<span></span>{ note_2 }} This is a constant.\</span></code>
`<variable name="note">`<code>\<span style="color: blue">Note: \</span></code>`</variable>`<br>
`<variable name="note_2">`<code>{<span></span>{ note }}</code>`</variable>`<br>
`<variable name="const_note">`<code>{<span></span>{ note_2 }} This is a constant.</code>`</variable>`

the result will be,<br>

Expand All @@ -143,9 +143,9 @@ You must use the `safe` filter when using such variables:

{{ icon_example }} If we use the safe filter for the second variable:<br>

<code>\<span id="note">\<span style="color: blue">Note: \</span>\</span></code><br>
<code>\<span id="note_2">{<span></span>{ note | safe }}\</span></code><br>
<code>\<span id="const_note">{<span></span>{ note_2 }} This is a constant.\</span></code>
`<variable name="note">`<code>\<span style="color: blue">Note: \</span></code>`</variable>`<br>
`<variable name="note_2">`<code>{<span></span>{ note | safe }}</code>`</variable>`<br>
`<variable name="const_note">`<code>{<span></span>{ note_2 }} This is a constant.</code>`</variable>`

<code>{<span></span>{ const_note }}</code> :fas-arrow-right: <span style="color: blue">Note: </span> This is a constant.
</div>
Expand All @@ -156,7 +156,7 @@ Global variables:

`_markbind/variables.md`:
```html
<span id="year">2018</span>
<variable name="year">2018</span>
```

<code>The year was {<span></span>{ year }}.</code>
Expand Down
10 changes: 5 additions & 5 deletions src/Site.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ const LAYOUT_SCRIPTS_DEFAULT = 'MarkBind.afterSetup(() => {\n'
+ ' // Include code to be called after MarkBind setup here.\n'
+ '});\n';

const USER_VARIABLES_DEFAULT = '<span id="example">\n'
const USER_VARIABLES_DEFAULT = '<variable name="example">\n'
+ 'To inject this HTML segment in your markbind files, use {{ example }} where you want to place it.\n'
+ 'More generally, surround the segment\'s id with double curly braces.\n'
+ '</span>';
+ '</variable>';

const MARKBIND_WEBSITE_URL = 'https://markbind.org/';
const MARKBIND_LINK_HTML = `<a href='${MARKBIND_WEBSITE_URL}'>MarkBind ${CLI_VERSION}</a>`;
Expand Down Expand Up @@ -481,11 +481,11 @@ Site.prototype.collectUserDefinedVariablesMap = function () {
this.userDefinedVariablesMap[base] = userDefinedVariables;

const $ = cheerio.load(content);
$.root().children().each(function () {
const id = $(this).attr('id');
$('variable,span').each(function () {
const name = $(this).attr('name') || $(this).attr('id');
// Process the content of the variable with nunjucks, in case it refers to other variables.
const html = nunjucks.renderString($(this).html(), userDefinedVariables);
userDefinedVariables[id] = html;
userDefinedVariables[name] = html;
});
});
};
Expand Down
11 changes: 6 additions & 5 deletions src/lib/markbind/src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,18 @@ function extractIncludeVariables(includeElement, contextVariables) {
});
if (includeElement.children) {
includeElement.children.forEach((child) => {
if (child.name !== 'span') {
if (child.name !== 'variable' && child.name !== 'span') {
return;
}
if (!child.attribs.id) {
const variableName = child.attribs.name || child.attribs.id;
if (!variableName) {
// eslint-disable-next-line no-console
console.warn(`Missing reference in ${includeElement.attribs[ATTRIB_CWF]}\n`
+ `Missing 'id' in variable for ${includeElement.attribs.src} include.`);
+ `Missing 'name' or 'id' in variable for ${includeElement.attribs.src} include.`);
return;
}
if (!includedVariables[child.attribs.id]) {
includedVariables[child.attribs.id] = cheerio.html(child.children);
if (!includedVariables[variableName]) {
includedVariables[variableName] = cheerio.html(child.children);
}
});
}
Expand Down
18 changes: 9 additions & 9 deletions test/functional/test_site/_markbind/variables.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<span id="referenced_value">This variable can be referenced.</span>
<span id="finalized_value">{{referenced_value}}</span>
<variable name="referenced_value">This variable can be referenced.</variable>
<variable name="finalized_value">{{referenced_value}}</variable>

<span id="reference_level_1">References can be several levels deep.</span>
<span id="reference_level_2">{{reference_level_1}}</span>
<span id="reference_level_3">{{reference_level_2}}</span>
<span id="reference_level_4">{{reference_level_3}}</span>
<variable name="reference_level_1">References can be several levels deep.</variable>
<variable name="reference_level_2">{{reference_level_1}}</variable>
<variable name="reference_level_3">{{reference_level_2}}</variable>
<variable name="reference_level_4">{{reference_level_3}}</variable>

<span id="global_variable_overriding_included_variable">Global Variable Overriding Included Variable</span>
<span id="global_variable">Global Variable</span>
<span id="page_global_variable_overriding_page_variable">Global Variable Overriding Page Variable</span>
<variable name="global_variable_overriding_included_variable">Global Variable Overriding Included Variable</variable>
<variable name="global_variable">Global Variable</variable>
<variable name="page_global_variable_overriding_page_variable">Global Variable Overriding Page Variable</variable>
24 changes: 12 additions & 12 deletions test/functional/test_site/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ tags: ["tag-frontmatter-shown", "tag-included-file", "+tag-exp*", "-tag-exp-hidd
# Test Page Variable and Included Variable Integrations
<variable name="explicitly_included_page_variable">Explicitly Included Page Variable</variable>
<include src="testPageVariablesInInclude.md">
<span id="explicitly_included_page_variable">{{ explicitly_included_page_variable }}</span>
<span id="included_variable">Included Variable</span>
<span id="included_variable_overriding_page_variable">Included Variable Overriding Page Variable</span>
<variable name="explicitly_included_page_variable">{{ explicitly_included_page_variable }}</variable>
<variable name="included_variable">Included Variable</variable>
<variable name="included_variable_overriding_page_variable">Included Variable Overriding Page Variable</variable>
</include>

# Heading with multiple keywords
Expand Down Expand Up @@ -135,15 +135,15 @@ tags: ["tag-frontmatter-shown", "tag-included-file", "+tag-exp*", "-tag-exp-hidd
# Include with custom variables

<include src="testIncludeVariables.md" var-included_variable_as_include_attribute="Included variable as include attribute">
<span id="included_variable">Included variable</span>
<span id="included_variable_with_markdown">__**Included variable with markdown**__</span>
<span id="included_variable_as_attribute">color: blue</span>
<span id="included_variable_as_html_element"><span>Included variable within html element</span></span>
<span id="global_variable_overriding_included_variable">**Should not appear**: Included variable overridden by global variable</span>
<span id="included_variable_inner_overridden">Included variable overriding inner variable</span>
<span id="included_variable_in_outer_included_file">Included variable in outer included file</span>
<span id="included_variable_should_not_leak">**Should not appear**: Included variable should not leak into other files</span>
<span id="included_variable_with_global_variable">Included variable with {{ global_variable }}</span>
<variable name="included_variable">Included variable</variable>
<variable name="included_variable_with_markdown">__**Included variable with markdown**__</variable>
<variable name="included_variable_as_attribute">color: blue</variable>
<variable name="included_variable_as_html_element"><span>Included variable within html element</span></variable>
<variable name="global_variable_overriding_included_variable">**Should not appear**: Included variable overridden by global variable</variable>
<variable name="included_variable_inner_overridden">Included variable overriding inner variable</variable>
<variable name="included_variable_in_outer_included_file">Included variable in outer included file</variable>
<variable name="included_variable_should_not_leak">**Should not appear**: Included variable should not leak into other files</variable>
<variable name="included_variable_with_global_variable">Included variable with {{ global_variable }}</variable>
</include>

# Included variables should not leak into other files
Expand Down
4 changes: 2 additions & 2 deletions test/functional/test_site/testIncludeVariables.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

# Test included variables in included file
<include src="testIncludeVariablesIncludedFile.md">
<span id="included_variable_inner_overridden">**Should not appear**: Included variable overridden by outer variable</span>
<span id="included_variable_should_not_leak_inner">**Should not appear**: Included variable should not leak into other files</span>
<variable name="included_variable_inner_overridden">**Should not appear**: Included variable overridden by outer variable</variable>
<variable name="included_variable_should_not_leak_inner">**Should not appear**: Included variable should not leak into other files</variable>
</include>

# Inner included variables should not leak into other files
Expand Down
18 changes: 9 additions & 9 deletions test/unit/Site.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,10 @@ test('Site resolves variables referencing other variables', async () => {
'src/template/page.ejs': PAGE_EJS,
'site.json': SITE_JSON_DEFAULT,
'_markbind/variables.md':
'<span id="level1">variable</span>'
+ '<span id="level2">{{level1}}</span>'
+ '<span id="level3"><span style="color: blue">Blue text</span></span>'
+ '<span id="level4">{{level3}}</span>',
'<variable name="level1">variable</variable>'
+ '<variable name="level2">{{level1}}</variable>'
+ '<variable name="level3"><span style="color: blue">Blue text</span></variable>'
+ '<variable name="level4">{{level3}}</variable>',
};
fs.vol.fromJSON(json, '');

Expand Down Expand Up @@ -298,11 +298,11 @@ test('Site read correct user defined variables', async () => {
'sub/sub/site.json': SITE_JSON_DEFAULT,
'otherSub/sub/site.json': SITE_JSON_DEFAULT,
'_markbind/variables.md':
'<span id="variable">variable</span>'
+ '<span id="number">2</span>',
'sub/_markbind/variables.md': '<span id="variable">sub_variable</span>',
'sub/sub/_markbind/variables.md': '<span id="number">9999</span>',
'otherSub/sub/_markbind/variables.md': '<span id="variable">other_variable</span>',
'<variable name="variable">variable</variable>'
+ '<variable name="number">2</variable>',
'sub/_markbind/variables.md': '<variable name="variable">sub_variable</variable>',
'sub/sub/_markbind/variables.md': '<variable name="number">9999</variable>',
'otherSub/sub/_markbind/variables.md': '<variable name="variable">other_variable</variable>',
};
fs.vol.fromJSON(json, '');

Expand Down
4 changes: 2 additions & 2 deletions test/unit/utils/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ module.exports.SITE_NAV_MD_DEFAULT = '<navigation>\n'
+ '* [Home :glyphicon-home:]({{baseUrl}}/index.html)\n'
+ '</navigation>\n';

module.exports.USER_VARIABLES_DEFAULT = '<span id="example">\n'
module.exports.USER_VARIABLES_DEFAULT = '<variable name="example">\n'
+ 'To inject this HTML segment in your markbind files, use {{ example }} where you want to place it.\n'
+ 'More generally, surround the segment\'s id with double curly braces.\n'
+ '</span>';
+ '</variable>';

0 comments on commit c6845fc

Please sign in to comment.