2024-10-12 23:47:09 -05:00
|
|
|
<script lang="ts">
|
2024-10-16 15:23:51 -05:00
|
|
|
import rehypeDocument from 'rehype-document';
|
|
|
|
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
|
|
|
|
import rehypeStringify from 'rehype-stringify';
|
|
|
|
import remarkParse from 'remark-parse';
|
|
|
|
import remarkRehype from 'remark-rehype';
|
|
|
|
import { unified } from 'unified';
|
|
|
|
|
2024-10-16 12:36:50 -05:00
|
|
|
import { pane } from '$lib/stores/nav.js';
|
2024-10-12 23:47:09 -05:00
|
|
|
|
2024-10-16 12:36:50 -05:00
|
|
|
interface Props {
|
|
|
|
mobile?: boolean;
|
|
|
|
markdown: string;
|
|
|
|
stylesheet: string;
|
|
|
|
}
|
2024-10-12 23:47:09 -05:00
|
|
|
|
2024-10-16 12:36:50 -05:00
|
|
|
let { mobile = true, markdown, stylesheet }: Props = $props();
|
2024-10-12 23:47:09 -05:00
|
|
|
|
2024-10-16 12:36:50 -05:00
|
|
|
let hidden: boolean = $derived(mobile ? $pane !== 'preview' : true);
|
2024-10-16 15:23:51 -05:00
|
|
|
|
|
|
|
let output: Promise<string> = $derived.by(async () => {
|
|
|
|
let allowedTags: string[] = ['body', 'head', 'html', 'style'];
|
|
|
|
if (defaultSchema.tagNames) {
|
|
|
|
allowedTags = [...defaultSchema.tagNames, ...allowedTags];
|
|
|
|
}
|
|
|
|
return String(
|
|
|
|
await unified()
|
|
|
|
.use(remarkParse)
|
|
|
|
.use(remarkRehype)
|
|
|
|
.use(rehypeDocument, { style: stylesheet })
|
|
|
|
.use(rehypeSanitize, {
|
|
|
|
...defaultSchema,
|
|
|
|
allowDoctypes: true,
|
|
|
|
tagNames: allowedTags,
|
|
|
|
})
|
|
|
|
.use(rehypeStringify)
|
|
|
|
.process(markdown),
|
|
|
|
);
|
|
|
|
});
|
2024-10-12 23:47:09 -05:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<main class:hidden class:mobile data-testid="preview-pane">
|
|
|
|
<h2>markdown:</h2>
|
|
|
|
<code>{markdown}</code>
|
|
|
|
<h2>stylesheet:</h2>
|
|
|
|
<code>{stylesheet}</code>
|
2024-10-16 15:23:51 -05:00
|
|
|
<h2>output:</h2>
|
|
|
|
{#await output}
|
|
|
|
<p>processing...</p>
|
|
|
|
{:then result}
|
|
|
|
<iframe title="résumé preview" srcdoc={result}></iframe>
|
|
|
|
{:catch err}
|
|
|
|
<p style:color="red">error: {err}!</p>
|
|
|
|
{/await}
|
2024-10-12 23:47:09 -05:00
|
|
|
</main>
|
|
|
|
|
|
|
|
<style lang="less">
|
2024-10-12 23:55:40 -05:00
|
|
|
code {
|
|
|
|
display: block;
|
|
|
|
padding: @padding-md-x 0;
|
|
|
|
}
|
|
|
|
|
2024-10-12 23:47:09 -05:00
|
|
|
main {
|
|
|
|
grid-area: preview;
|
2024-10-12 23:55:40 -05:00
|
|
|
margin: 0;
|
|
|
|
padding: @padding-lg;
|
2024-10-12 23:47:09 -05:00
|
|
|
|
|
|
|
&.mobile {
|
|
|
|
grid-area: editor;
|
|
|
|
|
|
|
|
&.hidden {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-10-12 23:55:40 -05:00
|
|
|
|
|
|
|
h2 {
|
|
|
|
font-weight: @font-w-semibold;
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
}
|
2024-10-12 23:47:09 -05:00
|
|
|
</style>
|