mirror of
https://github.com/ferrous-systems/embedded-trainings-2020.git
synced 2025-01-24 23:08:08 +00:00
Ensure marp can render slides.
We bundle markdown-it-kroki, which can add mermaid diagrams to marp slides using https://kroki.io.
This commit is contained in:
parent
04fc983107
commit
a4ee38540d
27 changed files with 1411 additions and 0 deletions
11
down-the-stack-book/README.md
Normal file
11
down-the-stack-book/README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Down the Stack Slides
|
||||
|
||||
To read as an mdbook:
|
||||
|
||||
1. `cargo install mdbook`
|
||||
2. `mdbook serve`
|
||||
|
||||
To read as a slide-show:
|
||||
|
||||
1. Download [marp-cli](https://github.com/marp-team/marp-cli/releases) and unpack into your `$PATH`
|
||||
2. `marp -c marp.config.js -I . -s`
|
6
down-the-stack-book/marp.config.js
Normal file
6
down-the-stack-book/marp.config.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
inputDir: './slides',
|
||||
engine: ({ marp }) => marp.use(require('@kazumatu981/markdown-it-kroki'), {
|
||||
entrypoint: "https://kroki.io",
|
||||
})
|
||||
}
|
13
down-the-stack-book/node_modules/.package-lock.json
generated
vendored
Normal file
13
down-the-stack-book/node_modules/.package-lock.json
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "down-the-stack-book",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/@kazumatu981/markdown-it-kroki": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@kazumatu981/markdown-it-kroki/-/markdown-it-kroki-1.1.1.tgz",
|
||||
"integrity": "sha512-LDYl+mV2WogLQ5r4olxovm+gphL/MNGfWZ1M1woBO/YhFnfwdn5EAUu9zF/KoVZzytJPq0RNfyeDtMkv+GJihg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
17
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/CHANGELOG.md
generated
vendored
Normal file
17
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
# CHANGELOG
|
||||
|
||||
## v1.1.1
|
||||
|
||||
* fix readme, see [this issue](https://github.com/kazumatu981/markdown-it-kroki/issues/1)
|
||||
|
||||
## v1.1.0
|
||||
|
||||
* Obsolated Option `marpAutoScaling` and detect automatically wether it is nessesury or not.
|
||||
|
||||
## v1.0.1
|
||||
|
||||
release on npm
|
||||
|
||||
## v1.0.0
|
||||
|
||||
create new
|
21
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/LICENSE
generated
vendored
Normal file
21
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 Kazuyoshi Matsumoto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
157
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/README.md
generated
vendored
Normal file
157
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/README.md
generated
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
# markdown-it-kroki
|
||||
|
||||
> This library was designed to embed [Kori.io](https://kroki.io/) diagram into [Marp](https://marp.app/) Slide-deks!!
|
||||
|
||||
|
||||
This library is a pugin for markdown-it to embed figure is created by textual syntax.
|
||||
To use this package, You can embed **Software Diagram** (like uml) is written by **code** in Marp Slides-deck.
|
||||
|
||||
See marp sample code.
|
||||
|
||||
## Sample
|
||||
|
||||
---
|
||||
marp: true
|
||||
---
|
||||
|
||||
|
||||
## plantuml
|
||||
|
||||
```plantuml[platuml image]
|
||||
@startuml
|
||||
left to right direction
|
||||
actor Guest as g
|
||||
package Professional {
|
||||
actor Chef as c
|
||||
actor "Food Critic" as fc
|
||||
}
|
||||
package Restaurant {
|
||||
usecase "Eat Food" as UC1
|
||||
usecase "Pay for Food" as UC2
|
||||
usecase "Drink" as UC3
|
||||
usecase "Review" as UC4
|
||||
}
|
||||
fc --> UC4
|
||||
g --> UC1
|
||||
g --> UC2
|
||||
g --> UC3
|
||||
@enduml
|
||||
```
|
||||
|
||||
![plantuml-sample](img/plantuml-sample.png)
|
||||
|
||||
If you want to write daigram, you write Diagram Language (like [plantuml](https://plantuml.com/), [mermaid.js](https://mermaid-js.github.io/mermaid/#/)) with in fenced code block.
|
||||
|
||||
## How to install
|
||||
|
||||
You can install `npm install` command like bellow.
|
||||
|
||||
```bash
|
||||
npm install -D @kazumatu981/markdown-it-kroki
|
||||
```
|
||||
|
||||
## How to use
|
||||
|
||||
Here is the how to use `markdow-it-kroki`.
|
||||
This section introduce how to create Marp slides-deck project,
|
||||
and introduce how to create Marp slides-deck server.
|
||||
|
||||
You can find deltail info in [here](https://marp.app/),
|
||||
and you can learn about marp plugin eco-system, [here](https://marpit.marp.app/usage?id=extend-marpit-by-plugins).
|
||||
|
||||
### **[1st step]** Create Slides-deck project
|
||||
|
||||
First, for create slides-deck, you have to prepair to **Marp Project** directory.
|
||||
So First, Create slides-deck project, and init npm package.
|
||||
|
||||
```bash
|
||||
mkdir myslides
|
||||
cd myslides
|
||||
|
||||
npm init -y
|
||||
```
|
||||
|
||||
Secondary, Build Marp Environment.
|
||||
Install [@marp-team/marp-cli](https://github.com/marp-team/marp-cli).
|
||||
|
||||
```bash
|
||||
npm install -D @marp-team/marp-cli
|
||||
```
|
||||
|
||||
> Off-course you can install as **global package** (like `npm install -g @marp-team/marp-cli`), or **run at-once** (like `npx`).
|
||||
|
||||
### **[2nd step]** Download this project and install
|
||||
|
||||
```bash
|
||||
git clone https://github.com/kazumatu981/markdown-it-kroki.git
|
||||
|
||||
cd myslides
|
||||
npm install -D path/to/markdown-it-kroki
|
||||
```
|
||||
|
||||
|
||||
### **[3rd step]** Create `marp.config.js`.
|
||||
|
||||
Here is the configuration file for **Marp**.
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
inputDir: './slides',
|
||||
engine: ({ marp }) => marp.use(require('@kazumatu981/markdown-it-kroki'), {
|
||||
entrypoint: "https://kroki.io",
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### **[4th step]** Create your slides
|
||||
|
||||
On `slies` directory. you create slides-deck. like this.
|
||||
|
||||
---
|
||||
marp: true
|
||||
---
|
||||
|
||||
|
||||
## mermaid
|
||||
|
||||
```mermaid[mermaid image]
|
||||
flowchart TD
|
||||
Start --> Stop
|
||||
```
|
||||
|
||||
### **[5th step]** run server
|
||||
|
||||
Run marp server.
|
||||
|
||||
```bash
|
||||
marp -s -c marp.config.js
|
||||
```
|
||||
|
||||
## Detail
|
||||
|
||||
### Syntax of Markdown
|
||||
|
||||
#### Diagram Language
|
||||
|
||||
You have to write diagram language by [fenced code block](https://spec.commonmark.org/0.30/#fenced-code-blocks) syntax, start with **triple back quot** and after that the language.
|
||||
|
||||
```plantuml
|
||||
|
||||
This package depends on kroki.io.
|
||||
If you want to know which is **supported diagram language**,
|
||||
you will see in [Kroki.io official web site (https://kroki.io/)](https://kroki.io/).
|
||||
|
||||
#### Alt Text
|
||||
|
||||
You can write Alt-text attribute to IMG tag in HTML.
|
||||
Write in `square blacket` after **Diagram Language**.
|
||||
|
||||
```mermaid [check your network config..]
|
||||
|
||||
### Options of `constructor`
|
||||
|
||||
| property-name | type | mean | defaul value |
|
||||
| ---------------- | -------- | ------------------------------------------------------ | ------------------------- |
|
||||
| `entrypoint` | `string` | The entry point for Kroki server. | `'https://kroki.io'` |
|
||||
| `containerClass` | `string` | class name of container (`DIV`-tag `class` attribute). | `'kroki-image-container'` |
|
||||
| `imageFormat` | `string` | image format of diagram. see [here](https://kroki.io/) | `'svg'` |
|
8
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/demo/marp.config.js
generated
vendored
Normal file
8
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/demo/marp.config.js
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
module.exports = {
|
||||
inputDir: './',
|
||||
engine: ({ marp }) => marp.use(require('../index'), {
|
||||
entrypoint: "https://kroki.io",
|
||||
marpAutoScaling: true
|
||||
})
|
||||
}
|
59
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/demo/test.md
generated
vendored
Normal file
59
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/demo/test.md
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
marp: true
|
||||
---
|
||||
|
||||
# @kazumatu981/markdown-it-kroki
|
||||
|
||||
## Marp Sample
|
||||
|
||||
---
|
||||
|
||||
## plantuml
|
||||
|
||||
```plantuml[platuml image]
|
||||
@startuml
|
||||
left to right direction
|
||||
actor Guest as g
|
||||
package Professional {
|
||||
actor Chef as c
|
||||
actor "Food Critic" as fc
|
||||
}
|
||||
package Restaurant {
|
||||
usecase "Eat Food" as UC1
|
||||
usecase "Pay for Food" as UC2
|
||||
usecase "Drink" as UC3
|
||||
usecase "Review" as UC4
|
||||
}
|
||||
fc --> UC4
|
||||
g --> UC1
|
||||
g --> UC2
|
||||
g --> UC3
|
||||
@enduml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## mermaid
|
||||
|
||||
```mermaid[mermaid image]
|
||||
graph TD
|
||||
A[ Anyone ] -->|Can help | B( Go to github.com/yuzutech/kroki )
|
||||
B --> C{ How to contribute? }
|
||||
C --> D[ Reporting bugs ]
|
||||
C --> E[ Sharing ideas ]
|
||||
C --> F[ Advocating ]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## normal code
|
||||
|
||||
```JavaScript
|
||||
function testFunc(test) {
|
||||
let sum = 0;
|
||||
for(let x = 1; x<=test; x++) {
|
||||
sum += x;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
```
|
BIN
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/img/plantuml-sample.png
generated
vendored
Normal file
BIN
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/img/plantuml-sample.png
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
6
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/index.js
generated
vendored
Normal file
6
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/index.js
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
const { MarkdownItKrokiCore } = require('./lib/plugin-core');
|
||||
|
||||
module.exports = (md, opt) => {
|
||||
const plugin = new MarkdownItKrokiCore(md);
|
||||
plugin.setOptions(opt).use();
|
||||
};
|
37
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/contract.js
generated
vendored
Normal file
37
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/contract.js
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* contract `test` to be non-empty string.
|
||||
* @param {string} test test string
|
||||
* @param {string} msg message on exception
|
||||
*/
|
||||
toNonEmptyString: function (test, msg) {
|
||||
if (typeof test !== 'string') throw new Error(msg);
|
||||
if (test === ''
|
||||
|| test === null
|
||||
|| test === undefined) throw new Error(msg);
|
||||
},
|
||||
/**
|
||||
* contract `test` to be true.
|
||||
* @param {boolean} test test boolean.
|
||||
* @param {sting} msg massage on excetion.
|
||||
*/
|
||||
toTrue: function (test, msg) {
|
||||
if (typeof test !== 'boolean') throw new Error(msg);
|
||||
if (!test) throw new Error(msg);
|
||||
},
|
||||
toBeUrlString: function (test, msg) {
|
||||
this.toNonEmptyString(test, msg);
|
||||
try {
|
||||
require('url').parse(test);
|
||||
} catch {
|
||||
throw new Error(msg);
|
||||
}
|
||||
},
|
||||
toBeClassName: function (test, msg) {
|
||||
if (!/^[A-Za-z0-9]+(-?[A-Za-z0-9]+)*$/.exec(test)) {
|
||||
throw new Error(msg);
|
||||
}
|
||||
}
|
||||
};
|
27
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/diagram-encoder.js
generated
vendored
Normal file
27
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/diagram-encoder.js
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
const { deflateSync } = require('zlib');
|
||||
const contract = require('./contract');
|
||||
const support = require('./support');
|
||||
|
||||
function encode(diagram) {
|
||||
return deflateSync(diagram, { level: 9 }).toString('base64url');
|
||||
}
|
||||
function generateUrl(entrypoint, lang, imgType, diagram) {
|
||||
|
||||
contract.toNonEmptyString(entrypoint, '\'entrypoint\' must be non-empty string.');
|
||||
contract.toNonEmptyString(lang, '\'lang\' must be non-empty string.');
|
||||
contract.toNonEmptyString(imgType, '\'imgType\' must be non-empty string.');
|
||||
contract.toNonEmptyString(diagram, '\'diagram\' must be non-empty string.');
|
||||
contract.toTrue(support.languageSupports(lang), 'Not Supported Diagram Language.');
|
||||
contract.toTrue(support.imageFormatSupports(imgType), 'Not Supported Image Type.');
|
||||
|
||||
const api = `${lang}/${imgType}/${encode(diagram)}`;
|
||||
|
||||
return entrypoint.endsWith('/') ?
|
||||
`${entrypoint}${api}` : `${entrypoint}/${api}`;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
encode, generateUrl
|
||||
};
|
52
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/obs/marp-it-kroki.js
generated
vendored
Normal file
52
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/obs/marp-it-kroki.js
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
const { deflateSync } = require('zlib')
|
||||
|
||||
const krokiLangs = [
|
||||
'actdiag',
|
||||
'blockdiag',
|
||||
'bpmn',
|
||||
'bytefield',
|
||||
'c4plantuml',
|
||||
'ditaa',
|
||||
'dot',
|
||||
'erd',
|
||||
'excalidraw',
|
||||
'graphviz',
|
||||
'mermaid',
|
||||
'nomnoml',
|
||||
'nwdiag',
|
||||
'packetdiag',
|
||||
'pikchr',
|
||||
'plantuml',
|
||||
'rackdiag',
|
||||
'seqdiag',
|
||||
'svgbob',
|
||||
'umlet',
|
||||
'vega',
|
||||
'vegalite',
|
||||
'wavedrom',
|
||||
]
|
||||
|
||||
const entrypoint = 'https://kroki.io/'
|
||||
|
||||
const marpKrokiPlugin = (md) => {
|
||||
const { fence } = md.renderer.rules
|
||||
|
||||
md.renderer.rules.fence = (tokens, idx, options, env, self) => {
|
||||
const info = md.utils.unescapeAll(tokens[idx].info).trim()
|
||||
|
||||
if (info) {
|
||||
const [lang] = info.split(/(\s+)/g)
|
||||
|
||||
if (krokiLangs.includes(lang)) {
|
||||
const data = deflateSync(tokens[idx].content).toString('base64url')
|
||||
|
||||
// <marp-auto-scaling> is working only with Marp Core v3
|
||||
return `<p><marp-auto-scaling data-downscale-only><img src="${entrypoint}${lang}/svg/${data}"/></marp-auto-scaling></p>`
|
||||
}
|
||||
}
|
||||
|
||||
return fence.call(self, tokens, idx, options, env, self)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = marpKrokiPlugin
|
74
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/plugin-core.js
generated
vendored
Normal file
74
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/plugin-core.js
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
'use strict';
|
||||
|
||||
const support = require('./support');
|
||||
const contract = require('./contract');
|
||||
const { safeProperty, safeChoice } = require('./safe-property');
|
||||
const diagramEncoder = require('./diagram-encoder');
|
||||
|
||||
class MarkdownItKrokiCore {
|
||||
constructor(md) {
|
||||
this._md = md;
|
||||
}
|
||||
setOptions(opt) {
|
||||
this._entrypoint = safeProperty(opt, "entrypoint", "string", 'https://kroki.io');
|
||||
this._containerClass = safeProperty(opt, "containerClass", "string", "kroki-image-container");
|
||||
this._imageFormat = safeProperty(opt, "imageFormat", "string", "svg");
|
||||
|
||||
this._imageFormat = safeChoice(this._imageFormat, support.imageFormats, "svg");
|
||||
this._entrypoint = require('url').parse(this._entrypoint).href;
|
||||
|
||||
contract.toBeClassName(this._containerClass, "containerClass must be className.");
|
||||
|
||||
return this;
|
||||
}
|
||||
use() {
|
||||
// if _md has `marpit` property then use <marp-auto-scaling> tag
|
||||
this._marpAutoScaling = this._md['marpit'] !== undefined;
|
||||
|
||||
this._defaultFence = this._md.renderer.rules.fence;
|
||||
this._md.renderer.rules.fence
|
||||
= (tokens, idx, options, env, self) => this.krokiFencePlugin(tokens, idx, options, env, self);
|
||||
}
|
||||
static readLanguageAndAltText(info) {
|
||||
if (!info) return { language: '', alt: '' };
|
||||
|
||||
const trimed = info.trim();
|
||||
const langFound = /[\s|\[]/.exec(trimed);
|
||||
const altFound = /\[.*?\]/.exec(trimed);
|
||||
|
||||
return {
|
||||
language: langFound ?
|
||||
trimed.substring(0, langFound.index) : trimed,
|
||||
alt: altFound ?
|
||||
altFound[0].replace('[', '').replace(']', '') : ''
|
||||
};
|
||||
}
|
||||
buildEmbedHTML(langAndAlt, diagramCode) {
|
||||
// alt build url
|
||||
const url = diagramEncoder.generateUrl(
|
||||
this._entrypoint, langAndAlt.language, this._imageFormat, diagramCode);
|
||||
|
||||
// sanitize alt
|
||||
const alt = langAndAlt.alt ?
|
||||
this._md.utils.escapeHtml(langAndAlt.alt) : undefined;
|
||||
// build img tag
|
||||
const imgTag = langAndAlt.alt ?
|
||||
`<img alt="${alt}" src="${url}" />` : `<img src="${url}" />`;
|
||||
// build container contents
|
||||
const containerContents = this._marpAutoScaling ?
|
||||
`<marp-auto-scaling data-downscale-only>${imgTag}</marp-auto-scaling>` : imgTag;
|
||||
// build embed HTML
|
||||
return `<p class="${this._containerClass}">${containerContents}</p>`;
|
||||
}
|
||||
krokiFencePlugin(tokens, idx, options, env, self) {
|
||||
const info = this._md.utils.unescapeAll(tokens[idx].info)
|
||||
const langAndAlt = MarkdownItKrokiCore.readLanguageAndAltText(info);
|
||||
|
||||
return support.languageSupports(langAndAlt.language) ?
|
||||
this.buildEmbedHTML(langAndAlt, tokens[idx].content) :
|
||||
this._defaultFence.call(self, tokens, idx, options, env, self);
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
MarkdownItKrokiCore
|
||||
}
|
18
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/safe-property.js
generated
vendored
Normal file
18
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/safe-property.js
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
function safeProperty(test, name, type, defaultValue) {
|
||||
if (test == null || test == undefined) return defaultValue;
|
||||
if (typeof test[name] !== type) return defaultValue;
|
||||
if (typeof test[name] === "string" && test[name] === '') return defaultValue;
|
||||
return test[name];
|
||||
}
|
||||
|
||||
function safeChoice(test, candidates, defaultValue) {
|
||||
return candidates.includes(test) ?
|
||||
test : defaultValue;
|
||||
}
|
||||
function safeUrl(test) {
|
||||
|
||||
}
|
||||
|
||||
module.exports = { safeProperty, safeChoice };
|
54
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/support.js
generated
vendored
Normal file
54
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/lib/support.js
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* Diagram Languages are supported by kroki.io
|
||||
*/
|
||||
const LANGUAGES = [
|
||||
'actdiag',
|
||||
'blockdiag',
|
||||
'bpmn',
|
||||
'bytefield',
|
||||
'c4plantuml',
|
||||
'ditaa',
|
||||
'dot',
|
||||
'erd',
|
||||
'excalidraw',
|
||||
'graphviz',
|
||||
'mermaid',
|
||||
'nomnoml',
|
||||
'nwdiag',
|
||||
'packetdiag',
|
||||
'pikchr',
|
||||
'plantuml',
|
||||
'rackdiag',
|
||||
'seqdiag',
|
||||
'svgbob',
|
||||
'umlet',
|
||||
'vega',
|
||||
'vegalite',
|
||||
'wavedrom',
|
||||
];
|
||||
|
||||
/**
|
||||
* Image formats are supported by kroki.io
|
||||
*/
|
||||
const IMG_FORMATS = [
|
||||
'png', 'svg', 'jpeg', 'pdf', 'base64'
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
lnaguages: LANGUAGES,
|
||||
imageFormats: IMG_FORMATS,
|
||||
/**
|
||||
* test whether `lang` is supported diagram language by kroki.io
|
||||
* @param {string} lang target language
|
||||
* @returns is supported
|
||||
*/
|
||||
languageSupports: (lang) => LANGUAGES.includes(lang),
|
||||
/**
|
||||
* test whether `format` is supported image format by kroki.io
|
||||
* @param {string} format name of image format like 'png', 'svg', ... etc
|
||||
* @returns is supported
|
||||
*/
|
||||
imageFormatSupports: (format) => IMG_FORMATS.includes(format)
|
||||
};
|
35
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/package.json
generated
vendored
Normal file
35
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/package.json
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "@kazumatu981/markdown-it-kroki",
|
||||
"version": "1.1.1",
|
||||
"description": "markdown-it kroki plugin.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "mocha tests/**/*.test.js",
|
||||
"demo": "marp -s -c demo/marp.config.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/kazumatu981/markdown-it-kroki.git"
|
||||
},
|
||||
"keywords": [
|
||||
"markdown-it",
|
||||
"markdown-it-plugin",
|
||||
"kroki",
|
||||
"marp",
|
||||
"markdown"
|
||||
],
|
||||
"author": "kazumatu981",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/kazumatu981/markdown-it-kroki/issues"
|
||||
},
|
||||
"homepage": "https://github.com/kazumatu981/markdown-it-kroki#readme",
|
||||
"devDependencies": {
|
||||
"@marp-team/marp-cli": "^2.2.0",
|
||||
"chai": "^4.3.6",
|
||||
"jsdom": "^20.0.1",
|
||||
"markdown-it": "^13.0.1",
|
||||
"mocha": "^10.1.0",
|
||||
"nyc": "^15.1.0"
|
||||
}
|
||||
}
|
94
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/securitytest/security.test.js
generated
vendored
Normal file
94
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/securitytest/security.test.js
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
const MarkdownIt = require('markdown-it');
|
||||
const { expect } = require('chai');
|
||||
const { JSDOM } = require('jsdom');
|
||||
const MarkdownItKroki = require('../../index');
|
||||
|
||||
describe('# [Security-test] anti-injecttion for syntax.', () => {
|
||||
describe("## for alt", () => {
|
||||
it('* escape double quote', () => {
|
||||
const expected = 'this is a "test comment" test';
|
||||
|
||||
const md = new MarkdownIt();
|
||||
md.use(MarkdownItKroki, {
|
||||
entrypoint: "https://kroki.io",
|
||||
marpAutoScaling: true,
|
||||
containerClass: "the-container"
|
||||
});
|
||||
|
||||
const result = md.render(
|
||||
'```graphviz [this is a "test comment" test]\r\n' +
|
||||
'digraph G {Hello->World}\r\n' +
|
||||
'```\r\n'
|
||||
);
|
||||
const dom = new JSDOM(result);
|
||||
const imgTag = dom.window.document.getElementsByTagName("img")[0];
|
||||
const actual = imgTag.getAttribute('alt');
|
||||
|
||||
expect(actual).to.be.equal(expected);
|
||||
})
|
||||
})
|
||||
});
|
||||
describe('# [Security-test] anti-injecttion for option.', () => {
|
||||
describe("## for entrypoint", () => {
|
||||
it('* deny invalid URL', () => {
|
||||
const md = new MarkdownIt();
|
||||
md.use(MarkdownItKroki, {
|
||||
entrypoint: "https://kroki.io\"> <script src=\"xxxx.js",
|
||||
marpAutoScaling: true,
|
||||
containerClass: "the-container"
|
||||
});
|
||||
|
||||
const html = md.render(
|
||||
'```graphviz [this is a test]\r\n' +
|
||||
'digraph G {Hello->World}\r\n' +
|
||||
'```\r\n'
|
||||
);
|
||||
const dom = new JSDOM(html);
|
||||
const scriptTag = dom.window.document.getElementsByTagName("script");
|
||||
expect(scriptTag.length).to.equal(0);
|
||||
})
|
||||
})
|
||||
describe("## for containerClass", () => {
|
||||
|
||||
it('* throw when containerClass are not alpha, digit, or \"-\"', () => {
|
||||
const testFunction = () => {
|
||||
const md = new MarkdownIt();
|
||||
md.use(MarkdownItKroki, {
|
||||
entrypoint: "https://kroki.io",
|
||||
marpAutoScaling: true,
|
||||
containerClass: "<container>"
|
||||
});
|
||||
|
||||
const result = md.render(
|
||||
'```graphviz [this is a test]\r\n' +
|
||||
'digraph G {Hello->World}\r\n' +
|
||||
'```\r\n'
|
||||
);
|
||||
};
|
||||
expect(testFunction).to.throw();
|
||||
|
||||
})
|
||||
})
|
||||
describe("## for imageFormat", () => {
|
||||
it('* ignore invalid imageFormat', () => {
|
||||
const md = new MarkdownIt();
|
||||
md.use(MarkdownItKroki, {
|
||||
entrypoint: "https://kroki.io",
|
||||
marpAutoScaling: true,
|
||||
containerClass: "the-container",
|
||||
imageFormat: "<injected>"
|
||||
});
|
||||
|
||||
const html = md.render(
|
||||
'```graphviz [this is a test]\r\n' +
|
||||
'digraph G {Hello->World}\r\n' +
|
||||
'```\r\n'
|
||||
);
|
||||
const dom = new JSDOM(html);
|
||||
const imgTag = dom.window.document.getElementsByTagName("img")[0];
|
||||
const actual = imgTag.getAttribute('src');
|
||||
|
||||
expect(actual).to.includes('/svg/');
|
||||
})
|
||||
})
|
||||
});
|
96
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/totaltest/canrender.test.js
generated
vendored
Normal file
96
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/totaltest/canrender.test.js
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
const { expect } = require('chai');
|
||||
const MarkdownIt = require('markdown-it');
|
||||
const MarkdownItKroki = require('../../index');
|
||||
const { JSDOM } = require('jsdom');
|
||||
|
||||
const testData = [
|
||||
// graphviz
|
||||
{
|
||||
langname: 'graphviz',
|
||||
data: '```graphviz svg\r\n' +
|
||||
'digraph G {Hello->World}\r\n' +
|
||||
'```\r\n'
|
||||
}
|
||||
];
|
||||
|
||||
describe('# [total test] Test pulugin can Render DOM', () => {
|
||||
for (const test of testData) {
|
||||
describe(`## Test for ${test.langname}`, () => {
|
||||
describe('### no option call test', () => {
|
||||
it('* Not to Throw on no options', () => {
|
||||
const testFunction = () => {
|
||||
// render !
|
||||
const md = new MarkdownIt();
|
||||
md.use(MarkdownItKroki);
|
||||
const _ = md.render(test.data);
|
||||
};
|
||||
expect(testFunction).to.not.throw();
|
||||
});
|
||||
it('* root DOM item is \'p\' on no option', () => {
|
||||
// render !
|
||||
const md = new MarkdownIt();
|
||||
md.use(MarkdownItKroki);
|
||||
const result = md.render(test.data);
|
||||
|
||||
// find p-tag
|
||||
const dom = new JSDOM(result);
|
||||
const document = dom.window.document;
|
||||
const ptags = document.getElementsByTagName("p");
|
||||
|
||||
// test p-tag is only one
|
||||
expect(ptags.length).to.be.equal(1);
|
||||
|
||||
// test root item is p
|
||||
const thePtag = ptags[0];
|
||||
expect(thePtag.isSameNode(document.body.firstChild)).to.true;
|
||||
|
||||
// test embeded default container class
|
||||
expect(thePtag.getAttribute('class')).to.be.equal('kroki-image-container');
|
||||
});
|
||||
it('* has img tag and source is created by this library.', () => {
|
||||
// render !
|
||||
const md = new MarkdownIt();
|
||||
md.use(MarkdownItKroki);
|
||||
const result = md.render(test.data);
|
||||
|
||||
// find p-tag
|
||||
const dom = new JSDOM(result);
|
||||
const document = dom.window.document;
|
||||
const imgTags = document.getElementsByTagName("img");
|
||||
|
||||
// test img-tag is only one
|
||||
expect(imgTags.length).to.be.equal(1);
|
||||
|
||||
const imgTag = imgTags[0];
|
||||
expect(imgTag.getAttribute('src')).not.to.empty;
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
})
|
||||
describe('[total test] Can Render', () => {
|
||||
it('* option constainerClass is embeded.', () => {
|
||||
const md = new MarkdownIt();
|
||||
|
||||
md.use(MarkdownItKroki, {
|
||||
entrypoint: "https://kroki.io",
|
||||
marpAutoScaling: true,
|
||||
containerClass: "the-container"
|
||||
});
|
||||
|
||||
var result = md.render(
|
||||
'```graphviz [praphviz-image]\r\n' +
|
||||
'digraph G {Hello->World}\r\n' +
|
||||
'```\r\n'
|
||||
);
|
||||
const dom = new JSDOM(result);
|
||||
const document = dom.window.document;
|
||||
const ptags = document.getElementsByTagName("p");
|
||||
|
||||
expect(ptags.length).to.be.equal(1);
|
||||
const thePtag = ptags[0];
|
||||
|
||||
expect(thePtag.isSameNode(document.body.firstChild)).to.true;
|
||||
expect(thePtag.getAttribute('class')).to.be.equal('the-container');
|
||||
});
|
||||
});
|
35
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/conract.test.js
generated
vendored
Normal file
35
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/conract.test.js
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
const expect = require('chai').expect;
|
||||
const contract = require('../../lib/contract');
|
||||
|
||||
describe('# [unit test]: contract.js', () => {
|
||||
describe('## toNonEmptyString()', () => {
|
||||
['abc', ' ', ' abc '].forEach((test) => {
|
||||
it(`* normal cases. { testcase: ${test} }`, () => {
|
||||
expect(() => {
|
||||
contract.toNonEmptyString(test);
|
||||
}).not.to.throw();
|
||||
})
|
||||
});
|
||||
['', null, undefined, 123, 0.123, true, { test: 123 }].forEach((test) => {
|
||||
it(`* abnormal cases. { testcase: ${test} }`, () => {
|
||||
expect(() => {
|
||||
contract.toNonEmptyString(test);
|
||||
}).to.throw();
|
||||
})
|
||||
});
|
||||
});
|
||||
describe('## toTrue', () => {
|
||||
it('* normal case. {test case: true}', () => {
|
||||
expect(() => {
|
||||
contract.toTrue(true);
|
||||
}).not.to.throw();
|
||||
});
|
||||
['', null, undefined, 123, 0.123, false, { test: 123 }].forEach((test) => {
|
||||
it(`* abnormal cases. { testcase: ${test} }`, () => {
|
||||
expect(() => {
|
||||
contract.toTrue(test);
|
||||
}).to.throw();
|
||||
})
|
||||
});
|
||||
});
|
||||
})
|
75
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/diagram-encoder.test.js
generated
vendored
Normal file
75
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/diagram-encoder.test.js
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
const expect = require('chai').expect;
|
||||
const { inflateSync } = require('zlib');
|
||||
|
||||
const { encode, generateUrl } = require('../../lib/diagram-encoder');
|
||||
|
||||
describe('# [unit-test]: diagram-encoder.js', () => {
|
||||
describe('## [function]: encode()', () => {
|
||||
it('* encoded data is able to decode.', () => {
|
||||
const testFunc = () => {
|
||||
const expected = '@startuml\nBob -> Alice : hello\n@enduml';
|
||||
|
||||
const encoded = encode(expected);
|
||||
const deflated = Buffer.from(encoded, "base64url");
|
||||
const actual = inflateSync(deflated).toString();
|
||||
|
||||
expect(actual).to.be.equal(expected);
|
||||
}
|
||||
expect(testFunc).not.to.Throw();
|
||||
});
|
||||
});
|
||||
describe('## [function]: generateUrl()', () => {
|
||||
it('* must start format like <entry-point>/<lang>/<format>/', () => {
|
||||
const actual = generateUrl('https://kroki.io', 'graphviz', 'svg', 'digraph G {Hello->World}');
|
||||
const expected = 'https://kroki.io/graphviz/svg/';
|
||||
|
||||
expect(actual).to.be.a('string');
|
||||
expect(actual.startsWith(expected)).to.be.true;
|
||||
});
|
||||
it('* must endwith <encoded>', () => {
|
||||
const actual = generateUrl('https://kroki.io', 'graphviz', 'svg', 'digraph G {Hello->World}');
|
||||
const expected = encode('digraph G {Hello->World}');
|
||||
|
||||
expect(actual).to.be.a('string');
|
||||
expect(actual.endsWith(expected)).to.be.true;
|
||||
});
|
||||
[1, '', null, undefined].forEach(test => {
|
||||
it(`* [exception] throws when entry-point is, non-string object, empty string, null or undefined. Test: ${test}`, () => {
|
||||
const testFunction = () => {
|
||||
let _ = generateUrl(test, 'graphviz', 'svg', 'digraph G {Hello->World}');
|
||||
}
|
||||
expect(testFunction).throw();
|
||||
});
|
||||
it(`* [exception] throws when lang is, non-string object, empty string, null or undefined. Test: ${test}`, () => {
|
||||
const testFunction = () => {
|
||||
let _ = generateUrl('https://kroki.io', test, 'svg', 'digraph G {Hello->World}');
|
||||
}
|
||||
expect(testFunction).throw();
|
||||
});
|
||||
it(`* [exception] throws when imgType is, non-string object, empty string, null or undefined. Test: ${test}`, () => {
|
||||
const testFunction = () => {
|
||||
let _ = generateUrl('https://kroki.io', 'graphviz', test, 'digraph G {Hello->World}');
|
||||
}
|
||||
expect(testFunction).throw();
|
||||
});
|
||||
it(`* [exception] throws when diagram is, non-string object, empty string, null or undefined. Test: ${test}`, () => {
|
||||
const testFunction = () => {
|
||||
let _ = generateUrl('https://kroki.io', 'graphviz', 'svg', diagram);
|
||||
}
|
||||
expect(testFunction).throw();
|
||||
});
|
||||
});
|
||||
it('* [exception] throws when lang is unsupported lang', () => {
|
||||
const testFunction = () => {
|
||||
let _ = generateUrl('https://kroki.io', 'graphviz123', 'svg', 'digraph G {Hello->World}');
|
||||
}
|
||||
expect(testFunction).throw();
|
||||
});
|
||||
it('* [exception] throws when imgType is unsupported imgType', () => {
|
||||
const testFunction = () => {
|
||||
let _ = generateUrl('https://kroki.io', 'graphviz', 'svg123', 'digraph G {Hello->World}');
|
||||
}
|
||||
expect(testFunction).throw();
|
||||
});
|
||||
});
|
||||
});
|
146
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/plugin-core.buuildEmbedHTML.test.js
generated
vendored
Normal file
146
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/plugin-core.buuildEmbedHTML.test.js
generated
vendored
Normal file
|
@ -0,0 +1,146 @@
|
|||
const md = require('markdown-it');
|
||||
const expect = require('chai').expect;
|
||||
const { JSDOM } = require('jsdom');
|
||||
const { MarkdownItKrokiCore } = require('../../lib/plugin-core');
|
||||
const { encode } = require('../../lib/diagram-encoder');
|
||||
|
||||
describe('# [unit-test] plugin-core.js', () => {
|
||||
describe('## method: buuildEmbedHTML', () => {
|
||||
describe('### langAndAlt.language', () => {
|
||||
[null, undefined, ''].forEach((test) => {
|
||||
it(`* when langAndAlt.language is null or empty, throws error. testcase:${test}`, () => {
|
||||
const diagramCode = '@startuml\nBob -> Alice : hello\n @enduml';
|
||||
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
|
||||
const testFunc = () => {
|
||||
plugin.use();
|
||||
const _ = plugin.buildEmbedHTML(
|
||||
{ language: test, alt: '' }, diagramCode);
|
||||
};
|
||||
expect(testFunc).to.throw();
|
||||
});
|
||||
});
|
||||
it('* language embeded in to url', () => {
|
||||
const test = 'plantuml';
|
||||
|
||||
const diagramCode = '@startuml\nBob -> Alice : hello\n @enduml';
|
||||
|
||||
// build embed HTML
|
||||
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
|
||||
plugin.use();
|
||||
const html = plugin.buildEmbedHTML({ language: test, alt: '' }, diagramCode);
|
||||
|
||||
// parse dom
|
||||
const dom = new JSDOM(html);
|
||||
const imgTag = dom.window.document.getElementsByTagName("img")[0];
|
||||
|
||||
// get url attribute
|
||||
const url = imgTag.getAttribute('src');
|
||||
|
||||
expect(/\/plantuml\//.test(url)).to.true;
|
||||
});
|
||||
});
|
||||
describe('### langAndAlt.alt', () => {
|
||||
[null, undefined, ''].forEach((test) => {
|
||||
it(`* when langAndAlt.alt is null or empty, no alt attribute. testcase:${test}`, () => {
|
||||
const diagramCode = '@startuml\nBob -> Alice : hello\n @enduml';
|
||||
|
||||
// prepair
|
||||
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
|
||||
plugin.use();
|
||||
|
||||
// render
|
||||
const html = plugin.buildEmbedHTML(
|
||||
{ language: 'plantuml', alt: test }, diagramCode);
|
||||
// parse dom
|
||||
const dom = new JSDOM(html);
|
||||
const imgTag = dom.window.document.getElementsByTagName("img")[0];
|
||||
|
||||
expect(imgTag.hasAttribute('alt')).to.false;
|
||||
});
|
||||
});
|
||||
it('* embeded altText', () => {
|
||||
const expected = "this is test Text";
|
||||
const diagramCode = '@startuml\nBob -> Alice : hello\n @enduml';
|
||||
|
||||
// prepair
|
||||
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
|
||||
plugin.use();
|
||||
|
||||
// render
|
||||
const html = plugin.buildEmbedHTML(
|
||||
{ language: 'plantuml', alt: expected }, diagramCode);
|
||||
// parse dom
|
||||
const dom = new JSDOM(html);
|
||||
const imgTag = dom.window.document.getElementsByTagName("img")[0];
|
||||
|
||||
expect(imgTag.getAttribute('alt')).to.equal(expected);
|
||||
|
||||
});
|
||||
});
|
||||
describe('### diagramCode', () => {
|
||||
[null, undefined, ''].forEach((test) => {
|
||||
it(`* when diagramCode is null or empty, throws error. testcase:${test}`, () => {
|
||||
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
|
||||
const testFunc = () => {
|
||||
plugin.use();
|
||||
const _ = plugin.buildEmbedHTML(
|
||||
{ language: 'plantuml', alt: '' }, test);
|
||||
};
|
||||
expect(testFunc).to.throw();
|
||||
});
|
||||
});
|
||||
it('* encoded diagram must be embed to url on <img src=\'....\' ', () => {
|
||||
const test = '@startuml\nBob -> Alice : hello\n @enduml';
|
||||
|
||||
const expected = encode(test);
|
||||
|
||||
// build embed HTML
|
||||
const plugin = new MarkdownItKrokiCore(new md()).setOptions();
|
||||
plugin.use();
|
||||
const html = plugin.buildEmbedHTML({ language: 'plantuml', alt: '' }, test);
|
||||
|
||||
// parse dom
|
||||
const dom = new JSDOM(html);
|
||||
const imgTag = dom.window.document.getElementsByTagName("img")[0];
|
||||
|
||||
// get url attribute
|
||||
const url = imgTag.getAttribute('src');
|
||||
|
||||
expect(url.endsWith(expected)).to.true;
|
||||
});
|
||||
it('* <img> is surounded by <marp-auto-scaling> on to be used form marp-it', () => {
|
||||
const test = '@startuml\nBob -> Alice : hello\n @enduml';
|
||||
|
||||
const markdownIt = new md()
|
||||
markdownIt['marpit'] = { someObject: 'is implemented' };
|
||||
// build embed HTML
|
||||
const plugin = new MarkdownItKrokiCore(markdownIt).setOptions();
|
||||
plugin.use();
|
||||
const html = plugin.buildEmbedHTML({ language: 'plantuml', alt: '' }, test);
|
||||
|
||||
// parse dom
|
||||
const dom = new JSDOM(html);
|
||||
const imgTag = dom.window.document.getElementsByTagName("img")[0];
|
||||
const marpAutoScaling = dom.window.document.getElementsByTagName("marp-auto-scaling")[0];
|
||||
|
||||
expect(imgTag.isSameNode(marpAutoScaling.firstChild)).to.be.true;
|
||||
});
|
||||
it('* <img> is surounded by <marp-auto-scaling> on not to be used form marp-it', () => {
|
||||
const test = '@startuml\nBob -> Alice : hello\n @enduml';
|
||||
|
||||
const markdownIt = new md()
|
||||
// build embed HTML
|
||||
const plugin = new MarkdownItKrokiCore(markdownIt).setOptions();
|
||||
plugin.use();
|
||||
const html = plugin.buildEmbedHTML({ language: 'plantuml', alt: '' }, test);
|
||||
|
||||
// parse dom
|
||||
const dom = new JSDOM(html);
|
||||
const marpAutoScaling = dom.window.document.getElementsByTagName("marp-auto-scaling");
|
||||
|
||||
expect(marpAutoScaling.length).to.equal(0);
|
||||
})
|
||||
|
||||
});
|
||||
});
|
||||
});
|
178
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/plugin-core.setOptions.test.js
generated
vendored
Normal file
178
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/plugin-core.setOptions.test.js
generated
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
const md = require('markdown-it');
|
||||
const expect = require('chai').expect;
|
||||
const { JSDOM } = require('jsdom');
|
||||
const { MarkdownItKrokiCore } = require('../../lib/plugin-core');
|
||||
|
||||
describe('# [unit-test] plugin-core.js', () => {
|
||||
describe('## method: setOptions() must be work', () => {
|
||||
function buildHtmlForTest(options) {
|
||||
const test = 'plantuml';
|
||||
|
||||
const diagramCode = '@startuml\nBob -> Alice : hello\n @enduml';
|
||||
|
||||
// build embed HTML
|
||||
const plugin = new MarkdownItKrokiCore(new md()).setOptions(options);
|
||||
plugin.use();
|
||||
return plugin.buildEmbedHTML({ language: test }, diagramCode);
|
||||
}
|
||||
describe('### entrypoint', () => {
|
||||
function expectEntryPointToEmbed(htmlString, expected) {
|
||||
if (!expected) expected = 'https://kroki.io';
|
||||
// parse dom
|
||||
const dom = new JSDOM(htmlString);
|
||||
const imgTag = dom.window.document.getElementsByTagName("img")[0];
|
||||
|
||||
// get url attribute
|
||||
const url = imgTag.getAttribute('src');
|
||||
|
||||
expect(url.startsWith(expected)).to.true;
|
||||
}
|
||||
it('* no options', () => {
|
||||
const html = buildHtmlForTest();
|
||||
expectEntryPointToEmbed(html);
|
||||
});
|
||||
it('* option is null', () => {
|
||||
const html = buildHtmlForTest({ entrypoint: null });
|
||||
expectEntryPointToEmbed(html);
|
||||
});
|
||||
it('* option is undefined', () => {
|
||||
const html = buildHtmlForTest({ entrypoint: undefined });
|
||||
expectEntryPointToEmbed(html);
|
||||
});
|
||||
it('* option is \'\'', () => {
|
||||
const html = buildHtmlForTest({ entrypoint: '' });
|
||||
expectEntryPointToEmbed(html);
|
||||
});
|
||||
it('* option is 1', () => {
|
||||
const html = buildHtmlForTest({ entrypoint: 1 });
|
||||
expectEntryPointToEmbed(html);
|
||||
});
|
||||
it('* option is true', () => {
|
||||
const html = buildHtmlForTest({ entrypoint: true });
|
||||
expectEntryPointToEmbed(html);
|
||||
});
|
||||
it('* option is \'https://localhost:8080\'', () => {
|
||||
const html = buildHtmlForTest({
|
||||
entrypoint: 'https://localhost:8080'
|
||||
});
|
||||
expectEntryPointToEmbed(html, 'https://localhost:8080');
|
||||
});
|
||||
});
|
||||
describe.skip('### marpAutoScaling', () => {
|
||||
function expectMarpAutoScalingToEmbed(htmlString, expected) {
|
||||
// parse dom
|
||||
const dom = new JSDOM(htmlString);
|
||||
const tags = dom.window.document.getElementsByTagName("marp-auto-scaling");
|
||||
if (expected) {
|
||||
expect(tags).not.to.empty;
|
||||
} else {
|
||||
expect(tags).to.empty;
|
||||
}
|
||||
|
||||
}
|
||||
it('* no options', () => {
|
||||
const html = buildHtmlForTest();
|
||||
expectMarpAutoScalingToEmbed(html, true);
|
||||
});
|
||||
it('* option is null', () => {
|
||||
const html = buildHtmlForTest({ marpAutoScaling: null });
|
||||
expectMarpAutoScalingToEmbed(html, true);
|
||||
});
|
||||
it('* option is undefined', () => {
|
||||
const html = buildHtmlForTest({ marpAutoScaling: undefined });
|
||||
expectMarpAutoScalingToEmbed(html, true);
|
||||
});
|
||||
it('* option is \'\'', () => {
|
||||
const html = buildHtmlForTest({ marpAutoScaling: '' });
|
||||
expectMarpAutoScalingToEmbed(html, true);
|
||||
});
|
||||
it('* option is 1', () => {
|
||||
const html = buildHtmlForTest({ marpAutoScaling: 1 });
|
||||
expectMarpAutoScalingToEmbed(html, true);
|
||||
});
|
||||
it('* option is \'test\'', () => {
|
||||
const html = buildHtmlForTest({ marpAutoScaling: 'test' });
|
||||
expectMarpAutoScalingToEmbed(html, true);
|
||||
});
|
||||
it('* option is false', () => {
|
||||
const html = buildHtmlForTest({ marpAutoScaling: false });
|
||||
expectMarpAutoScalingToEmbed(html, false);
|
||||
});
|
||||
})
|
||||
describe('### containerClass', () => {
|
||||
function expectContainerClassToEmbed(htmlString, className) {
|
||||
// parse dom
|
||||
const dom = new JSDOM(htmlString);
|
||||
const pTag = dom.window.document.getElementsByTagName("p")[0];
|
||||
|
||||
const actualClassName = pTag.getAttribute('class');
|
||||
expect(actualClassName).to.equal(className);
|
||||
}
|
||||
it('* no options', () => {
|
||||
const html = buildHtmlForTest();
|
||||
expectContainerClassToEmbed(html, 'kroki-image-container');
|
||||
});
|
||||
it('* option is null', () => {
|
||||
const html = buildHtmlForTest({ containerClass: null });
|
||||
expectContainerClassToEmbed(html, 'kroki-image-container');
|
||||
});
|
||||
it('* option is undefined', () => {
|
||||
const html = buildHtmlForTest({ containerClass: undefined });
|
||||
expectContainerClassToEmbed(html, 'kroki-image-container');
|
||||
});
|
||||
it('* option is \'\'', () => {
|
||||
const html = buildHtmlForTest({ containerClass: '' });
|
||||
expectContainerClassToEmbed(html, 'kroki-image-container');
|
||||
});
|
||||
it('* option is 1', () => {
|
||||
const html = buildHtmlForTest({ containerClass: 1 });
|
||||
expectContainerClassToEmbed(html, 'kroki-image-container');
|
||||
});
|
||||
it('* option is \'containerClass\'', () => {
|
||||
const html = buildHtmlForTest({ containerClass: 'containerClass' });
|
||||
expectContainerClassToEmbed(html, 'containerClass');
|
||||
});
|
||||
});
|
||||
describe('### imageFormat', () => {
|
||||
function expectImageFormatToEmbed(htmlString, expected) {
|
||||
// parse dom
|
||||
const dom = new JSDOM(htmlString);
|
||||
const imgTag = dom.window.document.getElementsByTagName("img")[0];
|
||||
|
||||
// get url attribute
|
||||
const url = imgTag.getAttribute('src');
|
||||
|
||||
expect(url).to.includes('/' + expected + '/');
|
||||
}
|
||||
it('* no options', () => {
|
||||
const html = buildHtmlForTest();
|
||||
expectImageFormatToEmbed(html, 'svg');
|
||||
});
|
||||
it('* option is null', () => {
|
||||
const html = buildHtmlForTest({ imageFormat: null });
|
||||
expectImageFormatToEmbed(html, 'svg');
|
||||
});
|
||||
it('* option is undefined', () => {
|
||||
const html = buildHtmlForTest({ imageFormat: undefined });
|
||||
expectImageFormatToEmbed(html, 'svg');
|
||||
});
|
||||
it('* option is \'\'', () => {
|
||||
const html = buildHtmlForTest({ imageFormat: '' });
|
||||
expectImageFormatToEmbed(html, 'svg');
|
||||
});
|
||||
it('* option is 1', () => {
|
||||
const html = buildHtmlForTest({ imageFormat: 1 });
|
||||
expectImageFormatToEmbed(html, 'svg');
|
||||
|
||||
});
|
||||
it('* option is \'test\'', () => {
|
||||
const html = buildHtmlForTest({ imageFormat: 'test' });
|
||||
expectImageFormatToEmbed(html, 'svg');
|
||||
});
|
||||
it('* option is \'png\'', () => {
|
||||
const html = buildHtmlForTest({ imageFormat: 'png' });
|
||||
expectImageFormatToEmbed(html, 'png');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
49
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/plugin-core.static-methods.test.js
generated
vendored
Normal file
49
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/plugin-core.static-methods.test.js
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
const expect = require('chai').expect;
|
||||
const { MarkdownItKrokiCore } = require('../../lib/plugin-core');
|
||||
|
||||
describe('# [unit-test] plugin-core.js', () => {
|
||||
describe('## static method: readLanguageAndAltText() - language', () => {
|
||||
[
|
||||
{ test: null, expected: '' },
|
||||
{ test: undefined, expected: '' },
|
||||
{ test: '', expected: '' },
|
||||
{ test: ' ', expected: '' },
|
||||
{ test: 'plantuml', expected: 'plantuml' },
|
||||
{ test: ' plantuml', expected: 'plantuml' },
|
||||
{ test: 'plantuml ', expected: 'plantuml' },
|
||||
{ test: 'plantuml +++', expected: 'plantuml' },
|
||||
{ test: 'html+md', expected: 'html+md' },
|
||||
{ test: 'graphviz[]', expected: 'graphviz' },
|
||||
{ test: 'graphviz[test]', expected: 'graphviz' },
|
||||
{ test: 'graphviz [test test]', expected: 'graphviz' },
|
||||
].forEach(testCase => {
|
||||
it(`### Can read diagramLanguage. in case \'${testCase.test}\'`, () => {
|
||||
const actual = MarkdownItKrokiCore.readLanguageAndAltText(testCase.test);
|
||||
const expected = testCase.expected;
|
||||
expect(actual.language).to.be.equal(expected);
|
||||
})
|
||||
});
|
||||
});
|
||||
describe('## static method: readLanguageAndAltText() - alt', () => {
|
||||
[
|
||||
{ test: null, expected: '' },
|
||||
{ test: undefined, expected: '' },
|
||||
{ test: '', expected: '' },
|
||||
{ test: ' ', expected: '' },
|
||||
{ test: 'plantuml', expected: '' },
|
||||
{ test: ' plantuml', expected: '' },
|
||||
{ test: 'plantuml ', expected: '' },
|
||||
{ test: 'plantuml +++', expected: '' },
|
||||
{ test: 'html+md', expected: '' },
|
||||
{ test: 'graphviz[]', expected: '' },
|
||||
{ test: 'graphviz[test]', expected: 'test' },
|
||||
{ test: 'graphviz [test test]', expected: 'test test' },
|
||||
].forEach(testCase => {
|
||||
it(`### Can read diagramLanguage. in case \'${testCase.test}\'`, () => {
|
||||
const actual = MarkdownItKrokiCore.readLanguageAndAltText(testCase.test);
|
||||
const expected = testCase.expected;
|
||||
expect(actual.alt).to.be.equal(expected);
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
120
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/safe-property.test.js
generated
vendored
Normal file
120
down-the-stack-book/node_modules/@kazumatu981/markdown-it-kroki/tests/unittest/safe-property.test.js
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
const { expect } = require('chai');
|
||||
const { safeProperty } = require('../../lib/safe-property');
|
||||
|
||||
describe('# [unit-test]: safe-property.js', () => {
|
||||
[
|
||||
{
|
||||
testCaseDescription: "standard test - string",
|
||||
testCase: {
|
||||
test: {
|
||||
property1: "hello"
|
||||
},
|
||||
name: "property1",
|
||||
type: "string",
|
||||
defaultValue: undefined
|
||||
},
|
||||
expected: "hello"
|
||||
},
|
||||
{
|
||||
testCaseDescription: "standard test - boolean",
|
||||
testCase: {
|
||||
test: {
|
||||
property1: true
|
||||
},
|
||||
name: "property1",
|
||||
type: "boolean",
|
||||
defaultValue: undefined
|
||||
},
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
testCaseDescription: "standard test - boolean on null",
|
||||
testCase: {
|
||||
test: {
|
||||
property1: null
|
||||
},
|
||||
name: "property1",
|
||||
type: "boolean",
|
||||
defaultValue: false
|
||||
},
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
testCaseDescription: "on null",
|
||||
testCase: {
|
||||
test: {
|
||||
property1: null
|
||||
},
|
||||
name: "property1",
|
||||
type: "string",
|
||||
defaultValue: "hello"
|
||||
},
|
||||
expected: "hello"
|
||||
},
|
||||
{
|
||||
testCaseDescription: "on empty string",
|
||||
testCase: {
|
||||
test: {
|
||||
property1: ''
|
||||
},
|
||||
name: "property1",
|
||||
type: "string",
|
||||
defaultValue: "hello"
|
||||
},
|
||||
expected: "hello"
|
||||
},
|
||||
{
|
||||
testCaseDescription: "on undefined",
|
||||
testCase: {
|
||||
test: {
|
||||
property1: undefined
|
||||
},
|
||||
name: "property1",
|
||||
type: "string",
|
||||
defaultValue: "hello"
|
||||
},
|
||||
expected: "hello"
|
||||
},
|
||||
{
|
||||
testCaseDescription: "on not mutch type",
|
||||
testCase: {
|
||||
test: {
|
||||
property1: 1
|
||||
},
|
||||
name: "property1",
|
||||
type: "string",
|
||||
defaultValue: "hello"
|
||||
},
|
||||
expected: "hello"
|
||||
},
|
||||
{
|
||||
testCaseDescription: "on object is null",
|
||||
testCase: {
|
||||
test: null,
|
||||
name: "property1",
|
||||
type: "string",
|
||||
defaultValue: "hello"
|
||||
},
|
||||
expected: "hello"
|
||||
},
|
||||
{
|
||||
testCaseDescription: "on object is undefined",
|
||||
testCase: {
|
||||
test: undefined,
|
||||
name: "property1",
|
||||
type: "string",
|
||||
defaultValue: "hello"
|
||||
},
|
||||
expected: "hello"
|
||||
},
|
||||
].forEach((testItem) => {
|
||||
it(`* ${testItem.testCaseDescription}`, () => {
|
||||
const actual = safeProperty(
|
||||
testItem.testCase.test,
|
||||
testItem.testCase.name,
|
||||
testItem.testCase.type,
|
||||
testItem.testCase.defaultValue);
|
||||
expect(actual).to.equal(testItem.expected);
|
||||
});
|
||||
})
|
||||
})
|
18
down-the-stack-book/package-lock.json
generated
Normal file
18
down-the-stack-book/package-lock.json
generated
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "down-the-stack-book",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"devDependencies": {
|
||||
"@kazumatu981/markdown-it-kroki": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@kazumatu981/markdown-it-kroki": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@kazumatu981/markdown-it-kroki/-/markdown-it-kroki-1.1.1.tgz",
|
||||
"integrity": "sha512-LDYl+mV2WogLQ5r4olxovm+gphL/MNGfWZ1M1woBO/YhFnfwdn5EAUu9zF/KoVZzytJPq0RNfyeDtMkv+GJihg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
5
down-the-stack-book/package.json
Normal file
5
down-the-stack-book/package.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"@kazumatu981/markdown-it-kroki": "^1.1.1"
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue