diff --git a/CHANGES.md b/CHANGES.md
index e64932fdc4..c0fadbf799 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -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][]
diff --git a/src/languages/dart.js b/src/languages/dart.js
index cf198cc8ca..bbaa94760a 100644
--- a/src/languages/dart.js
+++ b/src/languages/dart.js
@@ -92,7 +92,8 @@ function(hljs) {
hljs.COMMENT(
'/\\*\\*',
'\\*/', {
- subLanguage: 'markdown'
+ subLanguage: 'markdown',
+ relevance:0
}
),
hljs.COMMENT(
@@ -102,6 +103,7 @@ function(hljs) {
subLanguage: 'markdown',
begin: '.',
end: '$',
+ relevance:0
}]
}
),
diff --git a/src/languages/markdown.js b/src/languages/markdown.js
index 7f56f771e0..e84cf9bc35 100644
--- a/src/languages/markdown.js
+++ b/src/languages/markdown.js
@@ -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
]
};
}
diff --git a/test/markup/markdown/bold_italics.expect.txt b/test/markup/markdown/bold_italics.expect.txt
new file mode 100644
index 0000000000..fee002a4a5
--- /dev/null
+++ b/test/markup/markdown/bold_italics.expect.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**
diff --git a/test/markup/markdown/bold_italics.txt b/test/markup/markdown/bold_italics.txt
new file mode 100644
index 0000000000..2b72d45cdd
--- /dev/null
+++ b/test/markup/markdown/bold_italics.txt
@@ -0,0 +1,18 @@
+_Italic_
+*Italic*
+__Bold__
+**Bold**
+*Is __Combined__*
+__Bold *then italic*__
+**Bold _then italic_**
+**Bold and
**
+**_[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**
diff --git a/test/markup/markdown/code.expect.txt b/test/markup/markdown/code.expect.txt
index 881ec4420e..c50bd78a60 100644
--- a/test/markup/markdown/code.expect.txt
+++ b/test/markup/markdown/code.expect.txt
@@ -1,8 +1,38 @@
- var code = true;
-
+ 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`.
diff --git a/test/markup/markdown/code.txt b/test/markup/markdown/code.txt
index d9bed99184..e095534bc0 100644
--- a/test/markup/markdown/code.txt
+++ b/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`.
diff --git a/test/markup/markdown/list.expect.txt b/test/markup/markdown/list.expect.txt
index 497d464750..64b2341b18 100644
--- a/test/markup/markdown/list.expect.txt
+++ b/test/markup/markdown/list.expect.txt
@@ -1,5 +1,5 @@
-- this is a list
-- this is another
- - nested list
- - another nested
- * nested alternative
+- this is a list
+- this is another
+ - nested list
+ - another nested
+ * nested alternative
diff --git a/test/markup/markdown/sections.expect.txt b/test/markup/markdown/sections.expect.txt
new file mode 100644
index 0000000000..36093ec8a7
--- /dev/null
+++ b/test/markup/markdown/sections.expect.txt
@@ -0,0 +1,11 @@
+# hello world
+
+## hello world
+
+hello world
+===========
+
+*hello world* or [google](link)
+===========
+
+# *hello world* or [google](link)
diff --git a/test/markup/markdown/sections.txt b/test/markup/markdown/sections.txt
new file mode 100644
index 0000000000..2dfe138e9f
--- /dev/null
+++ b/test/markup/markdown/sections.txt
@@ -0,0 +1,12 @@
+# hello world
+
+## hello world
+
+hello world
+===========
+
+*hello world* or [google](link)
+===========
+
+# *hello world* or [google](link)
+