markdown-it-plantuml icon indicating copy to clipboard operation
markdown-it-plantuml copied to clipboard

Support for inline SVG

Open gavinmcfarland opened this issue 5 years ago • 5 comments

Thanks so much for creating this markdown-it plugin!

Would it be feasible to add support for inline SVG? This would allow authors to style the SVG using CSS to match the branding of their site.

gavinmcfarland avatar Sep 12 '19 12:09 gavinmcfarland

This plugin doesn't really deal with generating the images. This feature would probably require adding a library to the plugin that does PlantUml to SVG conversion, which I guess would be quite involved.

I'm open for suggestions if someone finds a clever way to do this.

gmunguia avatar Oct 17 '20 17:10 gmunguia

You're requesting SVG already I think, but instead of putting it in an tag just write out the SVG directly.

https://www.w3schools.com/graphics/svg_intro.asp

Mind you only modern browsers support this. But by doing this it will give us the capability of putting in links in the SVG.

I think the tricky bit is the fetch call to get the data because rules are not allowed to be async.

trajano avatar Mar 09 '21 05:03 trajano

In my case I needed this for VuePress where I wanted links. So leveraging what you already had without modifying your plugin directly (I did initially by adding the src value to the token itself)

module.exports = {
  chainMarkdown(config) {
    config.plugin("plantuml").use(require("markdown-it-plantuml"), [
      {
        render: (tokens, idx) => {
          const src = tokens[idx].attrs
            .filter(attr => attr[0] === "src")
            .map(attr => attr[1])[0];
          return `<EmbedSvg src="${src}" />`;
        }
      }
    ]);
  },
};

and the component

<template>
  <div v-html="raw">asdf</div>
</template>

<script>
export default {
  props: {
    src: String
  },
  data() {
    return { raw: "" };
  },
  async beforeMount() {
    this.raw = await fetch(this.src).then(response => response.text());
  }
};
</script>

trajano avatar Mar 09 '21 07:03 trajano

VuePress 2.0 (beta) with Vue 3 implementation of @trajano's code (exactly what I was looking for tonight; thank you, sir):

/* src/.vuepress/config.js */
import { defineUserConfig } from "@vuepress/cli";
import markdownitPlantUML from "markdown-it-plantuml";

export default defineUserConfig({
  //...
  extendsMarkdown: (md) => {
    md.use(markdownitPlantUML, {
      render: (tokens, idx) => {
        const [src] = tokens[idx].attrs
          .filter((attr) => attr[0] === "src")
          .map((attr) => attr[1]);
        return `<EmbedSvg src="${src}" />`;
      },
    });
  },
});
<!-- src/.vuepress/components/EmbedSvg.vue -->
<template>
  <div v-html="raw"></div>
</template>

<script setup>
import { ref, onBeforeMount } from "vue";

const props = defineProps({
  src: {
    type: String,
  },
});

const raw = ref("");

onBeforeMount(async () => {
  raw.value = await fetch(props.src).then((response) => response.text());
});
</script>

jrtitus avatar Nov 19 '22 03:11 jrtitus

The basic problem is actually markdown-it does not support async render methods, so as long as the text2svg conversion happens through network, we can not get svg codes directly.

I am trying to add plantuml into vuepress-plugin-md-enhance and meet this issue as well.

Mister-Hope avatar Nov 26 '23 16:11 Mister-Hope