withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
46.16k stars 2.44k forks source link

Markdown code blocks lead to an error #233

Closed ewatch closed 3 years ago

ewatch commented 3 years ago

Description: When serving Markdown files with a code block and using frontmatter with a layout variable astro shows an error page.

Steps to reproduce:

  1. Create a blank astro project `npm init astro ./astro-blank``
  2. cd astro-blank
  3. Create a markdown file in /astro-blank/src/pages/ with the name `my-markdown.md``
  4. Put the following content into the markdown file
    
    ---
    layout: ../layouts/main.astro
    ---

My Markdown

Some source code

{ 
  "key": "value"
}

5. Create a layout file in `/astro-blank/layouts/main.astro``
6. Start astro with `npm start`
7. Access `localhost:3000/my-markdown`

Additionally I tried to use 

or

```html

which also lead to a different error.

Current Result: An error page will be displayed like this:

Bildschirmfoto 2021-05-24 um 10 10 15

Stack trace:

[executing astro] Error: Transform failed with 1 error:
<stdin>:1:5: error: Expected ";" but found ":"
    at failureErrorWithLog (/Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/esbuild/lib/main.js:1275:15)
    at /Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/esbuild/lib/main.js:1094:33
    at /Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/esbuild/lib/main.js:576:9
    at handleIncomingPacket (/Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/esbuild/lib/main.js:665:9)
    at readFromStdout (/Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/esbuild/lib/main.js:543:7)
    at runServiceSync (/Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/esbuild/lib/main.js:1591:3)
    at transformSync (/Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/esbuild/lib/main.js:1421:3)
    at compileExpressionSafe (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/astro/src/compiler/codegen/index.ts:260:18)
    at Object.enter (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/astro/src/compiler/codegen/index.ts:564:22)
    at SyncWalker.visit (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/estree-walker/src/sync.js:49:16)
    at SyncWalker.visit (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/estree-walker/src/sync.js:86:11)
    at SyncWalker.visit (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/estree-walker/src/sync.js:79:18)
    at SyncWalker.visit (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/estree-walker/src/sync.js:79:18)
    at SyncWalker.visit (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/estree-walker/src/sync.js:79:18)
    at walk (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/estree-walker/src/index.js:20:18)
    at compileHtml (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/astro/src/compiler/codegen/index.ts:547:3)
    at codegen (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/astro/src/compiler/codegen/index.ts:724:16)
    at convertAstroToJsx (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/astro/src/compiler/index.ts:44:10)
    at convertMdToJsx (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/astro/src/compiler/index.ts:84:10)
    at transformFromSource (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/astro/src/compiler/index.ts:98:14)
    at compileComponent (file:///Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/astro/src/compiler/index.ts:110:18)
    at Object.load (/Users/ewatch/Development/JavaScript/astro/astro-blank/node_modules/astro/snowpack-plugin.cjs:23:22) {
  errors: [
    {
      detail: undefined,
      location: [Object],
      notes: [],
      text: 'Expected ";" but found ":"'
    }
  ],
  warnings: [],
  __snowpackBuildDetails: { name: 'snowpack-astro', step: 'load' }
}

Expected Result: A proper HTML page with a code block not being interpreted will be displayed.

Analysis:

  1. In general Markdown will be converted to JSX and produce an html block like the following for the above code snippet and try to execute expressions in the template through the method convertMdToJsx

  2. The convertMdToAstroSource (which is called inside the convertMdToJsx method) converts the following markdown:

{ "key": "value" }

to this HTML block:

<pre><code>
{
    "key": "value"
}
</code></pre>
  1. The convertAstroToJsx uses the astro-parser which identifies the { as opening bracket for logic and marks this as MustacheTag as well as "key": "value" as Expression which will be tried to be compiled through the 'Expression' branch of the compileHtml method which is called by the code generator codegen.

Possible Solutions (not tested yet):

  1. Converting { and } to HTML entities inside <pre><code></code></pre> Blocks
  2. Replacing the code parts in markdown with something different and after compileHtml, replacing them back.
  3. Looking into the projects https://github.com/pngwn/MDsveX or https://github.com/AlexxNB/svelte-preprocess-markdown might also provide a solution
matthewp commented 3 years ago

Thanks, I found this this morning as well and am working on fix. Sorry for the disturbance, some recent upgrades to markdown support caused this regression but shouldn't be too hard of a fix.