vuejs / vitepress

Vite & Vue powered static site generator.
https://vitepress.dev
MIT License
11.48k stars 1.86k forks source link

Why I cannot use html in markdown file to insert an image with caption? #3262

Open liuguanfu1120 opened 5 months ago

liuguanfu1120 commented 5 months ago

Describe the bug

I am trying to use the follwing HTML code to insert an image with a caption:

<figure style="text-align: center;">
  <img src="path/to/your/image.png" alt="Description of the image">
  <figcaption>Caption describing the image</figcaption>
</figure>

If I run

npm run docs:dev

it works well. However, I cannot build it, i.e., by

npm run docs:build

Reproduction

  1. Add the following in a markdown file
    Description of the image
    Caption describing the image
  2. build it by "npm run docs:build"

Expected behavior

It should insert an image with a caption.

System Info

System:
    OS: macOS 13.5.2
    CPU: (10) arm64 Apple M1 Pro
    Memory: 211.97 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.16.1 - /usr/local/bin/node
    npm: 9.5.1 - /usr/local/bin/npm
  Browsers:
    Chrome: 119.0.6045.159
    Safari: 16.6
  npmPackages:
    vitepress: ^1.0.0-rc.29 => 1.0.0-rc.29

Additional context

No response

Validations

brc-dd commented 5 months ago

Please provide a reproducible example. It should work fine. Are there any errors on terminal during build or in devtools while previewing? What’s your directory structure and what’s the exact path you’re referencing? Have you tried using the latest version of vitepress?

liuguanfu1120 commented 5 months ago

Feeling sorry for any misleading. I found the problem:

 <figure style="text-align: center;">
  <img src="path/to/your/image.png" alt="Description of the image">
  <figcaption>Caption describing the image</figcaption>
</figure>

you must use absolute path in the HTML not the relative path.

liuguanfu1120 commented 5 months ago

However, it seems that there is another problem: I set

base: '/blog/'

in config.mts file, because my repository is named 'blog'. In addition, my file structure goes as follows,

image

I have a markdown file "test.md" and an image named "test-fit.png" both of which is in "/Notes". If I insert the "test-fig.png" in the "test.md" like

 <figure style="text-align: center;">
  <img src="/Notes/test-fig.png" alt="Description of the image">
  <figcaption>Caption describing the image</figcaption>
</figure>

and then

npm run docs:build
npm run docs:preview

works fine, but

npm run docs:dev

cannot show the figure.

I find that if I insert the image as follows

 <figure style="text-align: center;">
  <img src="/blog/Notes/test-fig.png" alt="Description of the image">
  <figcaption>Caption describing the image</figcaption>
</figure>

and then

npm run docs:dev

works fine. Therefore, the problem is that to make "npm run docs:dev" well, you should add "/blog/" (the base set in config.mts).

ghost commented 5 months ago

the latest version 1.0.0-rc31 has fixed a similar problem, maybe you can upgrade the version.

related issue: #3239

brc-dd commented 5 months ago

Relative paths should work too unless you are dynamically setting the src prop. Can you share some kind of repository where you are experiencing the issues?

liuguanfu1120 commented 5 months ago

the latest version 1.0.0-rc31 has fixed a similar problem, maybe you can upgrade the version.

related issue: #3239

Thanks! It helps!

liuguanfu1120 commented 5 months ago

Relative paths should work too unless you are dynamically setting the src prop. Can you share some kind of repository where you are experiencing the issues?

The version "1.0.0-rc.29" seems to be a little bit old. "1.0.0-rc31" works fine.

For the very first issue, it is: There is a markdown file "Note1.md" in the "Notes" folder. Since there are too many figures for the "Note1.md", a sub-folder "Note1-fig" was created in the "Notes" folder. At first, I inserted a figure in the "Notes1.md" like

![alt text](Note1-fig/Fig1.png)

everything is fine. However, I want to add a figure caption and center the figure. So I try:

 <figure style="text-align: center;">
  <img src="Note1-fig/Fig1.png" alt="Description of the image">
  <figcaption>Caption describing the image</figcaption>
