Markdown is really powerful, both for it’s simplicity and for the fact that it can be extended by using HTML/CSS.

This allows you to do things that Markdown can’t natively such as adding a caption to a figure:

<figure id="my-image">
    <img src="my_image.jpg" alt="don't forget to put some alt text here">
    <figcaption>This will be rendered below the image</figcaption>
</figure>

And even automatically numbering them by setting up a css counter in an internal <style> block. Fortunately for what we’re about to do, <style> blocks do not have to be in the document <head> to work.

<style>
    /* initialise the counter */
    body { counter-reset: figureCounter; }
    /* increment the counter for every instance of a figure even if it doesn't have a caption */
    figure { counter-increment: figureCounter; }
    /* prepend the counter to the figcaption content */
    figure figcaption:before {
        content: "Fig " counter(figureCounter) ": "
    }
</style>

Now every <figcaption> will be prepended with a fig number that is associated with it’s location, even if you don’t caption one of them.

placeholder kitten from placekitten.com
First fig
placeholder kitten from placekitten.com
placeholder kitten from placekitten.com
Last fig

Special Cases

Obsidian

Although this will work for most markdown editors, it does not work in Obsidian. However, should you want to recreate the behaviour there you can do so by creating an appropriately named css file in <vault>/.Obsidian/snippets and then activating the snippet via Settings > Appearance > CSS Snippets.

Ghost

If you use Ghost you will find that this method as written targets the Feature Image as well as any images you have defined as <figure> yourself. To get around that you can target .gh-content:

.gh-content { counter-reset: figureCounter; }
.gh-content figure { counter-increment: figureCounter; }
.gh-content figure figcaption::before {
    content: "Fig " counter(figureCounter) ": "
}

References