pablo-abc / svelte-markdown

Markdown parser to svelte components
MIT License
360 stars 50 forks source link

Made tokens a prop of SvelteMarkdown #30

Closed wozzashek closed 3 years ago

wozzashek commented 3 years ago

Not sure if this is the best approach for this, but essentially I wanted to know all the tokens generated from a parent component.

This way I could pass all the heading tokens from my parent component to a ToC component to render my table of contents as asked here #29

I was tempted to dispatch an event when the tokens were generated so parent components could optionally grab the tokens that way.

Feel free to ignore this, or propose a better solution and I will work to your solution design if you haven't got time.

P.S I'm very inexperienced doing pull requests hopefully this is correct.

pablo-abc commented 3 years ago

If you're passing tokens directly to Svelte Markdown, that'd mean you're doing the actual markdown parsing (with marked) elsewhere. Wouldn't it be beneficial in this case to make the Parser an exported module? Assuming you have another dependency for marked installed, this would mean that SvelteMarkdown's copy wouldn't be bundled as well.

How does that sound for you?

wozzashek commented 3 years ago

I'm not actually passing tokens into SvelteMarkdown, instead I want to access the tokens generated by SvelteMarkdown from the parent component, so I can pass them to another component.

The example below shows how I pass my source into SvelteMarkdown, bind to the tokens that it generates, and feed only the heading tokens into my Table of Contents component to render.

Example code below:

<script>
  import SvelteMarkdown from "svelte-markdown";
  import ToC from "./Toc.svelte"

  let tokens = [];

  $: headings = tokens.filter((tok) => { return tok.type==='heading' });

  const source = '# Heading 1\n## Heading 2\n### Heading 3';

</script>

<SvelteMarkdown {source} {options} bind:tokens />

<!-- 
 This component will take the tokens and render a Table of contents,
 by using the tokens of type 'heading' generated by SvelteMarkdown
 -->

<Toc {headings} />

image

pablo-abc commented 3 years ago

Ah, got it. So you only need to obtain the tokens that have been parsed. In this situation I am not a big fan of this API since it'd create a two-way data binding (and it would imply that independently parsing the MD and passing it to the SvelteMarkdown component is accepted).

But I do see the usefulness of getting the parsed tokens. What do you think of making this an event? I feel that API would be a bit more intuitive. So it could look like this:

<SvelteMarkdown {source} on:parsed={(tokens) => /* do something with tokens */} />

Generally, events seem to be the most accepted way to get information up to a parent component.

wozzashek commented 3 years ago

Yes I was hesitant about the 2-way binding as well. I'll turn it into an event so user can hook into if they want to access the tokens.

wozzashek commented 3 years ago

Would I have to add something to index.d.ts about the on:parsed event?

pablo-abc commented 3 years ago

Would I have to add something to index.d.ts about the on:parsed event?

That'd be nice! But I can take care of it if you're not familiar with TypeScript.

wozzashek commented 3 years ago

Gave it a go but im not that familiar with Typescript so failed miserably.

pablo-abc commented 3 years ago

Ah, this looks perfect! I reopened #29 expecting this to take a bit longer. But even the documentation you've added looks flawless!

Thanks so much for the effort! I won't have time to publish this today, but hopefully tomorrow I'll get the type's added and publish it.

wozzashek commented 3 years ago

Any update on adding the type and publishing to NPM?

pablo-abc commented 3 years ago

Hey, @wozzashek. Sorry about the delay. I found the event was not being dispatched on my testing and hadn't had time to check why. I just pushed a fix for it and will be publishing it during the next few minutes.

wozzashek commented 3 years ago

I didn't even think to check if the component had mounted yet. Thanks for fixing it.