Make Nuemark work on browsers
Describe the Bug
Nuemark can't be used by browser code, it has a nasty dependency on Node.js modules and can only be used in server code.
I'm not sure if this is a bug or intentional limitation but it does not seem like Nuemark was intended to only be used server-side so I will assume it's a bug until clarified.
Environment
Ubuntu 22.04 but all environments.
Minimal Reproduction
import { nuemark } from 'nuemark/index.js'
const html = nuemark(`Hello, World`)
console.info(html) // Hello, World
Logs & Additional Context
The first two lines of render-tag.js are:
import { join, extname } from 'node:path'
import { readFileSync } from 'node:fs'
These are mostly needed to load an svg icon in readIcon because it does not render the name of the file as the svg source, but actually tries to do a server-side read of the SVG content and insert it into the svg element.
I would like to see Nuemark support browser/client-side use, especially if it's only for svg icons that it is broken there.
Updated the title from issue to a new feature. I have thought about this: could be benefical for web AI assisted website generation. This is definitely in long-term roadmap
I think it's actually just small changes, except for the loading of the svg file content itself. The rest is just changing the path imports from:
import { join, extname } from 'node:path'
to
import { join, extname } from 'path'
since a copy of the node:path is available for browsers as path.
The only thing that doesn't fix in render-tag.js is the [svg ...] markdown. For SVG icons, since a file path is specified in the Nuemark content (e.g. [svg /icons/arrow-right.svg]), that could, and probably should translate directly to HTML on a browser letting the web server provide it, rather than trying to open the file and read it, e.g. something like:
<img src="/icons/arrow-right.svg" alt="arrow-right" />
At least for a browser implementation since it can't read the file. Or in the case of SVGs, get compiled inline as static HTML during a build. (Something to allow it to function to some degree, rather than break all the other markdown due to a missing import.) It would arguably be better to just drop the SVG markdown or display it as text, if there's no node/bun modules to import.
Well, inlined svg is way easier to style e.g. for night mode by using currentColor or so. Via img tag that won't work AFAIK.
Maybe fetch could be used to get the files content. Not sure about that. Problem would be, on how to do that locally (server side). Would have to be mocked somehow :/
Note: We don't really need the path import, as all the usage can be replaced with normal js. (str.split('.').at(-1) / arr.join('/'))
That's a really good point about currentColor and anything similar. Hmm.
I think my top concern here is that it feels more natural for a lib like Nuemark, which is fundamentally a rendering conversion lib, to normally live client-side, so at the very least it should still work there.
Dark mode support for svg icons, while important to get right, shouldn't break everything else in Nuemark (because it needs file I/O).
I'm not sure what the best solution is here (that's your call) but I can try to help.
One idea I had was to use Nue to request it server-side, but I think that violates the Unix-like philosophy of independent tools focusing on doing one thing well.
The other idea already mentioned is to fall back to src=path if Nuemark is found to be running client-side.
A third idea, perhaps the one I like most, is to conditionally load the fs module at runtime, only when needed (svg), via await import(). That way only svg markdown would be dependent on the node module, not all of Nuemark. We could just say svg isn't supported by the browser version. Or we could fall back to the src=x.svg version on browsers only.
It's breaks so much that I think we need a solution for browser use.