Skip to content

Commit

Permalink
feat: code highlighting
Browse files Browse the repository at this point in the history
  • Loading branch information
uetchy committed Jul 2, 2020
1 parent 45f2687 commit 10058f3
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 82 deletions.
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"build": "shx rm -rf lib && tsc && shx chmod +x lib/cli.js",
"dev": "tsc -w",
"prepublish": "yarn build",
"prepublishOnly": "yarn build",
"prerelease": "np prerelease --tag next",
"release": "np",
"test": "jest"
Expand All @@ -20,8 +20,9 @@
"mdast-util-to-hast": "^9.1.0",
"mdast-util-to-string": "^1.1.0",
"meow": "^7.0.1",
"refractor": "^3.0.0",
"rehype-document": "^5.1.0",
"rehype-mathjax": "^2.0.0",
"rehype-katex": "^3.0.0",
"rehype-raw": "^4.0.2",
"rehype-slug": "^3.0.0",
"rehype-stringify": "^8.0.0",
Expand All @@ -34,6 +35,7 @@
"unified": "^9.0.0",
"unist-builder": "^2.0.3",
"unist-util-inspect": "^6.0.0",
"unist-util-remove": "^2.0.0",
"unist-util-select": "^3.0.1",
"unist-util-visit": "^2.0.2"
},
Expand All @@ -44,6 +46,7 @@
"@types/js-yaml": "^3.12.4",
"@types/mdast": "^3.0.3",
"@types/node": "^14.0.14",
"@types/refractor": "^2.8.0",
"@types/vfile": "^4.0.0",
"doctoc": "^1.4.0",
"husky": "^4.2.5",
Expand Down
30 changes: 25 additions & 5 deletions src/plugins/code.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import {Code} from 'mdast';
import {Node} from 'unist';
import { Code } from 'mdast';
import { Handler } from 'mdast-util-to-hast';
import refractor from 'refractor';
import { Node } from 'unist';
import u from 'unist-builder';
import visit from 'unist-util-visit';

export function attacher() {
return (tree: Node) => {
visit<Code>(tree, ['code'], (node) => {
visit<Code>(tree, 'code', (node) => {
const match = /^(.+?):(.+)$/.exec(node.lang ?? '');

// parse lang:title syntax
if (match) {
const [, lang, title] = match;
node.data = {...(node.data ?? {}), hProperties: {title}};
node.data = { ...(node.data ?? {}), hProperties: { title } };
node.lang = lang;
if (node.position?.end.offset) {
node.position!.end.offset -= title.length + 1;
Expand All @@ -26,13 +30,29 @@ export function attacher() {
}) ?? [],
);

// copy title metadata for figure handler injecting figcaption
if (metadata.title) {
node.data = {
...(node.data ?? {}),
hProperties: {title: metadata.title},
hProperties: { title: metadata.title },
};
}
}

// syntax highlight
if (node.lang && refractor.registered(node.lang)) {
if (!node.data) node.data = {};
node.data.hChildren = refractor.highlight(node.value, node.lang);
}
});
};
}

export function handler(h: any, node: any): Handler {
const value = node.value || '';
const lang = node.lang ? node.lang.match(/^[^ \t]+(?=[ \t]|$)/) : 'text';
const props = { className: ['language-' + lang] };
return h(node.position, 'pre', props, [
h(node, 'code', props, [u('text', value)]),
]);
}
10 changes: 5 additions & 5 deletions src/plugins/figure.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {Parent as HastParent} from 'hast';
import { Parent as HastParent } from 'hast';
import is from 'hast-util-is-element';
import h from 'hastscript';
import {Node, Parent} from 'unist';
import { Node, Parent } from 'unist';
import visit from 'unist-util-visit';

interface HastNode extends HastParent {
properties: {[key: string]: any};
properties: { [key: string]: any };
}

export function handler(options = {}) {
export function plugin(options = {}) {
return (tree: Node) => {
visit<HastNode>(tree, 'element', (node, index, parent) => {
// handle captioned code block
Expand All @@ -18,7 +18,7 @@ export function handler(options = {}) {
delete maybeCode!.properties.title;
(parent as Parent).children[index] = h(
'figure',
{class: maybeCode!.properties.className[0]},
{ class: maybeCode!.properties.className[0] },
h('figcaption', maybeTitle),
node,
);
Expand Down
16 changes: 8 additions & 8 deletions src/revive-parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ import frontmatter from 'remark-frontmatter';
import math from 'remark-math';
import markdown from 'remark-parse';
import unified from 'unified';
import {attacher as code} from './plugins/code';
import {attacher as fencedBlock} from './plugins/fenced-block';
import {attacher as metadata} from './plugins/metadata';
import {attacher as ruby} from './plugins/ruby';
import {inspect} from './utils/debug';
import { attacher as code } from './plugins/code';
import { attacher as fencedBlock } from './plugins/fenced-block';
import { attacher as metadata } from './plugins/metadata';
import { attacher as ruby } from './plugins/ruby';
import { inspect } from './utils/debug';

export default [
[markdown, {commonmark: true}],
frontmatter,
metadata,
[markdown, { commonmark: false, footnotes: true }],
fencedBlock,
breaks,
code,
ruby,
math,
frontmatter,
metadata,
inspect('mdast'),
] as unified.PluggableList<unified.Settings>;
18 changes: 14 additions & 4 deletions src/revive-rehype.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@ import raw from 'rehype-raw';
import slug from 'rehype-slug';
import remark2rehype from 'remark-rehype';
import unified from 'unified';
import {handler as figure} from './plugins/figure';
import {handler as ruby} from './plugins/ruby';
import {inspect} from './utils/debug';
import { handler as code } from './plugins/code';
import { plugin as figure } from './plugins/figure';
import { plugin as math } from './plugins/math';
import { handler as ruby } from './plugins/ruby';
import { inspect } from './utils/debug';

export default [
[remark2rehype, {allowDangerousHtml: true, handlers: {ruby}}],
[
remark2rehype,
{
allowDangerousHtml: true,
handlers: {
ruby,
code,
},
},
],
raw,
figure,
math,
Expand Down
8 changes: 5 additions & 3 deletions types/remark.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@ declare namespace NodeJS {
declare module 'remark-math';
declare module 'remark-breaks';
declare module 'rehype-raw' {
import {Plugin} from 'unified';
import { Plugin } from 'unified';
const plugin: Plugin;
export default plugin;
}

declare module 'rehype-stringify' {
import {Plugin} from 'unified';
import { Plugin } from 'unified';
const plugin: Plugin;
export default plugin;
}
declare module 'rehype-mathjax';
declare module 'unist-util-remove';
declare module 'rehype-katex';
declare module 'rehype-slug';
declare module 'hastscript';
declare module 'mdast-util-to-hast/lib/all';
Expand All @@ -30,7 +32,7 @@ declare module 'to-vfile';
interface Tokenizer {
(
this: TokenizerInstance,
eat: Eat & {now: () => Point},
eat: Eat & { now: () => Point },
value: string,
silent?: boolean,
): boolean | Node | void;
Expand Down
Loading

0 comments on commit 10058f3

Please sign in to comment.