diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dev.ts | 7 | ||||
-rw-r--r-- | src/micromark-encode.ts | 35 | ||||
-rw-r--r-- | src/transform2.ts | 29 |
3 files changed, 61 insertions, 10 deletions
diff --git a/src/dev.ts b/src/dev.ts index 93a890057..c6ad9ff7c 100644 --- a/src/dev.ts +++ b/src/dev.ts @@ -57,6 +57,8 @@ export default async function (astroConfig: AstroConfig) { break; } } + res.statusCode = 500; + res.end(formatErrorForBrowser(result.error)); break; } } @@ -66,3 +68,8 @@ export default async function (astroConfig: AstroConfig) { console.log(`Server running at http://${hostname}:${port}/`); }); } + +function formatErrorForBrowser(error: Error) { + // TODO make this pretty. + return error.toString(); +}
\ No newline at end of file diff --git a/src/micromark-encode.ts b/src/micromark-encode.ts new file mode 100644 index 000000000..d205d13e3 --- /dev/null +++ b/src/micromark-encode.ts @@ -0,0 +1,35 @@ +import type { HtmlExtension, Token, Tokenize } from 'micromark/dist/shared-types'; + +const characterReferences = { + '"': 'quot', + '&': 'amp', + '<': 'lt', + '>': 'gt', + '{': 'lbrace', + '}': 'rbrace', +}; + +type EncodedChars = '"' | '&' | '<' | '>' | '{' | '}'; + +function encode(value: string): string { + return value.replace(/["&<>{}]/g, (raw: string) => { + return '&' + characterReferences[raw as EncodedChars] + ';'; + }); +} + +function encodeToken(this: Record<string, () => void>) { + const token: Token = arguments[0]; + const serialize = (this.sliceSerialize as unknown) as (t: Token) => string; + const raw = (this.raw as unknown) as (s: string) => void; + const value = serialize(token); + raw(encode(value)); +} + +const plugin: HtmlExtension = { + exit: { + codeTextData: encodeToken, + codeFlowValue: encodeToken, + }, +}; + +export { plugin as encodeMarkdown };
\ No newline at end of file diff --git a/src/transform2.ts b/src/transform2.ts index 2f1e651cf..42a151b3c 100644 --- a/src/transform2.ts +++ b/src/transform2.ts @@ -8,6 +8,7 @@ import gfmHtml from 'micromark-extension-gfm/html.js'; import { CompileResult, TransformResult } from './@types/astro'; import { parse } from './compiler/index.js'; import { createMarkdownHeadersCollector } from './micromark-collect-headers.js'; +import { encodeMarkdown } from './micromark-encode.js'; import { defaultLogOptions } from './logger.js'; import { optimize } from './optimize/index.js'; import { codegen } from './codegen/index.js'; @@ -54,8 +55,9 @@ async function convertMdToJsx( const { data: _frontmatterData, content } = matter(contents); const { headers, headersExtension } = createMarkdownHeadersCollector(); const mdHtml = micromark(content, { + allowDangerousHtml: true, extensions: [gfmSyntax()], - htmlExtensions: [gfmHtml, headersExtension], + htmlExtensions: [gfmHtml, encodeMarkdown, headersExtension], }); const setupContext = { @@ -68,19 +70,26 @@ async function convertMdToJsx( }, }; + let imports = ''; + for(let [ComponentName, specifier] of Object.entries(_frontmatterData.import || {})) { + imports += `import ${ComponentName} from '${specifier}';\n`; + } + // </script> can't be anywhere inside of a JS string, otherwise the HTML parser fails. // Break it up here so that the HTML parser won't detect it. const stringifiedSetupContext = JSON.stringify(setupContext).replace(/\<\/script\>/g, `</scrip" + "t>`); - return convertHmxToJsx( - `<script astro> - ${_frontmatterData.layout ? `export const layout = ${JSON.stringify(_frontmatterData.layout)};` : ''} - export function setup({context}) { - return {context: ${stringifiedSetupContext} }; - } - </script><section>{${JSON.stringify(mdHtml)}}</section>`, - { compileOptions, filename, fileID } - ); + const raw = `<script astro> + ${imports} + ${_frontmatterData.layout ? `export const layout = ${JSON.stringify(_frontmatterData.layout)};` : ''} + export function setup({context}) { + return {context: ${stringifiedSetupContext} }; + } +</script><section>${mdHtml}</section>`; + + const convertOptions = { compileOptions, filename, fileID }; + + return convertHmxToJsx(raw, convertOptions); } async function transformFromSource( |