-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial version of the plugin including unit tests and basic document…
…ation
- Loading branch information
Pierre Awaragi
committed
Jun 27, 2021
1 parent
452ed57
commit 2a99ba4
Showing
10 changed files
with
1,933 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,3 +102,7 @@ dist | |
|
||
# TernJS port file | ||
.tern-port | ||
|
||
# Project specific exclusions | ||
yarn.lock | ||
/.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
node_modules/ | ||
test/ | ||
.gitignore | ||
.npmignore | ||
jest.config.js | ||
yarn.lock | ||
yarn-error.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,55 @@ | ||
# eleventy-plugin-plantuml | ||
# eleventy-plugin-plantuml | ||
|
||
> Eleventy Plantuml plugin. Uses sync request to connect to a plantuml server to convert markddown code block of type | ||
> plantuml to an inline dataurl png ```<img>``` | ||
## Dependencies | ||
* [eleventy](https://www.npmjs.com/package/@11ty/eleventy) A simpler static site generator for which this plugin is make. | ||
* [sync-request](https://www.npmjs.com/package/sync-request) (for making blocking synchronous http request - not to be used in production) | ||
* [jest](https://www.npmjs.com/package/jest) (for executing unit tests) | ||
|
||
## Installation | ||
|
||
Add plugin to .eleventy.js configuration file and optionally provide a private Plantuml server | ||
```javascript | ||
eleventyConfig.addPlugin(plantuml, { | ||
hostname: "localhost", | ||
port: 8888, | ||
prefix: "" | ||
}); | ||
``` | ||
|
||
if options are omited, the plugin defaults to <http://plnntuml.com/plantuml> server for conversion. | ||
|
||
## Using in templates | ||
Simply create a markdown code block of type plantuml and it will be replaced by an img with inline png src (dataurl). | ||
|
||
>In the following example, there is an extra space between the ticks ` for escaping | ||
``` | ||
`` `plantuml | ||
@startuml | ||
!include https://raw.githubusercontent.com/bschwarz/puml-themes/master/themes/bluegray/puml-theme-bluegray.puml | ||
participant "Makrdown Highlighter" as MDH | ||
participant "eleventy-plugin-plantumt" as plugin | ||
participant "Plantuml Server" as plantuml | ||
MDH -> plugin : highlight | ||
plugin -> plugin: compress url | ||
plugin -> plantuml: GET /png/{url} | ||
plantuml -> plugin: image/png | ||
plugin -> plugin: base64 | ||
plugin -> MDH: img src="dataurl" | ||
@enduml | ||
`` ` | ||
``` | ||
|
||
## Contribute | ||
* create a fork of this repo | ||
* make your changes | ||
* test your code by running ```yarn test``` or ```npm test``` | ||
* create a Pull Request | ||
|
||
|
||
## Testing | ||
Execute ```yarn test``` or ```npm test``` to execute integration tests against <plantuml.com/plantuml> live server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('./lib/eleventy-plugin-plantuml'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module.exports = { | ||
"moduleFileExtensions": ["js", "json"], | ||
"rootDir": "./", | ||
"testMatch": ["<rootDir>/test/**/*.{spec,test}.js"], | ||
"testPathIgnorePatterns": ["<rootDir>/node_modules"], | ||
"testEnvironment": "node" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
const request = require('sync-request'); | ||
const plantumlEncode = require('./plantumlEncode'); | ||
|
||
const defaultOptions = { | ||
protocol: 'http', | ||
hostname: 'www.plantuml.com', | ||
port: "80", | ||
prefix: "/plantuml", | ||
outputType: "png", | ||
imgClass: "plantuml" | ||
}; | ||
|
||
function generatePlantumlUrl(encoded, options) { | ||
return `${options.protocol}://${options.hostname}${options.port === 80 ? "" : options.port === 443 ? "" : (":" + options.port)}${options.prefix}/${options.outputType}/${encoded}`; | ||
} | ||
|
||
const generateImageAsBase64String = (url, options) => { | ||
// request url | ||
const response = request('GET', url); | ||
// convert from Uint8Array to buffer to base64 string | ||
return Buffer.from(response.getBody()).toString('base64'); | ||
} | ||
|
||
const generateImgTag = (imageBase64, options) => { | ||
return `<img class="${options.imgClass}" src="data:image/png;base64,${imageBase64}" alt="Plantuml Diagram" />`; | ||
}; | ||
|
||
const highlight = (diagram, options) => { | ||
// compute compressed version of str | ||
const encoded = plantumlEncode(diagram); | ||
// URL to send to plantuml for conversion | ||
const url = generatePlantumlUrl(encoded, options); | ||
// Call plantuml server to generate image | ||
const imageBase64 = generateImageAsBase64String(url, options); | ||
// Finally convert image to dataurl | ||
return generateImgTag(imageBase64, options); | ||
}; | ||
|
||
const plugin = (eleventyConfig, pluginOptions = {}) => { | ||
// default options | ||
const options = Object.assign({}, defaultOptions, pluginOptions); | ||
|
||
// preserve chain of highlighter | ||
const highlighter = eleventyConfig.markdownHighlighter; | ||
|
||
// add highlighter | ||
eleventyConfig.addMarkdownHighlighter((diagram, language) => { | ||
if (language === "plantuml") { | ||
return highlight(diagram, options); | ||
} | ||
// just in case highlighter is not enabled in which case I am not sure why we are doing | ||
if (highlighter) { | ||
return highlighter(diagram, language) | ||
} | ||
// default highlighter just in case | ||
return `<pre class="${language}">${diagram}</a>`; | ||
}); | ||
return {} | ||
}; | ||
|
||
module.exports = { | ||
defaultOptions, | ||
plugin, | ||
highlight, | ||
|
||
generatePlantumlUrl, | ||
generateImageAsBase64String, | ||
generateImgTag | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Original: | ||
* https://github.com/johan/js-deflate | ||
*/ | ||
const { deflate } = require('./rawdeflate'); | ||
|
||
const 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; | ||
} | ||
|
||
const 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; | ||
} | ||
|
||
const 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 '?'; | ||
} | ||
const geturl = (s) => encode64(deflate(unescape(encodeURIComponent(s)), 9)); | ||
|
||
module.exports = geturl; |
Oops, something went wrong.