diff --git a/asset/css/markbind.css b/asset/css/markbind.css index 92328d46d5..99bccd71de 100644 --- a/asset/css/markbind.css +++ b/asset/css/markbind.css @@ -24,6 +24,26 @@ pre > code.hljs { border-radius: 5px; } +.code-block { + position: relative; +} + +.code-block > .code-block-lang { + background-color: #b4b4b9; + border-radius: 0.25rem; + color: #f8f8ff; + display: inline-block; + font-size: 75%; + line-height: 1; + padding: 0.25em 0.4em; + position: absolute; + right: 0.3em; + text-align: center; + top: 0.4em; + vertical-align: baseline; + white-space: nowrap; +} + kbd { background-color: #fafbfc; border: 1px solid #c6cbd1; diff --git a/docs/userGuide/syntax/code.mbdf b/docs/userGuide/syntax/code.mbdf index 18830a0b5a..9474779022 100644 --- a/docs/userGuide/syntax/code.mbdf +++ b/docs/userGuide/syntax/code.mbdf @@ -1,6 +1,6 @@ ## Code -MarkBind can provide syntax coloring for a code block (aka _Fenced Code Blocks_). +MarkBind can provide syntax coloring for a code block (aka _Fenced Code Blocks_). The language of the code block is labelled as well. diff --git a/src/lib/markbind/src/lib/markdown-it/index.js b/src/lib/markbind/src/lib/markdown-it/index.js index 15c8d17e4a..f60ea06a21 100644 --- a/src/lib/markbind/src/lib/markdown-it/index.js +++ b/src/lib/markbind/src/lib/markdown-it/index.js @@ -20,11 +20,11 @@ const slugify = require('@sindresorhus/slugify'); // markdown-it plugins markdownIt.use(require('markdown-it-mark')) .use(require('markdown-it-ins')) - .use(require('markdown-it-anchor'), {slugify: (str) => slugify(str, { decamelize: false })}) - .use(require('markdown-it-imsize'), {autofill: false}) + .use(require('markdown-it-anchor'), { slugify: (str) => slugify(str, { decamelize: false }) }) + .use(require('markdown-it-imsize'), { autofill: false }) .use(require('markdown-it-table-of-contents')) - .use(require('markdown-it-task-lists'), {enabled: true}) - .use(require('markdown-it-linkify-images'), {imgClass: 'img-fluid'}) + .use(require('markdown-it-task-lists'), { enabled: true }) + .use(require('markdown-it-linkify-images'), { imgClass: 'img-fluid' }) .use(require('markdown-it-attrs')) .use(require('./markdown-it-dimmed')) .use(require('./markdown-it-radio-button')) @@ -43,6 +43,61 @@ markdownIt.renderer.rules.table_close = (tokens, idx) => { return ''; }; +// rewritten markdown-it renderer.js rule to add a div containing the language of the code block +markdownIt.renderer.rules.fence = (tokens, idx, options, env, slf) => { + var token = tokens[idx], + info = token.info ? markdownIt.utils.unescapeAll(token.info).trim() : '', + langName = '', + highlighted, i, tmpAttrs, tmpToken; + + if (info) { + langName = info.split(/\s+/g)[0]; + } + + if (options.highlight) { + highlighted = options.highlight(token.content, langName) || escapeHtml(token.content); + } else { + highlighted = escapeHtml(token.content); + } + + if (highlighted.indexOf('' + highlighted + + '
' + langName + '
' + + '\n'; + } + return highlighted + '\n'; + } + + // If language exists, inject class gently, without modifying original token. + // May be, one day we will add .clone() for token and simplify this part, but + // now we prefer to keep things local. + if (info) { + i = token.attrIndex('class'); + tmpAttrs = token.attrs ? token.attrs.slice() : []; + + if (i < 0) { + tmpAttrs.push(['class', options.langPrefix + langName]); + } else { + tmpAttrs[i][1] += ' ' + options.langPrefix + langName; + } + + // Fake token just to render attributes + tmpToken = { + attrs: tmpAttrs + }; + + return '
'
+      + highlighted
+      + '
\n'; + } + + + return '
'
+    + highlighted
+    + '
\n'; +} + // highlight inline code markdownIt.renderer.rules.code_inline = (tokens, idx, options, env, slf) => { const token = tokens[idx]; diff --git a/test/functional/test_site/expected/markbind/css/markbind.css b/test/functional/test_site/expected/markbind/css/markbind.css index 92328d46d5..99bccd71de 100644 --- a/test/functional/test_site/expected/markbind/css/markbind.css +++ b/test/functional/test_site/expected/markbind/css/markbind.css @@ -24,6 +24,26 @@ pre > code.hljs { border-radius: 5px; } +.code-block { + position: relative; +} + +.code-block > .code-block-lang { + background-color: #b4b4b9; + border-radius: 0.25rem; + color: #f8f8ff; + display: inline-block; + font-size: 75%; + line-height: 1; + padding: 0.25em 0.4em; + position: absolute; + right: 0.3em; + text-align: center; + top: 0.4em; + vertical-align: baseline; + white-space: nowrap; +} + kbd { background-color: #fafbfc; border: 1px solid #c6cbd1; diff --git a/test/functional/test_site/expected/requirements/UserStories._include_.html b/test/functional/test_site/expected/requirements/UserStories._include_.html index 15a1fdbce6..edd61820b8 100644 --- a/test/functional/test_site/expected/requirements/UserStories._include_.html +++ b/test/functional/test_site/expected/requirements/UserStories._include_.html @@ -2,10 +2,13 @@

A commonly used format for writing user stories is:
As a <use type/role> I can <function> so that <benefit>

Here are some examples of user stories for the IVLE system:

-
* As a student, I can download files uploaded by lecturers, so that I can get my own copy of the files.
+
+
* As a student, I can download files uploaded by lecturers, so that I can get my own copy of the files.
 * As a lecturer, I can create discussion forums, so that students can discuss things online.
 * As a tutor, I can print attendance sheets, so that I can take attendance during the class.
 
+
bat
+

The <benefit> can be omitted if it is obvious. E.g. As a tutor, I can print attendance sheets. User stories are mainly used for early estimation and scheduling purposes.

According to this diff --git a/test/functional/test_site_algolia_plugin/expected/markbind/css/markbind.css b/test/functional/test_site_algolia_plugin/expected/markbind/css/markbind.css index 92328d46d5..99bccd71de 100644 --- a/test/functional/test_site_algolia_plugin/expected/markbind/css/markbind.css +++ b/test/functional/test_site_algolia_plugin/expected/markbind/css/markbind.css @@ -24,6 +24,26 @@ pre > code.hljs { border-radius: 5px; } +.code-block { + position: relative; +} + +.code-block > .code-block-lang { + background-color: #b4b4b9; + border-radius: 0.25rem; + color: #f8f8ff; + display: inline-block; + font-size: 75%; + line-height: 1; + padding: 0.25em 0.4em; + position: absolute; + right: 0.3em; + text-align: center; + top: 0.4em; + vertical-align: baseline; + white-space: nowrap; +} + kbd { background-color: #fafbfc; border: 1px solid #c6cbd1; diff --git a/test/functional/test_site_convert/expected/markbind/css/markbind.css b/test/functional/test_site_convert/expected/markbind/css/markbind.css index 92328d46d5..99bccd71de 100644 --- a/test/functional/test_site_convert/expected/markbind/css/markbind.css +++ b/test/functional/test_site_convert/expected/markbind/css/markbind.css @@ -24,6 +24,26 @@ pre > code.hljs { border-radius: 5px; } +.code-block { + position: relative; +} + +.code-block > .code-block-lang { + background-color: #b4b4b9; + border-radius: 0.25rem; + color: #f8f8ff; + display: inline-block; + font-size: 75%; + line-height: 1; + padding: 0.25em 0.4em; + position: absolute; + right: 0.3em; + text-align: center; + top: 0.4em; + vertical-align: baseline; + white-space: nowrap; +} + kbd { background-color: #fafbfc; border: 1px solid #c6cbd1; diff --git a/test/functional/test_site_templates/test_default/expected/index.html b/test/functional/test_site_templates/test_default/expected/index.html index 937f61d7f5..56d66560d3 100644 --- a/test/functional/test_site_templates/test_default/expected/index.html +++ b/test/functional/test_site_templates/test_default/expected/index.html @@ -88,10 +88,13 @@

Heading 1

A code example:

-
<foo>
+        
+
<foo>
   <bar type="name">goo</bar>
 </foo>
 
+
html
+

Sub Heading 1.1

A tooltip, a diff --git a/test/functional/test_site_templates/test_default/expected/markbind/css/markbind.css b/test/functional/test_site_templates/test_default/expected/markbind/css/markbind.css index 92328d46d5..99bccd71de 100644 --- a/test/functional/test_site_templates/test_default/expected/markbind/css/markbind.css +++ b/test/functional/test_site_templates/test_default/expected/markbind/css/markbind.css @@ -24,6 +24,26 @@ pre > code.hljs { border-radius: 5px; } +.code-block { + position: relative; +} + +.code-block > .code-block-lang { + background-color: #b4b4b9; + border-radius: 0.25rem; + color: #f8f8ff; + display: inline-block; + font-size: 75%; + line-height: 1; + padding: 0.25em 0.4em; + position: absolute; + right: 0.3em; + text-align: center; + top: 0.4em; + vertical-align: baseline; + white-space: nowrap; +} + kbd { background-color: #fafbfc; border: 1px solid #c6cbd1; diff --git a/test/functional/test_site_templates/test_minimal/expected/markbind/css/markbind.css b/test/functional/test_site_templates/test_minimal/expected/markbind/css/markbind.css index 92328d46d5..99bccd71de 100644 --- a/test/functional/test_site_templates/test_minimal/expected/markbind/css/markbind.css +++ b/test/functional/test_site_templates/test_minimal/expected/markbind/css/markbind.css @@ -24,6 +24,26 @@ pre > code.hljs { border-radius: 5px; } +.code-block { + position: relative; +} + +.code-block > .code-block-lang { + background-color: #b4b4b9; + border-radius: 0.25rem; + color: #f8f8ff; + display: inline-block; + font-size: 75%; + line-height: 1; + padding: 0.25em 0.4em; + position: absolute; + right: 0.3em; + text-align: center; + top: 0.4em; + vertical-align: baseline; + white-space: nowrap; +} + kbd { background-color: #fafbfc; border: 1px solid #c6cbd1;