-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Allow titles for code blocks * Add tests and CSS; fmt * fix --------- Co-authored-by: crowlkats <[email protected]>
- Loading branch information
1 parent
f4ae669
commit 46fa230
Showing
5 changed files
with
160 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
cov_profile | ||
deno.lock | ||
deno.lock | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,17 @@ | ||
import { emojify } from "emoji"; | ||
import * as Marked from "marked"; | ||
import GitHubSlugger from "github-slugger"; | ||
import he from "he"; | ||
import katex from "katex"; | ||
import * as Marked from "marked"; | ||
import markedAlert from "marked-alert"; | ||
import markedFootnote from "marked-footnote"; | ||
import { gfmHeadingId } from "marked-gfm-heading-id"; | ||
import Prism from "prismjs"; | ||
import sanitizeHtml from "sanitize-html"; | ||
import he from "he"; | ||
import katex from "katex"; | ||
import "prismjs-yaml"; | ||
|
||
import { CSS, KATEX_CLASSES, KATEX_CSS } from "./style.ts"; | ||
export { CSS, KATEX_CSS, Marked }; | ||
import "https://esm.sh/[email protected]/components/prism-yaml"; | ||
|
||
Marked.marked.use(markedAlert()); | ||
Marked.marked.use(gfmHeadingId()); | ||
|
@@ -39,11 +39,7 @@ export class Renderer extends Marked.Renderer { | |
this.#slugger = new GitHubSlugger(); | ||
} | ||
|
||
heading( | ||
text: string, | ||
level: 1 | 2 | 3 | 4 | 5 | 6, | ||
raw: string, | ||
): string { | ||
heading(text: string, level: 1 | 2 | 3 | 4 | 5 | 6, raw: string): string { | ||
const slug = this.#slugger.slug(raw); | ||
return `<h${level} id="${slug}"><a class="anchor" aria-hidden="true" tabindex="-1" href="#${slug}"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>${text}</h${level}>\n`; | ||
} | ||
|
@@ -53,6 +49,13 @@ export class Renderer extends Marked.Renderer { | |
} | ||
|
||
code(code: string, language?: string): string { | ||
const isTitleIncluded = language?.match(/\stitle="(.+)"/); | ||
let title = null; | ||
if (isTitleIncluded) { | ||
language = language!.split(" ")[0]; | ||
title = isTitleIncluded[1]; | ||
} | ||
|
||
// a language of `ts, ignore` should really be `ts` | ||
// and it should be lowercase to ensure it has parity with regular github markdown | ||
language = language?.split(",")?.[0].toLocaleLowerCase(); | ||
|
@@ -70,7 +73,10 @@ export class Renderer extends Marked.Renderer { | |
return `<pre><code class="notranslate">${he.encode(code)}</code></pre>`; | ||
} | ||
const html = Prism.highlight(code, grammar, language!); | ||
return `<div class="highlight highlight-source-${language} notranslate"><pre>${html}</pre></div>`; | ||
const titleHtml = title | ||
? `<div class="markdown-code-title">${title}</div>` | ||
: ``; | ||
return `<div class="highlight highlight-source-${language} notranslate">${titleHtml}<pre>${html}</pre></div>`; | ||
} | ||
|
||
link(href: string, title: string | null, text: string): string { | ||
|
@@ -153,10 +159,11 @@ export function render(markdown: string, opts: RenderOptions = {}): string { | |
|
||
const marked_opts = getOpts(opts); | ||
|
||
const html = | ||
(opts.inline | ||
const html = ( | ||
opts.inline | ||
? Marked.marked.parseInline(markdown, marked_opts) | ||
: Marked.marked.parse(markdown, marked_opts)) as string; | ||
: Marked.marked.parse(markdown, marked_opts) | ||
) as string; | ||
|
||
if (opts.disableHtmlSanitization) { | ||
return html; | ||
|
@@ -231,6 +238,7 @@ export function render(markdown: string, opts: RenderOptions = {}): string { | |
"notranslate", | ||
"markdown-alert", | ||
"markdown-alert-*", | ||
"markdown-code-title", | ||
], | ||
span: [ | ||
"token", | ||
|
@@ -312,18 +320,22 @@ export function render(markdown: string, opts: RenderOptions = {}): string { | |
annotation: ["encoding"], // Only enabled when math is enabled | ||
details: ["open"], | ||
section: ["data-footnotes"], | ||
input: ["checked", "disabled", { | ||
name: "type", | ||
values: ["checkbox"], | ||
}], | ||
input: [ | ||
"checked", | ||
"disabled", | ||
{ | ||
name: "type", | ||
values: ["checkbox"], | ||
}, | ||
], | ||
}; | ||
|
||
return sanitizeHtml(html, { | ||
transformTags: { | ||
img: transformMedia, | ||
video: transformMedia, | ||
}, | ||
allowedTags: [...defaultAllowedTags, ...opts.allowedTags ?? []], | ||
allowedTags: [...defaultAllowedTags, ...(opts.allowedTags ?? [])], | ||
allowedAttributes: mergeAttributes( | ||
defaultAllowedAttributes, | ||
opts.allowedAttributes ?? {}, | ||
|
@@ -356,14 +368,12 @@ function stripTokens( | |
|
||
for (const token of tokens) { | ||
if (token.type === "heading") { | ||
sections[index].header = sections[index].header.trim().replace( | ||
/\n{3,}/g, | ||
"\n", | ||
); | ||
sections[index].content = sections[index].content.trim().replace( | ||
/\n{3,}/g, | ||
"\n", | ||
); | ||
sections[index].header = sections[index].header | ||
.trim() | ||
.replace(/\n{3,}/g, "\n"); | ||
sections[index].content = sections[index].content | ||
.trim() | ||
.replace(/\n{3,}/g, "\n"); | ||
|
||
sections.push({ header: "", depth: token.depth, content: "" }); | ||
index += 1; | ||
|
@@ -488,20 +498,21 @@ export function stripSplitBySections( | |
markdown: string, | ||
opts: RenderOptions = {}, | ||
): MarkdownSections[] { | ||
markdown = emojify(markdown).replace(BLOCK_MATH_REGEXP, "").replace( | ||
INLINE_MATH_REGEXP, | ||
"", | ||
); | ||
markdown = emojify(markdown) | ||
.replace(BLOCK_MATH_REGEXP, "") | ||
.replace(INLINE_MATH_REGEXP, ""); | ||
const tokens = Marked.marked.lexer(markdown, { | ||
...getOpts(opts), | ||
tokenizer: new StripTokenizer(), | ||
}); | ||
|
||
const sections: MarkdownSections[] = [{ | ||
header: "", | ||
depth: 0, | ||
content: "", | ||
}]; | ||
const sections: MarkdownSections[] = [ | ||
{ | ||
header: "", | ||
depth: 0, | ||
content: "", | ||
}, | ||
]; | ||
stripTokens(tokens, sections, false); | ||
|
||
return sections; | ||
|
@@ -511,7 +522,11 @@ export function stripSplitBySections( | |
* Strip all markdown syntax to get a plaintext output | ||
*/ | ||
export function strip(markdown: string, opts: RenderOptions = {}): string { | ||
return stripSplitBySections(markdown, opts).map((section) => | ||
section.header + "\n\n" + section.content | ||
).join("\n\n").trim().replace(/\n{3,}/g, "\n") + "\n"; | ||
return ( | ||
stripSplitBySections(markdown, opts) | ||
.map((section) => section.header + "\n\n" + section.content) | ||
.join("\n\n") | ||
.trim() | ||
.replace(/\n{3,}/g, "\n") + "\n" | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.