support plantuml

This commit is contained in:
CofCool 2022-05-13 13:47:28 +08:00
parent ef6af8789b
commit 28c5b9ac87
17 changed files with 3250 additions and 150 deletions

2
.github/FUNDING.yml vendored
View File

@ -1 +1 @@
github: [hkgnp]
github: [cofcool]

View File

@ -24,7 +24,7 @@ jobs:
run: |
npm i && npm run build
mkdir ${{ env.PLUGIN_NAME }}
cp README.md package.json icon.svg ${{ env.PLUGIN_NAME }}
cp README.md package.json icon.png ${{ env.PLUGIN_NAME }}
mv dist ${{ env.PLUGIN_NAME }}
zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }}
ls

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2022 hkgnp
Copyright (c) 2022 hkgnp, CofCool
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,68 +1,26 @@
[[:gift_heart: Sponsor this project on Github](https://github.com/sponsors/hkgnp) or [:coffee: Get me a coffee](https://www.buymeacoffee.com/hkgnp.dev) if you like this plugin!
> Important! ⚠: This plugin will send your mermaid code to an [external server](https://mermaid.ink) **if** you do not set up your own local mermaid.ink server. Instructions for setting up your own local mermaid.ink server can be found [below](https://github.com/hkgnp/logseq-mermaid-plugin#using-with-your-own-local-mermaidink-server).
Note: This project is forked from [hkgnp/logseq-mermaid-plugin](https://github.com/hkgnp/logseq-mermaid-plugin)
# Overview
This simple plugin allows you to quickly insert mermaid diagrams in your notes, using either an external server or you have the option of setting up your own local one.
The render server default is https://www.plantuml.com/plantuml/png, you can change to your self server by plugin settings.
![](/screenshots/demo.gif)
Screenshots:
![demo](./screenshots/demo.png)
# Installation
If not available in the marketplace, [download the latest release](https://github.com/hkgnp/logseq-mermaid-plugin/releases) and manually load it into Logseq after unzipping.
If not available in the marketplace, [download the latest release](https://github.com/cofcool/logseq-plantuml-plugin/releases) and manually load it into Logseq after unzipping.
# Usage
To start, simply trigger it using `/Draw mermaid diagram`. Then add your mermaid syntax in the code block and click `Render`.
To start, simply trigger it using `/Draw plantuml diagram`. Then add your mermaid syntax in the code block and click `Render`.
## Changing background colour
# Todo
### Option 1
Same steps as above, but before clicking `Render`, include the colour inside the renderer, e.g.
```
{{renderer :mermaid_abc123, purple}}
or
{{renderer :mermaid_abc123, #000000}}
```
### Option 2
Define in your plugin settings file. This will apply to **all** mermaid diagrams that you render.
```
{
"config": {
"theme": "dark",
"colour": "#2f3437"
}
}
or
{
"config": {
"theme": "dark",
"colour": "gray"
}
}
```
# Using with your own local mermaid.ink server
1. Go to your terminal and navigate to where you would like to save the server files to, e.g. `cd ~/My\ Documents`
2. Enter `git clone https://github.com/jihchi/mermaid.ink && cd mermaid.ink && npm i && npm start` (This assumes that you already have NodeJS installed).
3. By default, your local mermaid.ink server will be running on port `3000`. This can be changed if you know what you are doing.
4. In Logseq, go to your plugin settings, and enter `3000`. Close the settings box.
![](/screenshots/mermaid-settings.png)
5. Proceed to draw your mermaid diagrams as per the [instructions above](https://github.com/hkgnp/logseq-mermaid-plugin#usage), and the images will be generated locally.
- [ ] Supports `plantuml.jar`
# Credits
[mermaid.ink](https://github.com/jihchi/mermaid.ink)
[mermaid-js-converter](https://github.com/superj80820/mermaid-js-converter) for the idea.
* [PlantUML](https://www.plantuml.com/)
* [hkgnp/logseq-mermaid-plugin](https://github.com/hkgnp/logseq-mermaid-plugin)

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -1,10 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-hierarchy" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="gray" fill="gray" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<circle cx="12" cy="5" r="2" />
<circle cx="5" cy="19" r="2" />
<circle cx="19" cy="19" r="2" />
<path d="M6.5 17.5l5.5 -4.5l5.5 4.5" />
<line x1="12" y1="7" x2="12" y2="13" />
</svg>

Before

Width:  |  Height:  |  Size: 471 B

11
package-lock.json generated
View File

@ -1,16 +1,15 @@
{
"name": "logseq-mermaid-plugin",
"version": "1.1.2",
"name": "logseq-plantuml-plugin",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "logseq-mermaid-plugin",
"version": "1.1.2",
"name": "logseq-plantuml-plugin",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@logseq/libs": "^0.0.1-alpha.35",
"js-base64": "^3.7.2"
"@logseq/libs": "^0.0.1-alpha.35"
},
"devDependencies": {
"buffer": "^6.0.3",

View File

@ -1,12 +1,12 @@
{
"logseq": {
"id": "logseq-mermaid-plugin",
"title": "logseq-mermaid-plugin",
"icon": "./icon.svg"
"id": "logseq-plantuml-plugin",
"title": "logseq-plantuml-plugin",
"icon": "./plantuml.png"
},
"name": "logseq-mermaid-plugin",
"version": "1.2.0",
"description": "",
"name": "logseq-plantuml-plugin",
"version": "1.0.0",
"description": "Render PlantUML in Logseq",
"main": "dist/index.html",
"targets": {
"main": false
@ -16,11 +16,10 @@
"build": "parcel build --no-source-maps src/index.html --public-url ./"
},
"keywords": [],
"author": "hkgnp",
"author": "CofCool",
"license": "MIT",
"dependencies": {
"@logseq/libs": "^0.0.1-alpha.35",
"js-base64": "^3.7.2"
"@logseq/libs": "^0.0.1-alpha.35"
},
"devDependencies": {
"buffer": "^6.0.3",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

BIN
screenshots/demo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

View File

@ -3,12 +3,12 @@ import { SettingSchemaDesc } from "@logseq/libs/dist/LSPlugin";
export const callSettings = () => {
const settings: SettingSchemaDesc[] = [
{
key: "port",
type: "number",
key: "server",
type: "string",
default: "",
description:
"If you are using a local mermaid.ink server, indicate the port number that mermaid.ink is running on. If you want to use https://mermaid.ink, then leave this field blank.",
title: "Port number",
"If you are using a local plantuml server, indicate the url that plantuml is running on. If you want to use https://www.plantuml.com/plantuml, then leave this field blank.",
title: "PlantUML url",
},
];

View File

@ -1,17 +1,17 @@
import { BlockUUID } from "@logseq/libs/dist/LSPlugin.user";
import { toBase64 } from "js-base64";
import { compress } from "./util";
export const renderMermaid = async (
export const render = async (
type: string,
payload: { uuid: string },
colour: string,
mermaidUUID: BlockUUID
plantumlUUID: BlockUUID
) => {
await logseq.Editor.editBlock(payload.uuid);
await logseq.Editor.exitEditingMode();
const mermaidBlock = await logseq.Editor.getBlock(mermaidUUID);
const matchData = mermaidBlock.content.match(/```mermaid(.|\n)*?```/gm);
const plantumlBlock = await logseq.Editor.getBlock(plantumlUUID);
const matchData = plantumlBlock.content.match(/```plantuml(.|\n)*?```/gm);
let toDecode = matchData[0];
@ -20,11 +20,11 @@ export const renderMermaid = async (
toDecode = toDecode.slice(0, 10) + initStr + toDecode.slice(10);
}
toDecode = toDecode.replace("```mermaid", "").replace("```", "");
toDecode = toDecode.replace("```plantuml", "").replace("```", "");
toDecode = toDecode.replace("\n", " ");
const jsonString = toBase64(toDecode, true);
const jsonString = compress(toDecode);
const renderBlock = async (str: string) => {
await logseq.Editor.updateBlock(
@ -35,66 +35,26 @@ export const renderMermaid = async (
};
const handleEvent = async () => {
const handlePort = () => {
const { port } = logseq.settings;
if (port) {
return `http://localhost:${port}`;
const handleUrl = () => {
const { server } = logseq.settings;
if (server) {
return server;
} else {
return `https://mermaid.ink`;
return `https://www.plantuml.com/plantuml`;
}
};
if (logseq.settings.config) {
const { colour } = logseq.settings.config;
// If mermaid config exists
if (colour.startsWith("#")) {
// If colour is a hexadecimal colour
renderBlock(
`<img src="${handlePort()}/img/${jsonString}?bgColor=${colour.substring(
1
)}" />`
);
} else if (!colour.startsWith("#")) {
// If colour is a plain colour description, e.g. blue
renderBlock(
`<img src="${handlePort()}/img/${jsonString}?bgColor=!${colour}" />`
);
} else {
// If error in config
renderBlock(`<img src="${handlePort()}/img/${jsonString}" />`);
}
} else if (colour) {
// If it is a local change of colour
if (colour.startsWith("#")) {
// If colour is a hexadecimal colour
renderBlock(
`<img src="${handlePort()}/img/${jsonString}?bgColor=${colour.substring(
1
)}" />`
);
} else if (!colour.startsWith("#")) {
// If colour is a plain colour description, e.g. blue
renderBlock(
`<img src="${handlePort()}/img/${jsonString}?bgColor=!${colour}" />`
);
} else {
// If error in config
renderBlock(`<img src="${handlePort()}/img/${jsonString}" />`);
}
} else {
// If mermaid config does not exist
renderBlock(`<img src="${handlePort()}/img/${jsonString}" />`);
}
renderBlock(`<img src="${handleUrl()}/png/${jsonString}" />`);
};
const handleError = () => {
renderBlock(
"<p>There is an error with your mermaid syntax. Please rectify and render again.</p>"
"<p>There is an error with your plantuml syntax. Please rectify and render again.</p>"
);
};
const image = new Image();
image.onload = handleEvent;
image.onerror = handleError;
image.src = `https://mermaid.ink/img/${jsonString}`;
image.src = `https://www.plantuml.com/plantuml/png/${jsonString}`;
};

1665
src/deflate.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
import "@logseq/libs";
import { callSettings } from "./callSettings";
import { renderMermaid } from "./convert";
import { render } from "./convert";
const uniqueIdentifier = () =>
Math.random()
@ -8,20 +8,20 @@ const uniqueIdentifier = () =>
.replace(/[^a-z]+/g, "");
const main = () => {
console.log("logseq-mermaid-plugin loaded");
console.log("logseq-plantuml-plugin loaded");
callSettings();
logseq.Editor.registerSlashCommand("Draw mermaid diagram", async () => {
logseq.Editor.registerSlashCommand("Draw plantuml diagram", async () => {
await logseq.Editor.insertAtEditingCursor(
`{{renderer :mermaid_${uniqueIdentifier()}}}`
`{{renderer :plantuml_${uniqueIdentifier()}}}`
);
const currBlock = await logseq.Editor.getCurrentBlock();
await logseq.Editor.insertBlock(
currBlock.uuid,
`\`\`\`mermaid
`\`\`\`plantuml
\`\`\``,
{
sibling: false,
@ -33,19 +33,19 @@ const main = () => {
logseq.App.onMacroRendererSlotted(async ({ slot, payload }) => {
const [type, colour] = payload.arguments;
const id = type.split("_")[1]?.trim();
const mermaidId = `mermaid_${id}`;
const plantumlId = `plantuml_${id}`;
if (!type.startsWith(":mermaid_")) return;
if (!type.startsWith(":plantuml_")) return;
const dataBlock = await logseq.Editor.getBlock(payload.uuid, {
includeChildren: true,
});
const mermaidUUID = dataBlock.children[0]["uuid"];
const plantumlUUID = dataBlock.children[0]["uuid"];
logseq.provideModel({
async show() {
renderMermaid(type, payload, colour, mermaidUUID);
render(type, payload, colour, plantumlUUID);
},
});
@ -66,7 +66,7 @@ const main = () => {
`);
logseq.provideUI({
key: `${mermaidId}`,
key: `${plantumlId}`,
slot,
reset: true,
template: `<button data-on-click="show" class="renderBtn">Render</button>`,

56
src/util.ts Normal file
View File

@ -0,0 +1,56 @@
import { deflate } from "./deflate.js"
// copy from plantuml site
function encode64(data) {
let r = "";
for (let i = 0; i < data.length; i += 3) {
if (i + 2 == data.length) {
r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), 0);
} else if (i + 1 == data.length) {
r += append3bytes(data.charCodeAt(i), 0, 0);
} else {
r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1),
data.charCodeAt(i + 2));
}
}
return r;
}
function append3bytes(b1, b2, b3) {
let c1 = b1 >> 2;
let c2 = ((b1 & 0x3) << 4) | (b2 >> 4);
let c3 = ((b2 & 0xF) << 2) | (b3 >> 6);
let c4 = b3 & 0x3F;
let r = "";
r += encode6bit(c1 & 0x3F);
r += encode6bit(c2 & 0x3F);
r += encode6bit(c3 & 0x3F);
r += encode6bit(c4 & 0x3F);
return r;
}
function encode6bit(b) {
if (b < 10) {
return String.fromCharCode(48 + b);
}
b -= 10;
if (b < 26) {
return String.fromCharCode(65 + b);
}
b -= 26;
if (b < 26) {
return String.fromCharCode(97 + b);
}
b -= 26;
if (b == 0) {
return '-';
}
if (b == 1) {
return '_';
}
return '?';
}
export const compress = (str: string) : string => {
const s = unescape(encodeURIComponent(str));
return encode64(deflate(s, 9));
}

1473
yarn.lock Normal file

File diff suppressed because it is too large Load Diff