Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion docs/userGuide/syntax/code.mbdf
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ To enable syntax coloring, specify a language next to the backticks before the f
</span>

##### Line numbering
Line numbers are automatically provided by default. To hide line numbers, add the class `no-line-numbers ` to the code block as below
Line numbers are provided by default. To hide line numbers, add the class `no-line-numbers` to the code block as below

<include src="outputBox.md" boilerplate >
<span id="code">
Expand All @@ -61,6 +61,30 @@ Line numbers are automatically provided by default. To hide line numbers, add th
</span>
</include>

You can have your line numbers start with a value other than `1` with the `start-from` attribute.

<include src="outputBox.md" boilerplate >
<span id="code">

```` {.no-line-numbers}
```js {start-from=6}
function add(a, b) {
return a + b;
}
```
````
</span>
<span id="output">

```js {start-from=6}
function add(a, b) {
return a + b;
}
```
</span>
</include>


##### Line highlighting
To highlight lines, add the attribute `highlight-lines` with the line numbers as value, as shown below. You can specify ranges or individual line numbers.

Expand Down
31 changes: 28 additions & 3 deletions src/lib/markbind/src/lib/markdown-it/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ markdownIt.renderer.rules.table_close = (tokens, idx) => {
return '</table></div>';
};

function getAttributeAndDelete(token, attr) {
const index = token.attrIndex(attr);
if (index === -1) {
return undefined;
}
// tokens are stored as an array of two-element-arrays:
// e.g. [ ['highlight-lines', '1,2,3'], ['start-from', '1'] ]
const value = token.attrs[index][1];
token.attrs.splice(index, 1);
return value;
}

// syntax highlight code fences and add line numbers
markdownIt.renderer.rules.fence = (tokens, idx, options, env, slf) => {
const token = tokens[idx];
Expand Down Expand Up @@ -64,18 +76,31 @@ markdownIt.renderer.rules.fence = (tokens, idx, options, env, slf) => {
if (!highlighted) {
lines = markdownIt.utils.escapeHtml(str).split('\n');
}

const startFromOneBased = Math.max(1, parseInt(getAttributeAndDelete(token, 'start-from'), 10) || 1);
const startFromZeroBased = startFromOneBased - 1;

if (startFromOneBased > 1) {
// counter is incremented on each span, so we need to subtract 1
token.attrJoin('style', `counter-reset: line ${startFromZeroBased};`);
}

const highlightLinesInput = token.attrGet('highlight-lines');
const highlightLinesInput = getAttributeAndDelete(token, 'highlight-lines');
let lineNumbersAndRanges = [];
if (highlightLinesInput) {
// example input format: "1,4-7,8,11-55"
// output: [[1],[4,7],[8],[11,55]]
// the output is an array contaning either single line numbers [lineNum] or ranges [start, end]
// ',' delimits either single line numbers (eg: 1) or ranges (eg: 4-7)
highlightLines = highlightLinesInput.split(',');
const highlightLines = highlightLinesInput.split(',');
// if it's the single number, it will just be parsed as an int, (eg: ['1'] --> [1] )
// if it's a range, it will be parsed as as an array of two ints (eg: ['4-7'] --> [4,6])
lineNumbersAndRanges = highlightLines.map(elem => elem.split('-').map(lineNumber => parseInt(lineNumber, 10)));
function parseAndZeroBaseLineNumber(numberString) {
// authors provide line numbers to highlight based on the 'start-from' attribute if it exists
// so we need to shift them all back down to start at 0
return parseInt(numberString, 10) - startFromZeroBased;
}
lineNumbersAndRanges = highlightLines.map(elem => elem.split('-').map(parseAndZeroBaseLineNumber));
}

lines.pop(); // last line is always a single '\n' newline, so we remove it
Expand Down
6 changes: 6 additions & 0 deletions test/functional/test_site/expected/testCodeBlocks.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
<pre><code class="hljs js"><span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fourEmptyLinesBelow</span>(<span class="hljs-params"></span>) </span>{</span><span>&#x200B;</span><span>&#x200B;</span><span>&#x200B;</span><span>&#x200B;</span><span>} <span class="hljs-comment">// four empty lines above</span></span></code></pre>
<p><strong>hljs span spanning multiple lines</strong></p>
<pre><code class="hljs markdown"><span><span class="hljs-strong">*****</span></span><span>-----</span></code></pre>
<p><strong>start-from attr causes inline style to be set</strong></p>
<pre><code style="counter-reset: line 29;" class="hljs markdown"><span><span class="hljs-strong">*****</span></span><span>-----</span></code></pre>
<p><strong>highlight-lines attr causes corresponding lines to have 'highlighted' class</strong></p>
<pre><code class="hljs markdown"><span class="highlighted">1 highlighted</span><span>2</span><span class="highlighted">3 highlighted</span><span>4</span><span class="highlighted">5 highlighted</span><span class="highlighted">6 highlighted</span><span class="highlighted">7 highlighted</span><span class="highlighted">8 highlighted</span><span>9</span><span>10</span></code></pre>
<p><strong>highlight-lines attr with start-from attr cause corresponding lines to have 'highlighted' class based on 'start-from'</strong></p>
<pre><code style="counter-reset: line 10;" class="hljs markdown"><span class="highlighted">11 highlighted</span><span>12</span><span class="highlighted">13 highlighted</span><span>14</span><span class="highlighted">15 highlighted</span><span class="highlighted">16 highlighted</span><span class="highlighted">17 highlighted</span><span class="highlighted">18 highlighted</span><span>19</span><span>20</span></code></pre>
</div>
</div>
<footer>
Expand Down
34 changes: 34 additions & 0 deletions test/functional/test_site/testCodeBlocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,37 @@ function fourEmptyLinesBelow() {
*****
-----
```

**start-from attr causes inline style to be set**
```markdown {start-from=30}
*****
-----
```

**highlight-lines attr causes corresponding lines to have 'highlighted' class**
```markdown {highlight-lines="1,3,5-8"}
1 highlighted
2
3 highlighted
4
5 highlighted
6 highlighted
7 highlighted
8 highlighted
9
10
```

**highlight-lines attr with start-from attr cause corresponding lines to have 'highlighted' class based on 'start-from'**
```markdown {start-from=11 highlight-lines="11,13,15-18"}
11 highlighted
12
13 highlighted
14
15 highlighted
16 highlighted
17 highlighted
18 highlighted
19
20
```