Skip to content

Commit 4db414d

Browse files
committed
Improve markdown plugin
1 parent 38c1f73 commit 4db414d

File tree

1 file changed

+14
-241
lines changed

1 file changed

+14
-241
lines changed

plugins/markdown.ts

Lines changed: 14 additions & 241 deletions
Original file line numberDiff line numberDiff line change
@@ -1,217 +1,12 @@
11
import type { Aleph, LoadInput, LoadOutput, ResolveResult, Plugin } from '../types.d.ts'
2-
import marked from 'https://esm.sh/[email protected]'
32
import { safeLoadFront } from 'https://esm.sh/[email protected]'
3+
import marked from 'https://esm.sh/[email protected]'
4+
import hljs from 'https://esm.sh/[email protected]?bundle'
5+
import unescape from 'https://esm.sh/[email protected]?bundle'
46
import util from '../shared/util.ts'
57

6-
const hljsUri = 'https://esm.sh/[email protected]'
7-
const languages = new Set([
8-
'1c',
9-
'abnf',
10-
'accesslog',
11-
'actionscript',
12-
'ada',
13-
'angelscript',
14-
'apache',
15-
'applescript',
16-
'arcade',
17-
'arduino',
18-
'armasm',
19-
'xml',
20-
'asciidoc',
21-
'aspectj',
22-
'autohotkey',
23-
'autoit',
24-
'avrasm',
25-
'awk',
26-
'axapta',
27-
'bash',
28-
'basic',
29-
'bnf',
30-
'brainfuck',
31-
'c',
32-
'cal',
33-
'capnproto',
34-
'ceylon',
35-
'clean',
36-
'clojure',
37-
'clojure-repl',
38-
'cmake',
39-
'coffeescript',
40-
'coq',
41-
'cos',
42-
'cpp',
43-
'crmsh',
44-
'crystal',
45-
'csharp',
46-
'csp',
47-
'css',
48-
'd',
49-
'markdown',
50-
'dart',
51-
'delphi',
52-
'diff',
53-
'django',
54-
'dns',
55-
'dockerfile',
56-
'dos',
57-
'dsconfig',
58-
'dts',
59-
'dust',
60-
'ebnf',
61-
'elixir',
62-
'elm',
63-
'ruby',
64-
'erb',
65-
'erlang-repl',
66-
'erlang',
67-
'excel',
68-
'fix',
69-
'flix',
70-
'fortran',
71-
'fsharp',
72-
'gams',
73-
'gauss',
74-
'gcode',
75-
'gherkin',
76-
'glsl',
77-
'gml',
78-
'go',
79-
'golo',
80-
'gradle',
81-
'groovy',
82-
'haml',
83-
'handlebars',
84-
'haskell',
85-
'haxe',
86-
'hsp',
87-
'http',
88-
'hy',
89-
'inform7',
90-
'ini',
91-
'irpf90',
92-
'isbl',
93-
'java',
94-
'javascript',
95-
'jboss-cli',
96-
'json',
97-
'julia',
98-
'julia-repl',
99-
'kotlin',
100-
'lasso',
101-
'latex',
102-
'ldif',
103-
'leaf',
104-
'less',
105-
'lisp',
106-
'livecodeserver',
107-
'livescript',
108-
'llvm',
109-
'lsl',
110-
'lua',
111-
'makefile',
112-
'mathematica',
113-
'matlab',
114-
'maxima',
115-
'mel',
116-
'mercury',
117-
'mipsasm',
118-
'mizar',
119-
'perl',
120-
'mojolicious',
121-
'monkey',
122-
'moonscript',
123-
'n1ql',
124-
'nestedtext',
125-
'nginx',
126-
'nim',
127-
'nix',
128-
'node-repl',
129-
'nsis',
130-
'objectivec',
131-
'ocaml',
132-
'openscad',
133-
'oxygene',
134-
'parser3',
135-
'pf',
136-
'pgsql',
137-
'php',
138-
'php-template',
139-
'plaintext',
140-
'pony',
141-
'powershell',
142-
'processing',
143-
'profile',
144-
'prolog',
145-
'properties',
146-
'protobuf',
147-
'puppet',
148-
'purebasic',
149-
'python',
150-
'python-repl',
151-
'q',
152-
'qml',
153-
'r',
154-
'reasonml',
155-
'rib',
156-
'roboconf',
157-
'routeros',
158-
'rsl',
159-
'ruleslanguage',
160-
'rust',
161-
'sas',
162-
'scala',
163-
'scheme',
164-
'scilab',
165-
'scss',
166-
'shell',
167-
'smali',
168-
'smalltalk',
169-
'sml',
170-
'sqf',
171-
'sql',
172-
'stan',
173-
'stata',
174-
'step21',
175-
'stylus',
176-
'subunit',
177-
'swift',
178-
'taggerscript',
179-
'yaml',
180-
'tap',
181-
'tcl',
182-
'thrift',
183-
'tp',
184-
'twig',
185-
'typescript',
186-
'vala',
187-
'vbnet',
188-
'vbscript',
189-
'vbscript-html',
190-
'verilog',
191-
'vhdl',
192-
'vim',
193-
'wasm',
194-
'wren',
195-
'x86asm',
196-
'xl',
197-
'xquery',
198-
'zephir',
199-
])
200-
const languageAlias = {
201-
'js': 'javascript',
202-
'jsx': 'javascript',
203-
'ts': 'typescript',
204-
'tsx': 'typescript',
205-
'py': 'python',
206-
'make': 'makefile',
207-
'md': 'markdown',
208-
'ps': 'powershell',
209-
'rs': 'rust',
210-
'styl': 'stylus',
211-
}
212-
2138
const test = /\.(md|markdown)$/i
214-
const reCodeLanguage = /<code class="language\-([^"]+)"/g
9+
const reCodeTag = /<code class="language\-([^"]+)">([\s\S]+?)<\/code>/g
21510

