Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Programmatic approach to use @sveltejs/enhanced-img in markdown #11132

Open
LukaHarambasic opened this issue Nov 28, 2023 · 4 comments
Open

Programmatic approach to use @sveltejs/enhanced-img in markdown #11132

LukaHarambasic opened this issue Nov 28, 2023 · 4 comments

Comments

@LukaHarambasic
Copy link

LukaHarambasic commented Nov 28, 2023

Describe the problem

I would like to also improve images in markdown, therefore I use remark/rehype and inject a custom plugin to replace the img tag with <enhanced:img /> (see here). The HTML generated that way than gets used via {@html html} (see here).

The modified version (<enhanced:img />) than gets added to the DOM, so it sveltekit doesn't know that it has to do some magic.

Describe the proposed solution

I see two options:

  1. A programmatic approach to do the transformation manually during the markdown to HTML process.
  2. Somehow tell svelte that the HTML injected this way needs some special treatment.

Alternatives considered

No response

Importance

would make my life easier

Additional Information

PS: When I use it as described in the docu for the more basic use case it works as expected and I love it!!

@benmccann
Copy link
Member

I don't see the @html call you're referring to

If you wrote a plugin for mdsvex it would probably work because it'd get inserted into a Svelte component that could then be preprocessed

@ryansheehan
Copy link

I've been looking for a workaround on this very issue. I have a working solution for images within the content of a markdown file, and I am currently looking for a solution for images specified in the frontmatter.

For some context, I am using mdsvex with some plugins. I wanted to have my posts contained within a folder, and all assets for a post within that folder. I am using several remark/rehype plugins for help.

Remark

Rehype

Modifying svelte.config.js to use rehype-rewrite

import { mdsvex, escapeSvelte } from 'mdsvex';
import remarkUnwrapImages from 'remark-unwrap-images';
import relativeImages from 'mdsvex-relative-images';
import rehypeRewrite from 'rehype-rewrite';

/** @type {import('mdsvex').MdsvexOptions} */
const mdsvexOptions = {
    ...,
    remarkPlugins: [
        remarkUnwrapImages,
        relativeImages,
    ],
    rehypePlugins: [
        [rehypeRewrite, {
            rewrite: (node) => {
                // replace img tags with enhanced:img
                if (node.type == 'element' && node.tagName == 'img') {
                    node.tagName = 'enhanced:img';
                    // add a css class "post-img" for styling purposes
                    node.properties['class'] = `post-img ${node.properties['class'] ?? ''}`.trimEnd();
                }

                // change the image import lines to have the "?enhanced" query param and carry
                // over any additional vite image transformations specified from the markdown source
                if (node.type == 'raw' && node.value?.startsWith("<script>")) {
                    const re = /"\.[\\\/].*\.(apng|avif|gif|jpg|jpeg|jfif|pjpeg|pjp|png|svg|webp)\??.*"/gm;
                    let newValue = node.value;
                    Array.from(node.value.match(re)).forEach(m => {
                        const relativePath = m.split('"')[1];
                        // using URL to help parse the src properties
                        // this allows us to specify vite image transformations on the src string in markdown
                        // the "c://" is just needed to help make parse a valid URL path, it's ultimately ignored
                        const url = new URL(relativePath, "c://");
                        // make sure the enhanced attribute is added so we don't have to specify it in markdown
                        url.searchParams.append('enhanced', '');
                        const updatedPath = `".${url.pathname}${url.search}"`;
                        newValue = newValue.replace(m, updatedPath);
                    })
                    node.value = newValue;
                }
            }
        }],
    ]
}

/** @type {import('@sveltejs/kit').Config} */
const config = {
        ...,
	extensions: ['.svelte', '.svx', '.md'],
        preprocess: [
		vitePreprocess(),
		mdsvex(mdsvexOptions),
	],
}

@LukaHarambasic
Copy link
Author

@benmccann

I don't see the @html call you're referring to

Updated in the issue and it's here: https://github.com/LukaHarambasic/harambasic.de/blob/main/src/routes/posts/%5Bslug%5D/Entry.svelte#L38

If you wrote a plugin for mdsvex it would probably work because it'd get inserted into a Svelte component that could then be preprocessed

mdsvex seems limiting for me as I have some other uses cases as well, where I would need another md to HTML conversion as well.

@ryansheehan
That's what i did, just without mdsvex, I also hooked into the process and provided my own plugin to do this.

@benmccann benmccann changed the title Programatic approach to use <enhanced:img /> in @sveltejs/enhanced-img Programmatic approach to use @sveltejs/enhanced-img in markdown Jan 13, 2024
@benallfree
Copy link

The https://www.npmjs.com/package/mdsvex-enhanced-images plugin will make MDsveX process normal Markdown images using enhanced-images.

Prior art:
pngwn/MDsveX#246
pngwn/MDsveX#550

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants