gmunguia / markdown-it-plantuml

:herb: :book: plantuml diagrams in your markdown
MIT License
99 stars 21 forks source link

Support for inline SVG #18

Open gavinmcfarland opened 5 years ago

gavinmcfarland commented 5 years ago

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.

gmunguia commented 3 years ago

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.

trajano commented 3 years ago

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 commented 3 years ago

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>
jrtitus commented 1 year ago

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>
Mister-Hope commented 10 months ago

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.