Skip to content

Commit

Permalink
Upgrade marked (#217)
Browse files Browse the repository at this point in the history
* remove default renderer, apparently we never needed this?

* update to marked 13

* update to marked 14

* more

* more

* fix
  • Loading branch information
Rich-Harris authored Oct 2, 2024
1 parent 3b34bc6 commit f298c65
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 187 deletions.
2 changes: 1 addition & 1 deletion apps/svelte.dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"jimp": "^1.1.1",
"lightningcss": "^1.25.1",
"magic-string": "^0.30.11",
"marked": "^12.0.2",
"marked": "^14.1.2",
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.4",
"satori": "^0.10.13",
Expand Down
12 changes: 6 additions & 6 deletions apps/svelte.dev/src/routes/content.json/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ async function content() {
}

async function plaintext(markdown: string) {
const block = (text: unknown) => `${text}\n`;
const block = ({ text }: any) => `${text}\n`;

const inline = (text: string) => text;
const inline = ({ text }: any) => text;

return (
await markedTransform(markdown, {
code: (source) => source.split('// ---cut---\n').pop() || 'ERROR: ---cut--- not found',
code: ({ text }) => text.split('// ---cut---\n').pop() || 'ERROR: ---cut--- not found',
blockquote: block,
html: () => '\n',
heading: (text) => `${text}\n`,
Expand All @@ -108,16 +108,16 @@ async function plaintext(markdown: string) {
paragraph: (text) => `${text}\n\n`,
table: block,
tablerow: block,
tablecell: (text, opts) => {
tablecell: ({ text }) => {
return text + ' ';
},
strong: inline,
em: inline,
codespan: inline,
br: () => '',
del: inline,
link: (href, title, text) => text,
image: (href, title, text) => text,
link: inline,
image: inline,
text: inline
})
)
Expand Down
13 changes: 6 additions & 7 deletions apps/svelte.dev/src/routes/tutorial/[slug]/markdown.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,19 @@ function highlight_spans(content, classname) {

/** @type {Partial<import('marked').Renderer>} */
const default_renderer = {
code: (source, language = '') => {
code: ({ text, lang = '' }) => {
/** @type {Record<string, string>} */
const options = {};

let html = '';

source = source
let source = text
.replace(/\/\/\/ (.+?)(?:: (.+))?\n/gm, (_, key, value) => {
options[key] = value;
return '';
})
.replace(/^([\-\+])?((?: )+)/gm, (match, prefix = '', spaces) => {
if (prefix && language !== 'diff') return match;
if (prefix && lang !== 'diff') return match;

// for no good reason at all, marked replaces tabs with spaces
let tabs = '';
Expand All @@ -64,7 +64,7 @@ const default_renderer = {
})
.replace(/\*\\\//g, '*/');

if (language === 'diff') {
if (lang === 'diff') {
const lines = source.split('\n').map((content) => {
let type = null;
if (/^[\+\-]/.test(content)) {
Expand All @@ -85,10 +85,9 @@ const default_renderer = {
})
.join('')}</code></pre></div>`;
} else {
const lang = /** @type {keyof languages} */ (language);
const plang = languages[lang];
const plang = languages[/** @type {keyof languages} */ (lang)];
const highlighted = plang
? PrismJS.highlight(source, PrismJS.languages[plang], language)
? PrismJS.highlight(source, PrismJS.languages[plang], lang)
: escape_html(source);

html = `<div class="code-block">${
Expand Down
18 changes: 10 additions & 8 deletions apps/svelte.dev/src/routes/tutorial/content.json/+server.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,19 @@ async function content() {
return { blocks };
}

// TODO is this still used?

/** @param {string} markdown */
async function plaintext(markdown) {
/** @param {unknown} text */
const block = (text) => `${text}\n`;
/** @param {any} token */
const block = ({ text }) => `${text}\n`;

/** @param {string} text */
const inline = (text) => text;
/** @param {any} token */
const inline = ({ text }) => text;

return (
await markedTransform(markdown, {
code: (source) => source.split('// ---cut---\n').pop() ?? '',
code: ({ text }) => text.split('// ---cut---\n').pop() ?? '',
blockquote: block,
html: () => '\n',
heading: (text) => `${text}\n`,
Expand All @@ -54,16 +56,16 @@ async function plaintext(markdown) {
paragraph: (text) => `${text}\n\n`,
table: block,
tablerow: block,
tablecell: (text, opts) => {
tablecell: ({ text }) => {
return text + ' ';
},
strong: inline,
em: inline,
codespan: inline,
br: () => '',
del: inline,
link: (href, title, text) => text,
image: (href, title, text) => text,
link: inline,
image: inline,
text: inline
})
)
Expand Down
2 changes: 1 addition & 1 deletion packages/repl/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"acorn": "^8.11.3",
"esm-env": "^1.0.0",
"esrap": "^1.2.2",
"marked": "^11.2.0",
"marked": "^14.1.2",
"resolve.exports": "^2.0.2",
"svelte": "^5.0.0-next.243",
"zimmerframe": "^1.1.2"
Expand Down
2 changes: 1 addition & 1 deletion packages/site-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@types/node": "^20.12.11",
"flexsearch": "^0.7.43",
"magic-string": "^0.30.11",
"marked": "^12.0.2",
"marked": "^14.1.2",
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.4",
"shiki-twoslash": "^3.1.2",
Expand Down
48 changes: 28 additions & 20 deletions packages/site-kit/src/lib/markdown/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,42 +259,50 @@ async function parse({
// from linking to themselves
let current = '';

/** @type {string} */
const content = await transform(body, {
text: smart_quotes,
heading(html, level, raw) {
const title = html
return await transform(body, {
text(token) {
// @ts-expect-error I think this is a bug in marked — some text tokens have children,
// but that's not reflected in the types. In these cases we can't just use `token.tokens`
// because that will result in e.g. `<code>` elements not being generated
if (token.tokens) {
// @ts-expect-error
return this.parser!.parseInline(token.tokens);
}

return smart_quotes(token.text);
},
heading({ tokens, depth, raw }) {
const text = this.parser!.parseInline(tokens);

const title = text
.replace(/<\/?code>/g, '')
.replace(/&quot;/g, '"')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>');

current = title;

const normalized = normalizeSlugify(raw);

headings[level - 1] = normalized;
headings.length = level;

headings[depth - 1] = normalized;
headings.length = depth;
const slug = headings.filter(Boolean).join('-');

return `<h${level} id="${slug}">${html.replace(
return `<h${depth} id="${slug}">${text.replace(
/<\/?code>/g,
''
)}<a href="#${slug}" class="permalink"><span class="visually-hidden">permalink</span></a></h${level}>`;
)}<a href="#${slug}" class="permalink"><span class="visually-hidden">permalink</span></a></h${depth}>`;
},
code({ text, lang }) {
return code(text, lang ?? 'js', current);
},
codespan({ text }) {
return codespan(text);
},
code: (source, language) => code(source, language ?? 'js', current),
codespan,
blockquote: (content) => {
blockquote(token) {
let content = this.parser?.parse(token.tokens) ?? '';
if (content.includes('[!LEGACY]')) {
content = `<details class="legacy"><summary>Legacy mode</summary>${content.replace('[!LEGACY]', '')}</details>`;
}

return `<blockquote>${content}</blockquote>`;
}
});

return content;
}

/**
Expand Down
125 changes: 1 addition & 124 deletions packages/site-kit/src/lib/markdown/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,126 +91,6 @@ export function smart_quotes(str: string) {
});
}

const default_renderer: Partial<Renderer> = {
code(code, infostring, escaped) {
const lang = infostring?.match(/\S*/)?.[0];

code = code.replace(/\n$/, '') + '\n';

if (!lang) {
return '<pre><code>' + (escaped ? code : escape(code, true)) + '</code></pre>\n';
}

return (
'<pre><code class="language-' +
escape(lang, true) +
'">' +
(escaped ? code : escape(code, true)) +
'</code></pre>\n'
);
},

blockquote(quote) {
return '<blockquote>\n' + quote + '</blockquote>\n';
},

html(html) {
return html;
},

heading(text, level) {
return '<h' + level + '>' + text + '</h' + level + '>\n';
},

hr() {
return '<hr>\n';
},

list(body, ordered, start) {
const type = ordered ? 'ol' : 'ul',
startatt = ordered && start !== 1 ? ' start="' + start + '"' : '';
return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
},

listitem(text) {
return '<li>' + text + '</li>\n';
},

checkbox(checked) {
return '<input ' + (checked ? 'checked="" ' : '') + 'disabled="" type="checkbox"' + '' + '> ';
},

paragraph(text) {
return '<p>' + text + '</p>\n';
},

table(header, body) {
if (body) body = '<tbody>' + body + '</tbody>';

return '<table>\n' + '<thead>\n' + header + '</thead>\n' + body + '</table>\n';
},

tablerow(content) {
return '<tr>\n' + content + '</tr>\n';
},

tablecell(content, flags) {
const type = flags.header ? 'th' : 'td';
const tag = flags.align ? '<' + type + ' align="' + flags.align + '">' : '<' + type + '>';
return tag + content + '</' + type + '>\n';
},

// span level renderer
strong(text) {
return '<strong>' + text + '</strong>';
},

em(text) {
return '<em>' + text + '</em>';
},

codespan(text) {
return '<code>' + text + '</code>';
},

br() {
return '<br>';
},

del(text) {
return '<del>' + text + '</del>';
},

link(href, title, text) {
if (href === null) {
return text;
}
let out = '<a href="' + escape(href) + '"';
if (title) {
out += ' title="' + title + '"';
}
out += '>' + text + '</a>';
return out;
},

image(href, title, text) {
if (href === null) {
return text;
}

let out = '<img src="' + href + '" alt="' + text + '"';
if (title) {
out += ' title="' + title + '"';
}
out += '>';
return out;
},

text(text) {
return text;
}
};

const tokenizer: TokenizerObject = {
url(src) {
// if `src` is a package version string, eg: [email protected]
Expand All @@ -225,10 +105,7 @@ const tokenizer: TokenizerObject = {

export async function transform(markdown: string, renderer: Partial<Renderer> = {}) {
const marked = new Marked({
renderer: {
...default_renderer,
...renderer
},
renderer,
tokenizer
});

Expand Down
Loading

0 comments on commit f298c65

Please sign in to comment.