work in progress. basic arguments handled in njk and md, need to do liquid and handling lineNumbersStart, highlight lines
This commit is contained in:
parent
c40be6836a
commit
4bb213e148
83
.eleventy.js
83
.eleventy.js
|
@ -1,59 +1,78 @@
|
||||||
const pkg = require("./package.json");
|
const pkg = require("./package.json");
|
||||||
const Prism = require("prismjs");
|
|
||||||
const hasTemplateFormat = require("./src/hasTemplateFormat");
|
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 markdownPrismJs = require("./src/markdownSyntaxHighlightOptions");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
initArguments: { Prism },
|
// initArguments: { Prism },
|
||||||
configFunction: function(eleventyConfig, options = {}) {
|
configFunction: function (eleventyConfig, options = {}) {
|
||||||
try {
|
try {
|
||||||
eleventyConfig.versionCheck(pkg["11ty"].compatibility);
|
eleventyConfig.versionCheck(pkg["11ty"].compatibility);
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
console.log( `WARN: Eleventy Plugin (${pkg.name}) Compatibility: ${e.message}` );
|
console.log(
|
||||||
|
`WARN: Eleventy Plugin (${pkg.name}) Compatibility: ${e.message}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
options = Object.assign({
|
options = Object.assign(
|
||||||
alwaysWrapLineHighlights: false,
|
{
|
||||||
// eligible to change the default to \n in a new major version.
|
theme: "onedark",
|
||||||
lineSeparator: "<br>",
|
lineNumbers: false,
|
||||||
preAttributes: {},
|
/* lineNumbersStyle: "table",*/ /* "table" or "inline" */
|
||||||
codeAttributes: {}
|
alwaysWrapLineHighlights: false,
|
||||||
}, options);
|
// eligible to change the default to \n in a new major version.
|
||||||
|
lineSeparator: "<br>",
|
||||||
|
preAttributes: {},
|
||||||
|
codeAttributes: {
|
||||||
|
theme: "onedark",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options
|
||||||
|
);
|
||||||
|
|
||||||
// TODO hbs?
|
if (hasTemplateFormat(options.templateFormats, "liquid")) {
|
||||||
if( hasTemplateFormat(options.templateFormats, "liquid") ) {
|
|
||||||
eleventyConfig.addLiquidTag("highlight", (liquidEngine) => {
|
eleventyConfig.addLiquidTag("highlight", (liquidEngine) => {
|
||||||
// {% highlight js 0 2 %}
|
// {% highlight js 0,2 %}
|
||||||
let highlight = new LiquidHighlightTag(liquidEngine);
|
let highlight = new LiquidHighlightTag(liquidEngine);
|
||||||
return highlight.getObject(options);
|
return highlight.getObject(options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hasTemplateFormat(options.templateFormats, "njk") ) {
|
if (hasTemplateFormat(options.templateFormats, "njk")) {
|
||||||
eleventyConfig.addPairedNunjucksShortcode("highlight", (content, args) => {
|
eleventyConfig.addPairedNunjucksShortcode(
|
||||||
// {% highlight "js 0 2-3" %}
|
"highlight",
|
||||||
let [language, ...highlightNumbers] = args.split(" ");
|
(content, args) => {
|
||||||
return HighlightPairedShortcode(content, language, highlightNumbers.join(" "), options);
|
// {% highlight "js 0,2-3" %}
|
||||||
});
|
return HighlightPairedShortcode(content, args, options);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hasTemplateFormat(options.templateFormats, "md") ) {
|
if (hasTemplateFormat(options.templateFormats, "md")) {
|
||||||
// ```js/0,2-3
|
// ```js/0,2-3
|
||||||
eleventyConfig.addMarkdownHighlighter(markdownPrismJs(options));
|
eleventyConfig.addMarkdownHighlighter(markdownPrismJs(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hasTemplateFormat(options.templateFormats, "11ty.js") ) {
|
// if (hasTemplateFormat(options.templateFormats, "11ty.js")) {
|
||||||
eleventyConfig.addJavaScriptFunction("highlight", (language, content, highlight1, highlight2) => {
|
// eleventyConfig.addJavaScriptFunction(
|
||||||
let highlightLines = [highlight1, highlight2].filter(entry => entry).join(" ");
|
// "highlight",
|
||||||
let result = HighlightPairedShortcode(content, language, highlightLines, options);
|
// (language, content, highlight1, highlight2) => {
|
||||||
return result;
|
// let highlightLines = [highlight1, highlight2]
|
||||||
});
|
// .filter((entry) => entry)
|
||||||
}
|
// .join(" ");
|
||||||
}
|
// let result = HighlightPairedShortcode(
|
||||||
|
// content,
|
||||||
|
// args,
|
||||||
|
// options
|
||||||
|
// );
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.pairedShortcode = HighlightPairedShortcode;
|
module.exports.pairedShortcode = HighlightPairedShortcode;
|
||||||
module.exports.CharacterWrap = CharacterWrap;
|
// module.exports.CharacterWrap = CharacterWrap;
|
||||||
|
|
39
README.md
39
README.md
|
@ -1,8 +1,41 @@
|
||||||
<p align="center"><img src="https://www.11ty.dev/img/logo-github.svg" width="200" height="200" alt="eleventy Logo"></p>
|
<p align="center"><img src="https://www.11ty.dev/img/logo-github.svg" width="200" height="200" alt="eleventy Logo"></p>
|
||||||
|
|
||||||
# eleventy-plugin-syntaxhighlight 🕚⚡️🎈🐀
|
# eleventy-plugin-syntaxhighlight-chroma
|
||||||
|
|
||||||
A pack of [Eleventy](https://github.com/11ty/eleventy) plugins for syntax highlighting. No browser/client JavaScript here, these highlight transformations are all done at build-time.
|
A module for handling syntax highlighting in [Eleventy](https://github.com/11ty/eleventy) using the [Chroma](https://github.com/alecthomas/chroma); a syntax highlighter written in Go. There is no browser/client JavaScript required, the highlight transformations are all done at build-time.
|
||||||
|
|
||||||
## Read the [Full Documentation on 11ty.dev](https://www.11ty.dev/docs/plugins/syntaxhighlight/)
|
I am making using of the [chroma-highlight](https://github.com/krymel/chroma-highlight) NPM package to include `Chroma` support. (It handles downloading the required binary for the platform you are working on).
|
||||||
|
|
||||||
|
This module/plugin took the 11ty plugin [eleventy-plugin-syntaxhighlight](https://github.com/11ty/eleventy-plugin-syntaxhighlight) as the basis.
|
||||||
|
|
||||||
|
## Supported args in code blocks
|
||||||
|
|
||||||
|
The first argument is always expected to be the language, at present there is no bugout/fail if a language is not provided first. (Nor in the original plugin)
|
||||||
|
|
||||||
|
For Markdown, separate arguments with a `/`, this seems to be hard coded somewhere and I haven't a workaround yet. For `liquid` and `njk` use spaces (` `) to separate arguments.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
- `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. i.e `lineNumberStyle=table`
|
||||||
|
- `lineNumbersStart` the number to start the line number count from. i.e `lineNumbersStart=200`
|
||||||
|
|
||||||
|
|
||||||
|
## Supported `options` in eleventy config
|
||||||
|
|
||||||
|
You can specify some arguments in the options object in `.eleventy.js` config. ~~Options are considered defaults, and can be overriden by codeblock arguments.~~**TODO**
|
||||||
|
|
||||||
|
Example of `options` object
|
||||||
|
|
||||||
|
```
|
||||||
|
options
|
||||||
|
{
|
||||||
|
theme: 'onedark',
|
||||||
|
lineNumbers: false,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Theme can be set to one of these [themes](https://xyproto.github.io/splash/docs/all.html). If no theme is specified, then `xcode-dark` is used.
|
||||||
|
|
||||||
|
- `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.
|
||||||
|
|
|
@ -8,12 +8,16 @@
|
||||||
<link rel="stylesheet" href="../prism-theme.css">
|
<link rel="stylesheet" href="../prism-theme.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
Just JS
|
||||||
{% highlight js %}
|
{% highlight js %}
|
||||||
function myFunction() {
|
function myFunction() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
|
Just JS multiline
|
||||||
|
|
||||||
{% highlight js %}
|
{% highlight js %}
|
||||||
let multilineString = `
|
let multilineString = `
|
||||||
this is the first line
|
this is the first line
|
||||||
|
@ -22,6 +26,7 @@ let multilineString = `
|
||||||
`;
|
`;
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
|
JS + Linehighlight
|
||||||
{% highlight js 1,3 %}
|
{% highlight js 1,3 %}
|
||||||
let multilineString = `
|
let multilineString = `
|
||||||
this is the first line
|
this is the first line
|
||||||
|
@ -29,5 +34,36 @@ let multilineString = `
|
||||||
this is the last line
|
this is the last line
|
||||||
`;
|
`;
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
|
Swift + show lineNumbers
|
||||||
|
|
||||||
|
{% highlight swift lineNumbers %}
|
||||||
|
let multilineString = `
|
||||||
|
this is the first line
|
||||||
|
this is the middle line
|
||||||
|
this is the last line
|
||||||
|
`;
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
Swift + show lineNumbers + highlight 1 & 3
|
||||||
|
|
||||||
|
{% highlight swift lineNumbers 1,3 %}
|
||||||
|
let multilineString = `
|
||||||
|
this is the first line
|
||||||
|
this is the middle line
|
||||||
|
this is the last line
|
||||||
|
`;
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
Swift + show lineNumbers + highlight 1 & 3
|
||||||
|
|
||||||
|
{% highlight swift lineNumbers 1,3 table %}
|
||||||
|
let multilineString = `
|
||||||
|
this is the first line
|
||||||
|
this is the middle line
|
||||||
|
this is the last line
|
||||||
|
`;
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,10 +4,20 @@
|
||||||
<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">
|
<!-- <link rel="stylesheet" href="../prism-theme.css"> -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
Just `curious` what
|
||||||
|
|
||||||
|
No lang
|
||||||
|
```
|
||||||
|
function myFunction() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Langs
|
||||||
```ts
|
```ts
|
||||||
function myFunction() {
|
function myFunction() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -44,6 +54,7 @@ let multilineString = `
|
||||||
`;
|
`;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Highlight 1 & 3
|
||||||
```js/1,3
|
```js/1,3
|
||||||
let multilineString = `
|
let multilineString = `
|
||||||
this is the first line
|
this is the first line
|
||||||
|
@ -52,11 +63,143 @@ let multilineString = `
|
||||||
`;
|
`;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Highlight 1, 3-6
|
||||||
|
|
||||||
|
```js/1,3-6
|
||||||
|
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
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
|
Highlight 1, 3-6
|
||||||
|
|
||||||
|
```js/1,3:6
|
||||||
|
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
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
|
Line numbers and highlight
|
||||||
|
Highlight 1, 3-6
|
||||||
|
|
||||||
|
```js/1,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
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
|
Line numbers, highlight, base number 200, table
|
||||||
|
Highlight 1, 3-6
|
||||||
|
|
||||||
|
```js/1,3:6/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
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
|
Line numbers, highlight, base number 200, table
|
||||||
|
Highlight 1, 3-6, separated spaces (won't work)
|
||||||
|
|
||||||
|
```swift 1,3:6 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
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Other arguments
|
||||||
|
|
||||||
|
Table
|
||||||
|
```js/table
|
||||||
|
function myFunction() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
linenums
|
||||||
|
```js/lineNumbers
|
||||||
|
function myFunction() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Scrollbar
|
## Scrollbar
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { aReallyLongFunctionNameThatCouldBeLongerButThisShouldBeLongEnoughByNowHopefully as anEvenLongerFunctionNameWithMoreCharactersThanCouldBeImaginedByAnyOnePersonInThisEntireWorldOfPeopleThatOneMightKnowAtLeastThatIsWhatIsTheorizedByThisLongName } from 'wow-this-is-so-long-you-might-need-a-scrollbar-to-see-it.long-ol-file-extension-that-should-not-be-this-long-on-a-real-site-but-this-is-to-demonstrate-the-accessibility-of-tabindex-and-scrollbars.js';
|
import { aReallyLongFunctionNameThatCouldBeLongerButThisShouldBeLongEnoughByNowHopefully as anEvenLongerFunctionNameWithMoreCharactersThanCouldBeImaginedByAnyOnePersonInThisEntireWorldOfPeopleThatOneMightKnowAtLeastThatIsWhatIsTheorizedByThisLongName } from 'wow-this-is-so-long-you-might-need-a-scrollbar-to-see-it.long-ol-file-extension-that-should-not-be-this-long-on-a-real-site-but-this-is-to-demonstrate-the-accessibility-of-tabindex-and-scrollbars.js';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## CSS
|
||||||
|
```css
|
||||||
|
pre {
|
||||||
|
display: block;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
|
||||||
|
overflow-x: auto;
|
||||||
|
background-color: #eee;
|
||||||
|
font-size: 1em; /*14px /16*/
|
||||||
|
-moz-tab-size: 2;
|
||||||
|
-o-tab-size: 2;
|
||||||
|
tab-size: 2;
|
||||||
|
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre;
|
||||||
|
word-spacing: normal;
|
||||||
|
word-break: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
|
||||||
|
background-color: #272822;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:not(pre) > code[class*="language-"] {
|
||||||
|
padding: 0.1em 0.3em;
|
||||||
|
border-radius: 0.3em;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.comment,
|
||||||
|
.token.prolog,
|
||||||
|
.token.doctype,
|
||||||
|
.token.cdata {
|
||||||
|
color: #8da1b9;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
Just `curious` what
|
||||||
|
|
||||||
{% highlight "js" %}
|
{% highlight "js" %}
|
||||||
function myFunction() {
|
function myFunction() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -70,5 +72,28 @@ function myFunction() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
|
lineNumbers
|
||||||
|
{% highlight "ruby lines lineNumbers" %}
|
||||||
|
function myFunction() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
table
|
||||||
|
{% highlight "ruby lines table" %}
|
||||||
|
function myFunction() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
lineNumbers + table
|
||||||
|
{% highlight "ruby lines table lineNumbers" %}
|
||||||
|
function myFunction() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -13,3 +13,25 @@
|
||||||
.highlight-line .highlight-line:not(:last-child) {
|
.highlight-line .highlight-line:not(:last-child) {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
display: block;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
|
||||||
|
overflow-x: auto;
|
||||||
|
background-color: #eee;
|
||||||
|
font-size: 1em; /*14px /16*/
|
||||||
|
-moz-tab-size: 2;
|
||||||
|
-o-tab-size: 2;
|
||||||
|
tab-size: 2;
|
||||||
|
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre;
|
||||||
|
word-spacing: normal;
|
||||||
|
word-break: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
|
||||||
|
background-color: #272822;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
|
@ -1,34 +1,27 @@
|
||||||
const Prism = require("prismjs");
|
const Chroma = require("chroma-highlight");
|
||||||
const PrismLoader = require("./PrismLoader");
|
const parseSyntaxArguments = require("./parseSyntaxArguments");
|
||||||
const HighlightLinesGroup = require("./HighlightLinesGroup");
|
|
||||||
const getAttributes = require("./getAttributes");
|
|
||||||
|
|
||||||
module.exports = function (content, language, highlightNumbers, options = {}) {
|
module.exports = function (content, args, options = {}) {
|
||||||
// default to on
|
// No args, so don't know language, drop out
|
||||||
if(options.trim === undefined || options.trim === true) {
|
if (!args) {
|
||||||
content = content.trim();
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
let highlightedContent;
|
let highlightedContent;
|
||||||
if( language === "text" ) {
|
|
||||||
highlightedContent = content;
|
if (options.trim === undefined || options.trim === true) {
|
||||||
} else {
|
content = content.trim();
|
||||||
highlightedContent = Prism.highlight(content, PrismLoader(language), language);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let group = new HighlightLinesGroup(highlightNumbers);
|
if (args === "text") {
|
||||||
let lines = highlightedContent.split(/\r?\n/);
|
highlightedContent = content;
|
||||||
lines = lines.map(function(line, j) {
|
} else {
|
||||||
if(options.alwaysWrapLineHighlights || highlightNumbers) {
|
const parsedArgs = parseSyntaxArguments(args, options);
|
||||||
let lineContent = group.getLineMarkup(j, line);
|
|
||||||
return lineContent;
|
|
||||||
}
|
|
||||||
return line;
|
|
||||||
});
|
|
||||||
|
|
||||||
const context = { content: content, language: language, options: options };
|
let opts = `--formatter html --html-only --html-inline-styles ${parsedArgs} `;
|
||||||
const preAttributes = getAttributes(options.preAttributes, context);
|
|
||||||
const codeAttributes = getAttributes(options.codeAttributes, context);
|
|
||||||
|
|
||||||
return `<pre${preAttributes}><code${codeAttributes}>` + lines.join(options.lineSeparator || "<br>") + "</code></pre>";
|
highlightedContent = Chroma.highlight(content, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return highlightedContent;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
const HighlightPairedShortcode = require("./HighlightPairedShortcode");
|
const HighlightPairedShortcode = require("./HighlightPairedShortcode");
|
||||||
|
const Chroma = require("chroma-highlight");
|
||||||
|
const parseSyntaxArguments = require("./parseSyntaxArguments");
|
||||||
|
const getAttributes = require("./getAttributes");
|
||||||
|
|
||||||
class LiquidHighlightTag {
|
class LiquidHighlightTag {
|
||||||
constructor(liquidEngine) {
|
constructor(liquidEngine) {
|
||||||
|
@ -6,9 +9,12 @@ class LiquidHighlightTag {
|
||||||
}
|
}
|
||||||
|
|
||||||
getObject(options = {}) {
|
getObject(options = {}) {
|
||||||
let ret = function(highlighter) {
|
let ret = function (highlighter) {
|
||||||
return {
|
return {
|
||||||
parse: function(tagToken, remainTokens) {
|
parse: function (tagToken, remainTokens) {
|
||||||
|
console.log(">>LIQIUD");
|
||||||
|
console.log(tagToken.args);
|
||||||
|
console.log("<<LIQIUD");
|
||||||
let split = tagToken.args.split(" ");
|
let split = tagToken.args.split(" ");
|
||||||
|
|
||||||
this.language = split.shift();
|
this.language = split.shift();
|
||||||
|
@ -16,29 +22,37 @@ class LiquidHighlightTag {
|
||||||
|
|
||||||
this.tokens = [];
|
this.tokens = [];
|
||||||
|
|
||||||
var stream = highlighter.liquidEngine.parser.parseStream(remainTokens);
|
var stream =
|
||||||
|
highlighter.liquidEngine.parser.parseStream(remainTokens);
|
||||||
|
|
||||||
stream
|
stream
|
||||||
.on("token", token => {
|
.on("token", (token) => {
|
||||||
if (token.name === "endhighlight") {
|
if (token.name === "endhighlight") {
|
||||||
stream.stop();
|
stream.stop();
|
||||||
} else {
|
} else {
|
||||||
this.tokens.push(token);
|
this.tokens.push(token);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on("end", x => {
|
.on("end", (x) => {
|
||||||
throw new Error(`tag ${tagToken.getText()} not closed`);
|
throw new Error(`tag ${tagToken.getText()} not closed`);
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.start();
|
stream.start();
|
||||||
},
|
},
|
||||||
render: function(scope, hash) {
|
render: function (scope, hash) {
|
||||||
let tokens = this.tokens.map(token => {
|
let tokens = this.tokens.map((token) => {
|
||||||
return token.raw || token.getText();
|
return token.raw || token.getText();
|
||||||
});
|
});
|
||||||
let tokenStr = tokens.join("").trim();
|
let tokenStr = tokens.join("").trim();
|
||||||
return Promise.resolve(HighlightPairedShortcode(tokenStr, this.language, this.highlightLines, options));
|
return Promise.resolve(
|
||||||
}
|
HighlightPairedShortcode(
|
||||||
|
tokenStr,
|
||||||
|
this.language,
|
||||||
|
this.highlightLines,
|
||||||
|
options
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,44 +1,25 @@
|
||||||
const Prism = require("prismjs");
|
const Chroma = require("chroma-highlight");
|
||||||
const PrismLoader = require("./PrismLoader");
|
const parseSyntaxArguments = require("./parseSyntaxArguments");
|
||||||
const HighlightLinesGroup = require("./HighlightLinesGroup");
|
|
||||||
const getAttributes = require("./getAttributes");
|
|
||||||
|
|
||||||
module.exports = function (options = {}) {
|
module.exports = function (options = {}) {
|
||||||
return function(str, language) {
|
return function (str, args) {
|
||||||
if(!language) {
|
if (!args) {
|
||||||
// empty string means defer to the upstream escaping code built into markdown lib.
|
// empty string means defer to the upstream escaping code built into markdown lib.
|
||||||
return "";
|
return str;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let split = language.split("/");
|
|
||||||
if( split.length ) {
|
|
||||||
language = split.shift();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let html;
|
let html;
|
||||||
if(language === "text") {
|
|
||||||
|
if (args === "text") {
|
||||||
html = str;
|
html = str;
|
||||||
} else {
|
} else {
|
||||||
html = Prism.highlight(str, PrismLoader(language), language);
|
const parsedArgs = parseSyntaxArguments(args, options);
|
||||||
|
|
||||||
|
let opts = `--formatter html --html-only --html-inline-styles ${parsedArgs} `;
|
||||||
|
|
||||||
|
html = Chroma.highlight(str, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
let hasHighlightNumbers = split.length > 0;
|
return html;
|
||||||
let highlights = new HighlightLinesGroup(split.join("/"), "/");
|
|
||||||
let lines = html.split("\n").slice(0, -1); // The last line is empty.
|
|
||||||
|
|
||||||
lines = lines.map(function(line, j) {
|
|
||||||
if(options.alwaysWrapLineHighlights || hasHighlightNumbers) {
|
|
||||||
let lineContent = highlights.getLineMarkup(j, line);
|
|
||||||
return lineContent;
|
|
||||||
}
|
|
||||||
return line;
|
|
||||||
});
|
|
||||||
|
|
||||||
const context = { content: str, language: language, options: options };
|
|
||||||
const preAttributes = getAttributes(options.preAttributes, context);
|
|
||||||
const codeAttributes = getAttributes(options.codeAttributes, context);
|
|
||||||
|
|
||||||
return `<pre${preAttributes}><code${codeAttributes}>${lines.join(options.lineSeparator || "<br>")}</code></pre>`;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
// const { split } = require("liquidjs/dist/builtin/filters");
|
||||||
|
const getAttributes = require("./getAttributes");
|
||||||
|
|
||||||
|
function attributeEntryToString2(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 parseSyntaxArguments(args, context = {}) {
|
||||||
|
console.log(">>pSA");
|
||||||
|
console.log(args);
|
||||||
|
console.log(">>>>>> context");
|
||||||
|
console.log(context);
|
||||||
|
const preAttributes = getAttributes(context.preAttributes);
|
||||||
|
const codeAttributes = getAttributes(context.codeAttributes);
|
||||||
|
|
||||||
|
console.log("<<pSA");
|
||||||
|
|
||||||
|
let splitArgs;
|
||||||
|
|
||||||
|
if (args.includes("/")) {
|
||||||
|
splitArgs = args.split("/");
|
||||||
|
} else if (args.includes(" ")) {
|
||||||
|
splitArgs = args.split(" ");
|
||||||
|
} else {
|
||||||
|
splitArgs = [args];
|
||||||
|
}
|
||||||
|
|
||||||
|
let opts = "";
|
||||||
|
|
||||||
|
opts += `--lexer ${splitArgs[0]} `;
|
||||||
|
|
||||||
|
if (context["theme"]) {
|
||||||
|
opts = opts + `--style ${context["theme"]} `;
|
||||||
|
} else {
|
||||||
|
opts = opts + "--style xcode-dark ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context["lineNumbers"] || args.includes("lineNumbers")) {
|
||||||
|
opts = opts + "--html-lines ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context["lineNumbersStyle"] == "table" || args.includes("table")) {
|
||||||
|
opts = opts + "--html-lines-table ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (splitArgs.includes("lineNumbersStart")) {
|
||||||
|
console.log("lineNumbersStart");
|
||||||
|
// console.log(splitArgs["lineNumbersStart"]);
|
||||||
|
// // console.log(args.keys());
|
||||||
|
// console.log(splitArgs.getAttribute("lineNumbersStart"));
|
||||||
|
// opts =
|
||||||
|
// opts + `--html-base-line= ${split["lineNumbersStart"].split("="[1])}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
// }
|
||||||
|
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = parseSyntaxArguments;
|
Loading…
Reference in New Issue