Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enh(markdown) much improved markdown support #2382

Merged
merged 11 commits into from Feb 6, 2020
3 changes: 3 additions & 0 deletions CHANGES.md
Expand Up @@ -14,6 +14,8 @@ Core Changes:

Language Improvements:

- (markdown) much improved code block support (#2382) [Josh Goebel][]
- (markdown) improve bold/italic nesting (#2382) [Josh Goebel][]
- (fortran) Add Fortran 2018 keywords and coarray intrinsics (#2361) [Sam Miller][]
- (delphi) highlight hexadecimal, octal, and binary numbers (#2370) [Robert Riebisch]()
- enh(plaintext) added `text` and `txt` as alias (#2360) [Taufik Nurrohman][]
Expand All @@ -22,6 +24,7 @@ Developer Tools:

- none.

[Josh Goebel]: https://github.com/yyyc514
[Sam Miller]: https://github.com/smillerc
[Robert Riebisch]: https://github.com/bttrx
[Taufik Nurrohman]: https://github.com/taufik-nurrohman
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`.