pngwn / mdsvex Goto Github PK
View Code? Open in Web Editor NEWA markdown preprocessor for Svelte.
Home Page: https://mdsvex.pngwn.io
License: MIT License
A markdown preprocessor for Svelte.
Home Page: https://mdsvex.pngwn.io
License: MIT License
I'm using MDsveX to create the documentation for my Svelte webapp. But, I'm running into difficulties getting the code highlighting to work. I'm using the highlight.js module and I can see everything loading into the browser, but the code isn't being highlighted. If you have a working example, I can most likely figure where I went wrong from it. Thanks.
Is it possible? Can you document this @pngwn ?
The decision to use markdown-it
was relatively arbitrary when I put this together initially: the performance was okay and there are a decent array of plugins. I've found it pretty annoying over time, however, and have been investigating alternatives. marked
is the obvious candidate due to its focus on performance (performance is a concern for sites with more content) but there don't seem to be as many plugins and I don't want to limit what users can actually do with MDsveX, although it does have a decent API. remarkable
is another candidate and, if performance is the priority, might a better option.
In that vein, I began investigating other solutions. remark
was my initial preference but I assumed (without any testing whatsoever) that it would be quite a bit slower due to the fact it builds an AST, but my very basic benchmarks have shown this to be a false assumption. It seems to be just as fast as marked
in my preliminary tests (these tests include writing to an HTML string). What is more, there are a huge array of plugins available and having access to an AST gives a huge amount of flexibility when it is needed.
remark
will almost definitely have higher memory consumption than a simple lexer/parser with no intermediary AST but this seems to be a trade-off that people are willing to make. There is precedent here as MDX uses Remark and no-one seems to mind much, although what is palatable to one community is not necessarily so for another.
I'll look into this over the coming weeks and take a closer look at the impact this change would have on both build times and memory consumption, the plugin ecosystem seems healthy (which matters quite a bit) but I'll do some more research in that regard as well. When I have more concrete data on the tradeoffs between the two I will make a decision.
Would you accept a PR for a frontmatter option which would basically be a callback that is passed the attributes
value? I'm trying to get the frontmatter data in a less roundabout way. Thanks!
sdasdasd
in MDX theres a concept of a provider where for example you can supply your own <img>
and <pre>
and so on components. as far as i can tell the only similar concept here is custom Layout?
Is it possible to change the variable name? Currently it seems like you can safely format .svx files with prettier (using markdown parser). Unfortunately the _metadata
gets escaped to \_metadata
.
This would be a cheaper solution than writing a custom parser for prettier. I haven't dived much into svx so there might be more issues.
Hi,
I would like to use SVX files with Sapper dynamic routing (eg. routes/blog/[slug].svelte
, routes/blog/[slug].json.js
). Wondering if it’s possible to use mdsvex the way marked is use in Svelte’s official site (relevant code here)?
Thanks!
hey,
https://mdsvex.pngwn.io/ shows a blank result, its <body>
seems to be empty. see screenshots below.
macOS Catalina 10.15.2, same empty result on Firefox 74.0, Brave 1.3.115 (Chromium 80.0......) and Safari
EDIT: My bad, file was ignored by Mdsvex and preprocess directly by svelte
How do you create #anchors with MDsveX?
sdasdadasd
Getting this error when using layouts;
Uncaught ReferenceError: Layout_MDSVEX_DEFAULT is not defined
Svelte version: 3.20.1
Config:
svelte({
extensions: ['.svelte', '.md', '.svx'],
preprocess: mdsvex({
remarkPlugins: [slug],
extension: '.svx',
layout: {
"blogpost": "./src/components/MarkdownBlogLayout.svelte"
}
}),
post.svx
---
layout: blogpost
---
```html
```MarkdownBlogLayout.svelte
<slot />
<slot name="default" >default</slot> <!-- this line makes no difference -->
Not sure if this is of any value to you, but sharing is caring and all that...
Hi,
I was wondering how possible it would be, to let a user chose what to pass as a property to the layout?
A little example:
I am building a static blog, where each post is a svexy
. Each post exposes a Metadata object, just like this:
'''js module
export const Metadata = {
title: 'My Nice Article',
date: '20 March 2000',
seoDescription: 'My Old test'
};
'''
this is a really nice article we have here.
Then I obviously build a blog index by just requiring this data object on the backend
. It would be amazing if in some way I could have access to this object in the layout as a property.
Now, you could ask me: why not use the frontmatter?
And there are several reasons for that:
backend
to parse the frontmatter.import myThumbnailURL from 'thumbnail.jpg';
export Metadata = { thumbnail: myThumbnailURL }:
Right now I found a workaround, but I think it could be a super nice feature. Tell me what you think about it!
Easier to manage.
Hello. I just started using MDsveX with sapper and it was all going well until I started testing my site with javascript off. It looks like the markdown isn't be rendered at all.
If this is a bug I can work on a test case. If it's by design then I suggest adding support for server-side rendering (and as a consequence, static site export).
Here's a simple example with an HTML codeblock:
## Hello world
```
<a>Hello world</a>
```
This is parsed literally in 0.8, the back-tick fencing is ignored and a link is rendered.
as i explore this space more i think the ideal authoring experience really looks something like this:
---
title: foo
bar: baz
---
<script>
import Counter from './path/to/Counter.svelte';
import {H1, UL, LI} from './customComponents.svelte';
let number = 500;
export let mdsvexComponents = {H1, UL, LI}
</script>
<style>
ul {
color: red
}
</style>
<script module>
export let potato = "russet"
</script>
# hi! this is markdown in svelte!
<Counter count="{number}" />
Inline components <Counter count="{5}" /> are absolute fine too.
I like lists:
- these are rendered
- with custom svelte
- components
\```js
const str = `this just displays as a normal code block`
\```
so working backwards from the ideal experience we could explore being a loader fork instead of being a svelte preprocessor?
I have a bunch of markdown files in my routes/ directory in a Sapper app. I am noticing the styles from one markdown file applied to other markdown files. If this is not the desired behavior, I will try to be more specific about what makes the problem occur.
Hi,
I like using the new highlighter, Prism, but I don't see how you setup the theme. You should have a mention of that in the website.
Also, I can't use a code block in the "Try" section of your website. It just dies saying I need a }
. The code I tried to insert was:
if (true) {
console.log("JavaScript");
}
Currently errors are a bit hit or miss: some get swallowed and there are silent and confusing failures (YAML parsing failures for example), other fail noisily but unhelpfully.
We should be recovering with helpful messages where possible and failing noisily but helpfully where that is not possible.
One key aspect fo this is trying to resolve paths to layouts and components and providing helpful messages when this fails. Figuring out relatives vs absolute paths will help here, as we can provide more descriptive messages in this case.
SHould be straightforward for the common cases.
Hi,
Really great plugin, works pretty well!
I found a little something, that is linked to how MarkdownIt parses images.
If we want to use a variable for an image URL, markdownIT will converts the URLs to unicode. So this variable will not be able to be parsed after.
Example:
This markdown line:
![]({ thumbnailURL })
outputs that:
<p><img src="%7Bthumbnail%7D" alt=""></p>
This isn't necessarily an issue, possibly just something that needs to be more explicit in the README. When including Svelte components in your Markdown, you need to quote any attributes taking curly braces.
So
<MyButton on:click={() => alert('Click')}>Hello</MyButton>
doesn't work, but this will:
<MyButton on:click="{() => alert('Click')}">Hello</MyButton>
The latter is valid Svelte, and I don't have a strong objection to doing it that way, but it isn't the way I was used to and it took me a while to figure out that markdown-it
wasn't recognizing the opening tag as valid HTML, which makes sense.
asdasd
Hi,
This may be a tricky problem to solve, imagine this situation:
---
layout: './layouts/about.svelte'
---
<h1 class='noooes'>Test</h1>
<style>
.noooes {
color: white;
}
</style>
The style will not get applied to the <h1>
tag. When removing the layout, the still gets applied.
My guess is that at some poin the <style>
tag may be exported for the Layout component but not for the file component? (I mean the svexy).
Problem
mdast-util-to-hast
is passed a deprecated option
mdast-util-to-hast: deprecation: `allowDangerousHTML` is nonstandard, use `allowDangerousHtml` instead
Solution
PassallowDangerousHtml
instead.
In the https://mdsvex.pngwn.io playground
in Seriously.svelte
change
<div><slot></slot></div>
to
<div><slot name='a'></slot><slot name='b'></slot></div>
in App.svexy
change
<Seriously>
### I wasn't joking
...
</Seriously>
to
<Seriously>
<div slot='a'>**A**</div>
<div slot='b'>*B*</div>
</Seriously>
Markup **A**
and *B*
in named slots are not changed to A
and B.
a bit self promotional but may make it easier for people...
ssg adds mdsvex in the rollup config by default: https://github.com/sw-yx/ssg
Version: 0.5.1 beta 0
It seems like using several preprocessors does not work correctly on layout files. This is what I am using at the moment:
preprocess: [
mdsvex({
layout: "./src/layouts/Test.svelte"
}),
sveltePreprocess()
],
The preprocessors seem to be working as expected on mdsvex files.
That's pretty much it. Even if you try and import via a Svelte component that uses it, you are toast. So I just switched to using marked
for my runtime Markdown renders.
Version: 0.5.1 beta 0
it looks like this works:
mdsvex({
layout: "./src/layouts/Test.svelte"
})
But this does not:
mdsvex({
layouts: {
test: "./src/layouts/Test.svelte",
_: "./src/layouts/Test.svelte"
}
});
The latter seems to result in no layout being used at all. Adding layout: test
to the mdsvex file does not seem to help either.
It seems there's an ongoing "standardisation" effort for MDX :
https://github.com/mdx-js
https://github.com/mdx-js/specification
But... it seems JSX based.
Reading their transpilation pipeline, it seems that if we can hook into the last steps, it could be usable to generate svelte components. Unfortunately, it also seems that MDX syntax offers less possibilities than the MDsveX one, but I may haven't read enough.
How this project could relate to MDsveX ?
Hi, thanks a lot for MDsveX,
Since I tried it with sapper, it blew my mind !
On the readme, you states :
A Sapper/MDsveX template is also in the works (and by 'in the works' I mean that I haven't started it yet).
In your opinion, what's lacking ? Integration with sapper is a breeze with your instructions, the only "difficult" part was figuring out to call sapper with the --ext '.svelte .svx'
parameter.
I also noticed a potential bug, when using css style fenced code blocks. Sapper keeps complaining about unused CSS selectors, even if the scoped style rule is being generated and applied on the resulting webpage.
Currently trying to add some OG tags to my pages and running into an issue. Using the following code:
<svelte:head>
<meta property="og:title" content={title} />
<meta property="og:type" content="article" />
<meta property="og:url" content="{host}{path}" />
</svelte:head>
I get the following error:
<svelte:head> tags cannot be inside elements or blocks
13: <Layout_MDSVEX_DEFAULT {...metadata}>
14:
15: <svelte:head>
^
16: <meta property="og:title" content={title} />
17: <meta property="og:type" content="article" />
The 'Try it' page contains the following phrase:
You can't use
each
blocks. Don't try, it wont work.
Of course I tried it. They do in fact work...
Try this:
```js exec
let cats = [
{ id: 'J---aiyznGQ', name: 'Keyboard Cat' },
{ id: 'z_AbfPXTKms', name: 'Maru' },
{ id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' }
];
```
<ul>
{#each cats as cat}
<li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}">
{cat.name}
</a></li>
{/each}
</ul>
The demo at https://mdsvex.pngwn.io/ seems to give no output (Chrome, latest)
I think i should be able to build all 5 million language definitions to JSON modules and pop them somewhere accessible relatively easily. Since the preprocessor runs in a worker, loading modules on demand is a little more complicated than it might be. Bundling them and loading them up-front is not an option.
Currently, the browser build completely removes any highlighting because highlighting depends on node require
calls. If I wrap those require calls in a function to decouple the loading from any particular mechanism, I could use require in node builds and something else in the browser. I don't think dynamic imports inside workers are well supported but I could use importScript()
calls for this in the worker (which is also how mdsvex itself is loaded).
This might work. I think this would fix #65 as well.
When composing a link with a curlywurly inside it fails to work. When using a solo curlywurly it does work.
` ` `js exec
let variable = 'testing'
` ` `
> [Compound link](/base/{variable})
There are a number of accessibility and usability issues with the current docs site:
There are almost definitely more issues, I'll add to this as I look into it more closely. Some of these issues have SEO implications too but I care a lot less about that.
Hi,
There is a little parsing error when adding empty lines into a <script>
tag:
For instance, this will compile:
<style>
.nonono {
color: white;
}
</style>
And this will not compile:
<style>
.nonono {
color: white;
}
</style>
In the second case it looks like MarkdownIT will try to parse it, because the output is something like:
<style>
<p>.nonono {
color: white;
}</p></style>
So that, for example, writing js exec-render
instead of js exec
at the start of a fence would both add the code into the scripts section, as it does now, but also render it into the document, saving the effort of writing the code block twice.
I think something like a -render
suffix, as shown above, is the way to go, instead of a plugin or front-matter option. This way the author can control rendering for each block, instead of it being all or nothing. What do you think?
I'm happy to submit a PR if you like this idea. Thanks!
<svelte:head>
special elements have to be top level, applying a custom layout currently wraps these tags as well as everything else.
This is currently handled for style
and script
tags in a rehype
plugin (in the current rewrite) but the same needs to be done for svelte:head
tags. I also need to check if this is true for other tags. svelte:window
and svelte:body
probaby need the same treatment.
0.5 beta doesn't have any. I need to add them. JSDOC comments will also add nice in-editor descriptions for the API.
The current setup for sapper and webpack uses svelte-loader
as the default. I was wondering what's the right way to get MDsveX working in such a setup?
It seems that indenting HTML code when writing .svx components breaks the compiler and makes it think that elements weren't closed.
Seems to happen when there are multiple levels of indentation with space and returns like:
<main>
<h1>Major Headline</h1>
<section>
<p>Here is text</p>
<h2>A Second Heading</h2>
<SvelteComponentToRender />
```html
<h1>Example</h1>
<p>code block</p>
```
</section>
</main>
The error:
[!] (plugin svelte) ParseError: <section> was left open
src/App.svx
12: <main>
13: <h1>Major Headline</h1>
14: <section>
^
15: <p class="info">
16: All found on
ParseError: <section> was left open
at error (project_folder/node_modules/svelte/src/compiler/utils/error.ts:25:16)
at Parser$1.error (project_folder/node_modules/svelte/src/compiler/parse/index.ts:93:3)
at new Parser$1 (project_folder/node_modules/svelte/src/compiler/parse/index.ts:54:9)
at parse (project_folder/node_modules/svelte/src/compiler/parse/index.ts:208:17)
at compile (project_folder/node_modules/svelte/src/compiler/compile/index.ts:79:14)
at project_folder/node_modules/rollup-plugin-svelte/index.js:252:22
at ModuleLoader.addModuleSource (project_folder/node_modules/rollup/dist/shared/rollup.js:17430:30)
at ModuleLoader.fetchModule (project_folder/node_modules/rollup/dist/shared/rollup.js:17491:9)
at project_folder/node_modules/rollup/dist/shared/rollup.js:17461:36
at async Promise.all (index 0)
I wasn't sure if this was a Markdown thing i wasn't aware of or if it is MDsvX related.
If this is clear as mud I will try to get a better example for ya!
mdsvex supports YAML front-matter out of the box but people might want to use a custom language in their fontmatter. As long as the function returns an object of key vaue pairs this should be fine.
Error handling needs to be considered as well, unified
provides a really nice way to handle errors via messages
on the vFile
object, so some way to hook into this and provide custom error message/ object would be nice. See #39.
i've read #10, so i understand that this may be hard given the current setup of mdsvex, but the way i really do want to code is to use mdsvex as a single file component file authoring mechanism.
while this thing is still in early life, i think its worth considering if this is what we want (i'm also throwing in github flavored markdown mixing of markdown and html tags):
<script>
import Layout from './layout'
</script>
<style>
.noooes {
color: white;
}
</style>
<Layout>
<h1 class='noooes'>Test</h1>
- markdown li 1
- markdown li 2
- markdown li 3
</Layout>
this may mean forking rollup-plugin-svelte or integrating with it in some other way in order to be a superset.
Using backticks to escape '{...}' changes the styling. Is there a way to use brackets in text so that they get the same styling as the rest of the paragraph?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.