21611
export const markdownResovler = (specifier: string): ResolveResult => {
21712
let pagePath = util.trimPrefix(specifier.replace(/\.(md|markdown)$/i, ''), '/pages')
@@ -229,7 +24,6 @@ export const markdownLoader = async ({ specifier }: LoadInput, aleph: Aleph, { h
22924
const { framework } = aleph.config
23025
const { content } = await aleph.fetchModule(specifier)
23126
const { __content, ...meta } = safeLoadFront((new TextDecoder).decode(content))
232-
const html = marked.parse(__content)
23327
const props = {
23428
id: util.isString(meta.id) ? meta.id : undefined,
23529
className: util.isString(meta.className) ? meta.className.trim() : undefined,
@@ -238,9 +32,17 @@ export const markdownLoader = async ({ specifier }: LoadInput, aleph: Aleph, { h
23832
return prev
23933
}, {} as Record<string, any>) : undefined,
24034
}
35+
let html = marked.parse(__content)
36+
if (highlight) {
37+
html = html.replace(reCodeTag, (_, language, code) => {
38+
const h = hljs.highlight(unescape(code), { language }).value
39+
return `<code class="language-${language} hljs">${h}</code>`
40+
})
41+
}
24142
const code = [
242-
`import { createElement, useEffect, useRef } from 'https://esm.sh/react'`,
43+
`import { createElement } from 'https://esm.sh/react'`,
24344
`import HTMLPage from 'https://deno.land/x/aleph/framework/react/components/HTMLPage.ts'`,
45+
highlight && `import 'https://esm.sh/[email protected]/styles/${highlight.theme || 'default'}.css'`,
24446
`export default function MarkdownPage(props) {`,
24547
` return createElement(HTMLPage, {`,
24648
` ...${JSON.stringify(props)},`,
@@ -250,39 +52,10 @@ export const markdownLoader = async ({ specifier }: LoadInput, aleph: Aleph, { h
25052
`}`,
25153
`MarkdownPage.meta = ${JSON.stringify(meta)}`,
25254
]
253-
if (highlight) {
254-
const extra: string[] = [`import hljs from '${hljsUri}/lib/core'`]
255-
const activated: Set<string> = new Set()
256-
const hooks = [
257-
` const ref = useRef()`,
258-
` useEffect(() => ref.current && ref.current.querySelectorAll('code').forEach(el => hljs.highlightElement(el)), [])`
259-
]
260-
for (const m of html.matchAll(reCodeLanguage)) {
261-
let lang = m[1]
262-
if (lang === 'jsx' || lang === 'tsx') {
263-
activated.add('xml')
264-
}
265-
if (lang in languageAlias) {
266-
lang = (languageAlias as any)[lang]
267-
}
268-
if (languages.has(lang)) {
269-
activated.add(lang)
270-
}
271-
}
272-
activated.forEach(lang => {
273-
extra.push(
274-
`import ${lang} from '${hljsUri}/lib/languages/${lang}'`,
275-
`hljs.registerLanguage('${lang}', ${lang})`
276-
)
277-
})
278-
code.splice(6, 0, ` ref,`)
279-
code.splice(3, 0, ...hooks)
280-
code.unshift(...extra, `import '${hljsUri}/styles/${highlight.theme || 'default'}.css'`)
281-
}
28255

28356
if (framework === 'react') {
28457
return {
285-
code: code.join('\n')
58+
code: code.filter(Boolean).join('\n')
28659
}
28760
}
28861

0 commit comments

Comments
 (0)