Skip to content

Commit

Permalink
feat: add support for passing custom preAttributes and `codeAttribu…
Browse files Browse the repository at this point in the history
…tes` options (#10)
  • Loading branch information
dancormier authored Apr 22, 2022
1 parent d7a784d commit 00c8d2c
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
6 changes: 5 additions & 1 deletion src/HighlightPairedShortcode.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
const hljs = require("highlight.js");
const HighlightLinesGroup = require("./HighlightLinesGroup");
const getAttributes = require("./getAttributes");

module.exports = function (content, language, highlightNumbers, options = {}) {
const preAttributes = getAttributes(options.preAttributes);
const codeAttributes = getAttributes(options.codeAttributes);

let highlightedContent;
if (language === "text") {
highlightedContent = content.trim();
Expand All @@ -22,7 +26,7 @@ module.exports = function (content, language, highlightNumbers, options = {}) {
let classString = options.className ? " " + options.className : "";

return (
`<pre class="language-${language}${classString}"><code class="language-${language}${classString}">` +
`<pre class="language-${language}${classString}"${preAttributes}><code class="language-${language}${classString}"${codeAttributes}>` +
lines.join("<br>") +
"</code></pre>"
);
Expand Down
39 changes: 39 additions & 0 deletions src/getAttributes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
function attributeEntryToString([key, value]) {
if (typeof value !== "string" && typeof value !== "number")
throw new Error(
`Attribute "${key}" must have a value of type string or number not "${typeof value}".`
);

return `${key}="${value}"`;
}

/**
* ## Usage
* The function `getAttributes` is used to convert an object, `attributes`, with HTML attributes as keys and the values as the corresponding HTML attribute's values.
* If it is falsey, an empty string will be returned.
*
* ```js
getAttributes({
tabindex: 0,
'data-language': 'JavaScript',
'data-otherStuff': 'value'
}) // => ' tabindex="0" data-language="JavaScript" data-otherStuff="value"'
```
*
* @param {{[s: string]: string | number}} attributes An object with key-value pairs that represent attributes.
* @returns {string} A string containing the above HTML attributes preceded by a single space.
*/
function getAttributes(attributes) {
if (!attributes) {
return "";
} else if (typeof attributes === "object") {
const formattedAttributes = Object.entries(attributes).map(
attributeEntryToString
);
return formattedAttributes.length ? ` ${formattedAttributes.join(" ")}` : "";
} else if (typeof attributes === "string") {
throw new Error("Syntax highlighter plugin custom attributes on <pre> and <code> must be an object. Received: " + JSON.stringify(attributes));
}
}

module.exports = getAttributes;
6 changes: 5 additions & 1 deletion src/markdownSyntaxHighlightOptions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
const hljs = require("highlight.js");
const HighlightLinesGroup = require("./HighlightLinesGroup");
const getAttributes = require("./getAttributes");

module.exports = function (options = {}) {
const preAttributes = getAttributes(options.preAttributes);
const codeAttributes = getAttributes(options.codeAttributes);

return function (str, language) {
if (!language) {
// empty string means defer to the upstream escaping code built into markdown lib.
Expand Down Expand Up @@ -34,7 +38,7 @@ module.exports = function (options = {}) {

let classString = options.className ? " " + options.className : "";

return `<pre class="language-${language}${classString}"><code class="language-${language}${classString}">${lines.join(
return `<pre class="language-${language}${classString}"${preAttributes}><code class="language-${language}${classString}"${codeAttributes}>${lines.join(
"<br>"
)}</code></pre>`;
};
Expand Down

0 comments on commit 00c8d2c

Please sign in to comment.