Compare commits
3 Commits
91e57182f3
...
5f3d7238d9
Author | SHA1 | Date |
---|---|---|
Robert McGovern | 5f3d7238d9 | |
Robert McGovern | 04f69115c9 | |
Robert McGovern | 53be570c16 |
|
@ -3,10 +3,9 @@ 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 markdownPrismJs = require("./src/markdownSyntaxHighlightOptions");
|
const markdownChroma = 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);
|
||||||
|
@ -21,9 +20,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",
|
||||||
|
@ -52,7 +51,7 @@ module.exports = {
|
||||||
|
|
||||||
if (hasTemplateFormat(options.templateFormats, "md")) {
|
if (hasTemplateFormat(options.templateFormats, "md")) {
|
||||||
// ```js/0,2-3
|
// ```js/0,2-3
|
||||||
eleventyConfig.addMarkdownHighlighter(markdownPrismJs(options));
|
eleventyConfig.addMarkdownHighlighter(markdownChroma(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (hasTemplateFormat(options.templateFormats, "11ty.js")) {
|
// if (hasTemplateFormat(options.templateFormats, "11ty.js")) {
|
||||||
|
|
62
README.md
62
README.md
|
@ -41,3 +41,65 @@ 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,7 +5,6 @@
|
||||||
<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>
|
||||||
|
|
||||||
|
@ -16,52 +15,52 @@ function myFunction() {
|
||||||
}
|
}
|
||||||
{% 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 1,3 table %}
|
{% highlight swift lineNumbers 2: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 %}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<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,7 +5,6 @@
|
||||||
<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.
After Width: | Height: | Size: 63 KiB |
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
|
@ -1,33 +0,0 @@
|
||||||
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;
|
|
|
@ -1,68 +0,0 @@
|
||||||
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,13 +12,7 @@ class LiquidHighlightTag {
|
||||||
let ret = function (highlighter) {
|
let ret = function (highlighter) {
|
||||||
return {
|
return {
|
||||||
parse: function (tagToken, remainTokens) {
|
parse: function (tagToken, remainTokens) {
|
||||||
console.log(">>LIQIUD");
|
this.args = tagToken.args;
|
||||||
console.log(tagToken.args);
|
|
||||||
console.log("<<LIQIUD");
|
|
||||||
let split = tagToken.args.split(" ");
|
|
||||||
|
|
||||||
this.language = split.shift();
|
|
||||||
this.highlightLines = split.join(" ");
|
|
||||||
|
|
||||||
this.tokens = [];
|
this.tokens = [];
|
||||||
|
|
||||||
|
@ -44,13 +38,9 @@ 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(
|
HighlightPairedShortcode(tokenStr, this.args, options)
|
||||||
tokenStr,
|
|
||||||
this.language,
|
|
||||||
this.highlightLines,
|
|
||||||
options
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
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 ];
|
|
||||||
};
|
|
|
@ -1,42 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
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