</figure>

"npm run docs:dev" is OK, but "npm run docs:build" does not work. To solve it, I found that I have to do as follows

 <figure style="text-align: center;">
  <img src="/Notes/Note1-fig/Fig1.png" alt="Description of the image">
  <figcaption>Caption describing the image</figcaption>
</figure>

Namely, I have to use the absolute path.

I tested just now and found that version "1.0.0-rc.31" solved the problem. You can use either the absolute or relative path.

Thanks again for your kind reply!

brc-dd commented 5 months ago

src="./Note1-fig/Fig1.png" should also work I guess 👀

liuguanfu1120 commented 5 months ago

src="./Note1-fig/Fig1.png" should also work I guess 👀

Yeah! "Note1-fig/Fig1.png" is OK for markdown, so I just assume that it also works for HTML.

By the way, may I ask that: can the official provide some examples to insert images in the default template?

It is something like

<figure style="text-align: center;">
  <img src="./test.png" alt="test" style="display: block; margin: 0 auto;">
  <figcaption> Figure caption here </figcaption>
</figure>

It will be very helpful for the one who wants to enjoy vitepress but is new to HTML grammar.

fractalf commented 1 month ago

Hi, I wanted to do the same, but didn't feel like using html in markdown, so I added some pieces here and there and came up with this solution which solves it using a markdown-it plugin

![My alternative text](./my-image.jpg "My caption")
// .vitepress/config.mjs
export default defineConfig({
    ..
    markdown: {
        config: md => {
            const _super = md.renderer.rules.image
            md.renderer.rules.image = function (tokens, idx, options, env, self) {
                let title = tokens[idx].attrs[2]
                if (title) {
                    title = title[1]
                    const src = tokens[idx].attrs[0][1]
                    const alt = tokens[idx].content
                    return `
                        <figure>
                            <img src="${src}" alt="${alt}" title="${title}" />
                            <figcaption align="center">
                                <small>${title}</small>
                            </figcaption>
                        </figure>`
                }
                return _super(tokens, idx, options, env, self)
            }
        }
    },
})
2BAB commented 3 weeks ago

Hi, I wanted to do the same, but didn't feel like using html in markdown, so I added some pieces here and there and came up with this solution which solves it using a markdown-it plugin

![My alternative text](./my-image.jpg "My caption")
// .vitepress/config.mjs
export default defineConfig({
    ..
    markdown: {
        config: md => {
            const _super = md.renderer.rules.image
            md.renderer.rules.image = function (tokens, idx, options, env, self) {
                let title = tokens[idx].attrs[2]
                if (title) {
                    title = title[1]
                    const src = tokens[idx].attrs[0][1]
                    const alt = tokens[idx].content
                    return `
                        <figure>
                            <img src="${src}" alt="${alt}" title="${title}" />
                            <figcaption align="center">
                                <small>${title}</small>
                            </figcaption>
                        </figure>`
                }
                return _super(tokens, idx, options, env, self)
            }
        }
    },
})

This is an amazing transform script, I simply changed it and used it to show up the alt message. Kudo to @fractalf

fractalf commented 3 weeks ago

@2BAB I must make you aware that I ran into problems with this "quick fix" when building static assets.

You can see this issue here https://github.com/vuejs/vitepress/issues/3702

..I ended up writing my own Vue component to view images, it just made stuff so much easier.

I wanted to stay pure to markdown, but in the end I asked myself if it was really worth it. For me it wasn't and if I really do need pure markdown later on my current solution is really easy to convert to markdown anyway.

This is what I do now

bla bla bla some markdown

<Image name="my-image" caption="Some caption" right />

bla bla more markdown

It gives me so much more features as well and easier to add and extend. Example right floats the image to the right with text around it. Looks really nice. Also opening an image in a modal to see a big version, much easier.

Here's an example of the features I now get with images image

https://abc.fractalf.net/articles/005-how-do-chess-engines-work.html