Skip to content

Commit

Permalink
enh(markdown) much improved markdown support (highlightjs#2382)
Browse files Browse the repository at this point in the history
* basic nested bold/italics support
* bold and italic can contain links and html
* blockquote can contain other markup
* language (dart) should not get bonus points for embedded markdown
* much better code block support
* test emphasis vs bullets
* remove space from end of bullets
  • Loading branch information
joshgoebel authored and taufik-nurrohman committed Feb 18, 2020
1 parent fd47bd9 commit 0db52b3
Show file tree
Hide file tree
Showing 10 changed files with 259 additions and 97 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Expand Up @@ -15,6 +15,8 @@ Core Changes:

Language Improvements:

- (markdown) much improved code block support (#2382) [Josh Goebel][]
- (markdown) improve bold/italic nesting (#2382) [Josh Goebel][]
- enh(csharp) Support `where` keyword as class constraint (#2378) [Josh Goebel][]
- enh(csharp) Allow reference path in class inheritance lists (#2378) [Josh Goebel][]
- enh(csharp) Add generic modifiers (in, out) (#2378) [Josh Goebel][]
Expand Down
4 changes: 3 additions & 1 deletion src/languages/dart.js
Expand Up @@ -92,7 +92,8 @@ function(hljs) {
hljs.COMMENT(
'/\\*\\*',
'\\*/', {
subLanguage: 'markdown'
subLanguage: 'markdown',
relevance:0
}
),
hljs.COMMENT(
Expand All @@ -102,6 +103,7 @@ function(hljs) {
subLanguage: 'markdown',
begin: '.',
end: '$',
relevance:0
}]
}
),
Expand Down
217 changes: 128 additions & 89 deletions src/languages/markdown.js
Expand Up @@ -7,109 +7,148 @@ Category: common, markup
*/

function(hljs) {
return {
aliases: ['md', 'mkdown', 'mkd'],
contains: [
// highlight headers
{
className: 'section',
variants: [
{ begin: '^#{1,6}', end: '$' },
{ begin: '^.+?\\n[=-]{2,}$' }
]
},
// inline html
INLINE_HTML = {
begin: '<', end: '>',
subLanguage: 'xml',
relevance: 0
};
HORIZONTAL_RULE = {
begin: '^[-\\*]{3,}', end: '$'
};
CODE = {
className: 'code',
variants: [
// TODO: fix to allow these to work with sublanguage also
{ begin: '(`{3,})(.|\\n)*?\\1`*[ ]*', },
{ begin: '(~{3,})(.|\\n)*?\\1~*[ ]*', },
// needed to allow markdown as a sublanguage to work
{ begin: '```', end: '```+[ ]*$' },
{ begin: '~~~', end: '~~~+[ ]*$' },
{ begin: '`.+?`' },
{
begin: '<', end: '>',
subLanguage: 'xml',
begin: '(?=^( {4}|\\t))',
// use contains to gobble up multiple lines to allow the block to be whatever size
// but only have a single open/close tag vs one per line
contains: [
{ begin: '^( {4}|\\t)', end: '(\\n)$' }
],
relevance: 0
},
// lists (indicators only)
}
]
};
LIST = {
className: 'bullet',
begin: '^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)',
end: '\\s+',
excludeEnd: true
};
LINK_REFERENCE = {
begin: /^\[[^\n]+\]:/,
returnBegin: true,
contains: [
{
className: 'bullet',
begin: '^\\s*([*+-]|(\\d+\\.))\\s+'
className: 'symbol',
begin: /\[/, end: /\]/,
excludeBegin: true, excludeEnd: true
},
// strong segments
{
className: 'strong',
begin: '[*_]{2}.+?[*_]{2}'
},
// emphasis segments
className: 'link',
begin: /:\s*/, end: /$/,
excludeBegin: true
}
]
};
LINK = {
begin: '\\[.+?\\][\\(\\[].*?[\\)\\]]',
returnBegin: true,
contains: [
{
className: 'emphasis',
variants: [
{ begin: '\\*.+?\\*' },
{ begin: '_.+?_'
, relevance: 0
}
]
className: 'string',
begin: '\\[', end: '\\]',
excludeBegin: true,
returnEnd: true,
relevance: 0
},
// blockquotes
{
className: 'quote',
begin: '^>\\s+', end: '$'
className: 'link',
begin: '\\]\\(', end: '\\)',
excludeBegin: true, excludeEnd: true
},
// code snippets
{
className: 'code',
variants: [
{
begin: '^```\\w*\\s*$', end: '^```[ ]*$'
},
{
begin: '`.+?`'
},
{
begin: '^( {4}|\\t)', end: '$',
relevance: 0
}
]
},
// horizontal rules
{
begin: '^[-\\*]{3,}', end: '$'
},
// using links - title and link
className: 'symbol',
begin: '\\]\\[', end: '\\]',
excludeBegin: true, excludeEnd: true
}
],
relevance: 10
};
BOLD = {
className: 'strong',
contains: [],
variants: [
{begin: /_{2}/, end: /_{2}/ },
{begin: /\*{2}/, end: /\*{2}/ }
]
};
ITALIC = {
className: 'emphasis',
contains: [],
variants: [
{ begin: /\*(?!\*)/, end: /\*/ },
{ begin: /_(?!_)/, end: /_/, relevance: 0},
]
};
BOLD.contains.push(ITALIC);
ITALIC.contains.push(BOLD);

CONTAINABLE = [
INLINE_HTML,
LINK
];

BOLD.contains = BOLD.contains.concat(CONTAINABLE);
ITALIC.contains = ITALIC.contains.concat(CONTAINABLE);

CONTAINABLE = CONTAINABLE.concat(BOLD,ITALIC);

HEADER = {
className: 'section',
variants: [
{
begin: '\\[.+?\\][\\(\\[].*?[\\)\\]]',
returnBegin: true,
contains: [
{
className: 'string',
begin: '\\[', end: '\\]',
excludeBegin: true,
returnEnd: true,
relevance: 0
},
{
className: 'link',
begin: '\\]\\(', end: '\\)',
excludeBegin: true, excludeEnd: true
},
{
className: 'symbol',
begin: '\\]\\[', end: '\\]',
excludeBegin: true, excludeEnd: true
}
],
relevance: 10
},
begin: '^#{1,6}',
end: '$',
contains: CONTAINABLE
},
{
begin: /^\[[^\n]+\]:/,
returnBegin: true,
begin: '(?=^.+?\\n[=-]{2,}$)',
contains: [
{
className: 'symbol',
begin: /\[/, end: /\]/,
excludeBegin: true, excludeEnd: true
},
{
className: 'link',
begin: /:\s*/, end: /$/,
excludeBegin: true
}
{ begin: '^[=-]*$' },
{ begin: '^', end: "\\n", contains: CONTAINABLE },
]
}
}
]
};

BLOCKQUOTE = {
className: 'quote',
begin: '^>\\s+',
contains: CONTAINABLE,
end: '$',
};

return {
aliases: ['md', 'mkdown', 'mkd'],
contains: [
HEADER,
INLINE_HTML,
LIST,
BOLD,
ITALIC,
BLOCKQUOTE,
CODE,
HORIZONTAL_RULE,
LINK,
LINK_REFERENCE
]
};
}
18 changes: 18 additions & 0 deletions test/markup/markdown/bold_italics.expect.txt
@@ -0,0 +1,18 @@
<span class="hljs-emphasis">_Italic_</span>
<span class="hljs-emphasis">*Italic*</span>
<span class="hljs-strong">__Bold__</span>
<span class="hljs-strong">**Bold**</span>
<span class="hljs-emphasis">*Is <span class="hljs-strong">__Combined__</span>*</span>
<span class="hljs-strong">__Bold <span class="hljs-emphasis">*then italic*</span>__</span>
<span class="hljs-strong">**Bold <span class="hljs-emphasis">_then italic_</span>**</span>
<span class="hljs-strong">**Bold and <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span></span>**</span>
<span class="hljs-strong">**<span class="hljs-emphasis">_[<span class="hljs-string">this</span>](<span class="hljs-link">https://google.com</span>)_</span>**</span>

<span class="hljs-quote">&gt; quoted <span class="hljs-strong">**Bold <span class="hljs-emphasis">_then italic_</span>**</span></span>
<span class="hljs-quote">&gt; <span class="hljs-emphasis">_[<span class="hljs-string">this</span>](<span class="hljs-link">https://google.com</span>)_</span></span>

<span class="hljs-emphasis">*this is a emphasized paragraph*</span>
<span class="hljs-emphasis">*this is too*</span>

<span class="hljs-bullet">*</span> list with a <span class="hljs-emphasis">*italic item*</span>
<span class="hljs-bullet">*</span> list with a <span class="hljs-strong">**bold item**</span>
18 changes: 18 additions & 0 deletions test/markup/markdown/bold_italics.txt
@@ -0,0 +1,18 @@
_Italic_
*Italic*
__Bold__
**Bold**
*Is __Combined__*
__Bold *then italic*__
**Bold _then italic_**
**Bold and <br/>**
**_[this](https://google.com)_**

> quoted **Bold _then italic_**
> _[this](https://google.com)_

*this is a emphasized paragraph*
*this is too*

* list with a *italic item*
* list with a **bold item**
34 changes: 32 additions & 2 deletions test/markup/markdown/code.expect.txt
@@ -1,8 +1,38 @@
<span class="hljs-code"> var code = true;</span>

<span class="hljs-code"> var code = true;
var code = false;
</span>

<span class="hljs-code">```javascript
var code = true;
```</span>

<span class="hljs-code">````md
```
a = 'This is a code block in python'
```
````</span>

<span class="hljs-code">~~~
tilde can be used also (github)
~~~</span>

<span class="hljs-code">~~~~ ruby startline=3 $%@#$
def foo(x)
return 3
end
~~~~~~~</span>

<span class="hljs-code">~~~~~~~something
code here
~~~~~~~</span>

<span class="hljs-code">```
aaa
~~~
```</span>

<span class="hljs-code">```javascript
can be indented
```</span>

Inline <span class="hljs-code">`code`</span>, and <span class="hljs-code">`more code`</span>.
30 changes: 30 additions & 0 deletions test/markup/markdown/code.txt
@@ -1,8 +1,38 @@
var code = true;
var code = false;


```javascript
var code = true;
```

````md
```
a = 'This is a code block in python'
```
````

~~~
tilde can be used also (github)
~~~

~~~~ ruby startline=3 $%@#$
def foo(x)
return 3
end
~~~~~~~

~~~~~~~something
code here
~~~~~~~

```
aaa
~~~
```

```javascript
can be indented
```

Inline `code`, and `more code`.
10 changes: 5 additions & 5 deletions test/markup/markdown/list.expect.txt
@@ -1,5 +1,5 @@
<span class="hljs-bullet">- </span>this is a list
<span class="hljs-bullet">- </span>this is another
<span class="hljs-bullet"> - </span>nested list
<span class="hljs-bullet"> - </span>another nested
<span class="hljs-bullet"> * </span>nested alternative
<span class="hljs-bullet">-</span> this is a list
<span class="hljs-bullet">-</span> this is another
<span class="hljs-bullet"> -</span> nested list
<span class="hljs-bullet"> -</span> another nested
<span class="hljs-bullet"> *</span> nested alternative

0 comments on commit 0db52b3

Please sign in to comment.