Compare commits
No commits in common. "5f3d7238d9ee8b16fc67994ca4b0d5786c465bfc" and "91e57182f373f3b84f348e5adb94da2ea70abc3e" have entirely different histories.
5f3d7238d9
...
91e57182f3
|
@ -3,9 +3,10 @@ const hasTemplateFormat = require("./src/hasTemplateFormat");
|
||||||
const HighlightPairedShortcode = require("./src/HighlightPairedShortcode");
|
const HighlightPairedShortcode = require("./src/HighlightPairedShortcode");
|
||||||
const LiquidHighlightTag = require("./src/LiquidHighlightTag");
|
const LiquidHighlightTag = require("./src/LiquidHighlightTag");
|
||||||
// const CharacterWrap = require("./src/CharacterWrap");
|
// const CharacterWrap = require("./src/CharacterWrap");
|
||||||
const markdownChroma = require("./src/markdownSyntaxHighlightOptions");
|
const markdownPrismJs = require("./src/markdownSyntaxHighlightOptions");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
// initArguments: { Prism },
|
||||||
configFunction: function (eleventyConfig, options = {}) {
|
configFunction: function (eleventyConfig, options = {}) {
|
||||||
try {
|
try {
|
||||||
eleventyConfig.versionCheck(pkg["11ty"].compatibility);
|
eleventyConfig.versionCheck(pkg["11ty"].compatibility);
|
||||||
|
@ -20,9 +21,9 @@ module.exports = {
|
||||||
theme: "onedark",
|
theme: "onedark",
|
||||||
lineNumbers: false,
|
lineNumbers: false,
|
||||||
/* lineNumbersStyle: "table",*/ /* "table" or "inline" */
|
/* lineNumbersStyle: "table",*/ /* "table" or "inline" */
|
||||||
//alwaysWrapLineHighlights: false,
|
alwaysWrapLineHighlights: false,
|
||||||
// eligible to change the default to \n in a new major version.
|
// eligible to change the default to \n in a new major version.
|
||||||
//lineSeparator: "<br>",
|
lineSeparator: "<br>",
|
||||||
preAttributes: {},
|
preAttributes: {},
|
||||||
codeAttributes: {
|
codeAttributes: {
|
||||||
theme: "onedark",
|
theme: "onedark",
|
||||||
|
@ -51,7 +52,7 @@ module.exports = {
|
||||||
|
|
||||||
if (hasTemplateFormat(options.templateFormats, "md")) {
|
if (hasTemplateFormat(options.templateFormats, "md")) {
|
||||||
// ```js/0,2-3
|
// ```js/0,2-3
|
||||||
eleventyConfig.addMarkdownHighlighter(markdownChroma(options));
|
eleventyConfig.addMarkdownHighlighter(markdownPrismJs(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (hasTemplateFormat(options.templateFormats, "11ty.js")) {
|
// if (hasTemplateFormat(options.templateFormats, "11ty.js")) {
|
||||||
|
|
62
README.md
62
README.md
|
@ -41,65 +41,3 @@ Theme can be set to one of these [themes](https://xyproto.github.io/splash/docs/
|
||||||
|
|
||||||
- `lineNumbers` will add line numbers starting from 1 for each code block.
|
- `lineNumbers` will add line numbers starting from 1 for each code block.
|
||||||
- `lineNumbersStyle` if `table` is used, then code block will use a table to make it easier to drag and select the code.
|
- `lineNumbersStyle` if `table` is used, then code block will use a table to make it easier to drag and select the code.
|
||||||
|
|
||||||
## TO DO
|
|
||||||
|
|
||||||
- [✅] Support `.liquid` files
|
|
||||||
- [] Add passed in `code` and `pre` atributes into returned html from chroma
|
|
||||||
- [] Add testing
|
|
||||||
- [] Add improve regex for line numbers
|
|
||||||
- [] Add other arguments that chroma can take (`--html-tab-width`, `--html-highlight-style`, maybe `--html-linkable-lines`)
|
|
||||||
|
|
||||||
## Example output
|
|
||||||
|
|
||||||
Highlight line 1 and 3
|
|
||||||
|
|
||||||
````
|
|
||||||
```js
|
|
||||||
let multilineString = `
|
|
||||||
this is the first line
|
|
||||||
this is the middle line
|
|
||||||
this is the last line
|
|
||||||
`;
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
![](./images/hightlight-first-and-third-lines.png)
|
|
||||||
|
|
||||||
Line numbers shown and highlighting range of lines 3 through 6
|
|
||||||
|
|
||||||
````
|
|
||||||
```js/3:6/lineNumbers
|
|
||||||
let multilineString = `
|
|
||||||
this is the first line
|
|
||||||
this is the second line
|
|
||||||
this is the third line
|
|
||||||
this is the fourth line
|
|
||||||
this is the fifth line
|
|
||||||
this is the sixth line
|
|
||||||
this is the seventh line
|
|
||||||
this is the eighth line
|
|
||||||
`;
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
![](./images/highlight-range-with-line-numbers.png)
|
|
||||||
|
|
||||||
Line numbers shown, line numbers set to start at 200, and highlighting range of lines 202 through 204
|
|
||||||
|
|
||||||
````
|
|
||||||
```js/202:204/lineNumbers/table/lineNumbersStart=200
|
|
||||||
let multilineString = `
|
|
||||||
this is the first line
|
|
||||||
this is the second line
|
|
||||||
this is the third line
|
|
||||||
this is the fourth line
|
|
||||||
this is the fifth line
|
|
||||||
this is the sixth line
|
|
||||||
this is the seventh line
|
|
||||||
this is the eighth line
|
|
||||||
`;
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
![](./images/highlight-range-with-line-numbers-arbitary-start-number.png)
|
|
|
@ -5,64 +5,65 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title></title>
|
<title></title>
|
||||||
<link rel="stylesheet" href="../test.css">
|
<link rel="stylesheet" href="../test.css">
|
||||||
|
<link rel="stylesheet" href="../prism-theme.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
Just JS
|
Just JS
|
||||||
{% highlight js %}
|
{% highlight js %}
|
||||||
function myFunction() {
|
function myFunction() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Just JS multiline
|
Just JS multiline
|
||||||
|
|
||||||
{% highlight js %}
|
{% highlight js %}
|
||||||
let multilineString = `
|
let multilineString = `
|
||||||
this is the first line
|
this is the first line
|
||||||
this is the middle line
|
this is the middle line
|
||||||
this is the last line
|
this is the last line
|
||||||
`;
|
`;
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
JS + Linehighlight
|
JS + Linehighlight
|
||||||
{% highlight js 1,3 %}
|
{% highlight js 1,3 %}
|
||||||
let multilineString = `
|
let multilineString = `
|
||||||
this is the first line
|
this is the first line
|
||||||
this is the middle line
|
this is the middle line
|
||||||
this is the last line
|
this is the last line
|
||||||
`;
|
`;
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Swift + show lineNumbers
|
Swift + show lineNumbers
|
||||||
|
|
||||||
{% highlight swift lineNumbers %}
|
{% highlight swift lineNumbers %}
|
||||||
let multilineString = `
|
let multilineString = `
|
||||||
this is the first line
|
this is the first line
|
||||||
this is the middle line
|
this is the middle line
|
||||||
this is the last line
|
this is the last line
|
||||||
`;
|
`;
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Swift + show lineNumbers + highlight 1 & 3
|
Swift + show lineNumbers + highlight 1 & 3
|
||||||
|
|
||||||
{% highlight swift lineNumbers 1,3 %}
|
{% highlight swift lineNumbers 1,3 %}
|
||||||
let multilineString = `
|
let multilineString = `
|
||||||
this is the first line
|
this is the first line
|
||||||
this is the middle line
|
this is the middle line
|
||||||
this is the last line
|
this is the last line
|
||||||
`;
|
`;
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Swift + show lineNumbers + highlight 1 & 3
|
Swift + show lineNumbers + highlight 1 & 3
|
||||||
|
|
||||||
{% highlight swift lineNumbers 2:3 table %}
|
{% highlight swift lineNumbers 1,3 table %}
|
||||||
let multilineString = `
|
let multilineString = `
|
||||||
this is the first line
|
this is the first line
|
||||||
this is the middle line
|
this is the middle line
|
||||||
this is the last line
|
this is the last line
|
||||||
`;
|
`;
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title></title>
|
<title></title>
|
||||||
<link rel="stylesheet" href="../test.css">
|
<link rel="stylesheet" href="../test.css">
|
||||||
|
<!-- <link rel="stylesheet" href="../prism-theme.css"> -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title></title>
|
<title></title>
|
||||||
<link rel="stylesheet" href="../test.css">
|
<link rel="stylesheet" href="../test.css">
|
||||||
|
<link rel="stylesheet" href="../prism-theme.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 63 KiB |
Binary file not shown.
Before Width: | Height: | Size: 49 KiB |
Binary file not shown.
Before Width: | Height: | Size: 25 KiB |
|
@ -0,0 +1,33 @@
|
||||||
|
class HighlightLines {
|
||||||
|
constructor(rangeStr) {
|
||||||
|
this.highlights = this.convertRangeToHash(rangeStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
convertRangeToHash(rangeStr) {
|
||||||
|
let hash = {};
|
||||||
|
if( !rangeStr ) {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ranges = rangeStr.split(",").map(function(range) {
|
||||||
|
return range.trim();
|
||||||
|
});
|
||||||
|
|
||||||
|
for(let range of ranges) {
|
||||||
|
let startFinish = range.split('-');
|
||||||
|
let start = parseInt(startFinish[0], 10);
|
||||||
|
let end = parseInt(startFinish[1] || start, 10);
|
||||||
|
|
||||||
|
for( let j = start, k = end; j<=k; j++ ) {
|
||||||
|
hash[j] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
isHighlighted(lineNumber) {
|
||||||
|
return !!this.highlights[lineNumber];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = HighlightLines;
|
|
@ -0,0 +1,68 @@
|
||||||
|
const HighlightLines = require("./HighlightLines");
|
||||||
|
|
||||||
|
class HighlightLinesGroup {
|
||||||
|
constructor(str, delimiter) {
|
||||||
|
this.init(str, delimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
init(str = "", delimiter = " ") {
|
||||||
|
this.str = str;
|
||||||
|
this.delimiter = delimiter;
|
||||||
|
|
||||||
|
let split = str.split(this.delimiter);
|
||||||
|
this.highlights = new HighlightLines(split.length === 1 ? split[0] : "");
|
||||||
|
this.highlightsAdd = new HighlightLines(split.length === 2 ? split[0] : "");
|
||||||
|
this.highlightsRemove = new HighlightLines(split.length === 2 ? split[1] : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
isHighlighted(lineNumber) {
|
||||||
|
return this.highlights.isHighlighted(lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
isHighlightedAdd(lineNumber) {
|
||||||
|
return this.highlightsAdd.isHighlighted(lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
isHighlightedRemove(lineNumber) {
|
||||||
|
return this.highlightsRemove.isHighlighted(lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasTagMismatch(line) {
|
||||||
|
let startCount = line.split("<span").length;
|
||||||
|
let endCount = line.split("</span").length;
|
||||||
|
if( startCount !== endCount ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
splitLineMarkup(line, before, after) {
|
||||||
|
|
||||||
|
// skip line highlighting if there is an uneven number of <span> or </span> on the line.
|
||||||
|
// for example, we can’t wrap <span> with <span><span></span>
|
||||||
|
if(this.hasTagMismatch(line)) {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
return before + line + after;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLineMarkup(lineNumber, line, extraClasses = []) {
|
||||||
|
let extraClassesStr = (extraClasses.length ? " " + extraClasses.join(" ") : "");
|
||||||
|
|
||||||
|
if (this.isHighlighted(lineNumber)) {
|
||||||
|
return this.splitLineMarkup(line, `<mark class="highlight-line highlight-line-active${extraClassesStr}">`, `</mark>`);
|
||||||
|
}
|
||||||
|
if (this.isHighlightedAdd(lineNumber)) {
|
||||||
|
return this.splitLineMarkup(line, `<ins class="highlight-line highlight-line-add${extraClassesStr}">`, `</ins>`);
|
||||||
|
}
|
||||||
|
if (this.isHighlightedRemove(lineNumber)) {
|
||||||
|
return this.splitLineMarkup(line, `<del class="highlight-line highlight-line-remove${extraClassesStr}">`, `</del>`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.splitLineMarkup( line, `<span class="highlight-line${extraClassesStr}">`, `</span>`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = HighlightLinesGroup;
|
|
@ -12,7 +12,13 @@ class LiquidHighlightTag {
|
||||||
let ret = function (highlighter) {
|
let ret = function (highlighter) {
|
||||||
return {
|
return {
|
||||||
parse: function (tagToken, remainTokens) {
|
parse: function (tagToken, remainTokens) {
|
||||||
this.args = tagToken.args;
|
console.log(">>LIQIUD");
|
||||||
|
console.log(tagToken.args);
|
||||||
|
console.log("<<LIQIUD");
|
||||||
|
let split = tagToken.args.split(" ");
|
||||||
|
|
||||||
|
this.language = split.shift();
|
||||||
|
this.highlightLines = split.join(" ");
|
||||||
|
|
||||||
this.tokens = [];
|
this.tokens = [];
|
||||||
|
|
||||||
|
@ -38,9 +44,13 @@ class LiquidHighlightTag {
|
||||||
return token.raw || token.getText();
|
return token.raw || token.getText();
|
||||||
});
|
});
|
||||||
let tokenStr = tokens.join("").trim();
|
let tokenStr = tokens.join("").trim();
|
||||||
console.log(this.args);
|
|
||||||
return Promise.resolve(
|
return Promise.resolve(
|
||||||
HighlightPairedShortcode(tokenStr, this.args, options)
|
HighlightPairedShortcode(
|
||||||
|
tokenStr,
|
||||||
|
this.language,
|
||||||
|
this.highlightLines,
|
||||||
|
options
|
||||||
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
const Prism = require("prismjs");
|
||||||
|
const PrismLoader = require("prismjs/components/index.js");
|
||||||
|
// Avoid "Language does not exist: " console logs
|
||||||
|
PrismLoader.silent = true;
|
||||||
|
|
||||||
|
const PrismAlias = require("./PrismNormalizeAlias");
|
||||||
|
|
||||||
|
module.exports = function(language) {
|
||||||
|
let diffRemovedRawName = language;
|
||||||
|
if(language.startsWith("diff-")) {
|
||||||
|
diffRemovedRawName = language.substr("diff-".length);
|
||||||
|
}
|
||||||
|
// aliasing should ignore diff-
|
||||||
|
let aliasedName = PrismAlias(diffRemovedRawName);
|
||||||
|
|
||||||
|
if(!Prism.languages[ aliasedName ]) {
|
||||||
|
PrismLoader(aliasedName);
|
||||||
|
}
|
||||||
|
if(!Prism.languages[ aliasedName ]) {
|
||||||
|
throw new Error(`"${language}" is not a valid Prism.js language for eleventy-plugin-syntaxhighlight`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!language.startsWith("diff-")) {
|
||||||
|
return Prism.languages[ aliasedName ];
|
||||||
|
}
|
||||||
|
|
||||||
|
// language has diff- prefix
|
||||||
|
let fullLanguageName = `diff-${aliasedName}`;
|
||||||
|
|
||||||
|
if(!Prism.languages.diff) {
|
||||||
|
PrismLoader("diff");
|
||||||
|
// Bundled Plugin
|
||||||
|
require("prismjs/plugins/diff-highlight/prism-diff-highlight");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store into with aliased keys
|
||||||
|
// ts -> diff-typescript
|
||||||
|
// js -> diff-javascript
|
||||||
|
Prism.languages[ fullLanguageName ] = Prism.languages.diff;
|
||||||
|
|
||||||
|
return Prism.languages[ fullLanguageName ];
|
||||||
|
};
|
|
@ -0,0 +1,42 @@
|
||||||
|
const Prism = require("prismjs");
|
||||||
|
|
||||||
|
const HARDCODED_ALIASES = {
|
||||||
|
njk: "jinja2",
|
||||||
|
nunjucks: "jinja2",
|
||||||
|
};
|
||||||
|
|
||||||
|
// This was added to make `ts` resolve to `typescript` correctly.
|
||||||
|
// The Prism loader doesn’t seem to always handle aliasing correctly.
|
||||||
|
module.exports = function(language) {
|
||||||
|
try {
|
||||||
|
// Careful this is not public API stuff:
|
||||||
|
// https://github.com/PrismJS/prism/issues/2146
|
||||||
|
const PrismComponents = require("prismjs/components.json");
|
||||||
|
let langs = PrismComponents.languages;
|
||||||
|
|
||||||
|
// Manual override
|
||||||
|
if(HARDCODED_ALIASES[language]) {
|
||||||
|
language = HARDCODED_ALIASES[language];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(langs[ language ]) {
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
for(let langName in langs) {
|
||||||
|
if(Array.isArray(langs[langName].alias)) {
|
||||||
|
for(let alias of langs[langName].alias) {
|
||||||
|
if(alias === language) {
|
||||||
|
return langName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(langs[langName].alias === language) {
|
||||||
|
return langName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
// Couldn’t find the components file, aliases may not resolve correctly
|
||||||
|
// See https://github.com/11ty/eleventy-plugin-syntaxhighlight/issues/19
|
||||||
|
}
|
||||||
|
|
||||||
|
return language;
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
function attributeEntryToString(attribute, context) {
|
||||||
|
let [key, value] = attribute;
|
||||||
|
|
||||||
|
if (typeof value === "function") { // Callback must return a string or a number
|
||||||
|
value = value(context); // Run the provided callback and store the result
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value !== "string" && typeof value !== "number") {
|
||||||
|
throw new Error(
|
||||||
|
`Attribute "${key}" must have, or evaluate to, 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': function (context) { return context.language; },
|
||||||
|
'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.
|
||||||
|
* @param {object} context An object with the current context.
|
||||||
|
* @param {string} context.content The code to parse and highlight.
|
||||||
|
* @param {string} context.language The language for the current instance.
|
||||||
|
* @param {object} context.options The options passed to the syntax highlighter.
|
||||||
|
* @returns {string} A string containing the above HTML attributes preceded by a single space.
|
||||||
|
*/
|
||||||
|
function getAttributes(attributes, context = {}) {
|
||||||
|
let langClass = context.language ? `language-${context.language}` : "";
|
||||||
|
|
||||||
|
if (!attributes) {
|
||||||
|
return langClass ? ` class="${langClass}"` : "";
|
||||||
|
} else if (typeof attributes === "object") {
|
||||||
|
if(!("class" in attributes) && langClass) {
|
||||||
|
// class attribute should be first in order
|
||||||
|
let tempAttrs = { class: langClass };
|
||||||
|
for(let key in attributes) {
|
||||||
|
tempAttrs[key] = attributes[key];
|
||||||
|
}
|
||||||
|
attributes = tempAttrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formattedAttributes = Object.entries(attributes).map(
|
||||||
|
entry => attributeEntryToString(entry, context)
|
||||||
|
);
|
||||||
|
|
||||||
|
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;
|
Loading…
Reference in New Issue