├── site ├── .gitignore ├── src │ ├── _includes │ │ ├── header.njk │ │ ├── footer.njk │ │ ├── layout.njk │ │ ├── style.css │ │ └── prism.css │ ├── math.md │ ├── tables.md │ ├── music.md │ ├── index.md │ ├── prism.md │ ├── graphviz.md │ └── charts.md ├── .eleventy.js └── package.json ├── packages ├── math │ ├── src │ │ ├── types.d.ts │ │ ├── mathup.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── README.md │ ├── test │ │ └── index.spec.ts │ └── package.json ├── charts │ ├── .gitignore │ ├── tsconfig.json │ ├── src │ │ ├── vega.ts │ │ ├── pie.ts │ │ ├── bar.ts │ │ ├── multiline.ts │ │ ├── area.ts │ │ ├── line.ts │ │ └── index.ts │ ├── package.json │ ├── test │ │ └── charts.spec.ts │ └── README.md ├── types │ ├── README.md │ ├── tsconfig.json │ ├── package.json │ └── src │ │ └── index.ts ├── prism │ ├── prepareLangs.js │ ├── tsconfig.json │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── languages.ts │ ├── README.md │ └── package-lock.json ├── from-md │ ├── test │ │ ├── test.md │ │ └── index.spec.ts │ ├── tsconfig.json │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts ├── parser │ ├── src │ │ ├── index.ts │ │ ├── parseJson.ts │ │ ├── getMeta.ts │ │ └── parseDsv.ts │ ├── tsconfig.json │ ├── test │ │ ├── parseJson.spec.ts │ │ ├── parseDsv.spec.ts │ │ └── getMeta.spec.ts │ ├── README.md │ ├── package.json │ └── package-lock.json ├── tables │ ├── tsconfig.json │ ├── package-lock.json │ ├── package.json │ ├── README.md │ └── src │ │ └── index.ts ├── from-html │ ├── tsconfig.json │ ├── README.md │ ├── package.json │ ├── test │ │ └── index.spec.ts │ ├── src │ │ └── index.ts │ └── package-lock.json ├── graphviz │ ├── tsconfig.json │ ├── test │ │ └── index.spec.ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── render.ts │ └── README.md ├── eleventy-plugin │ ├── tsconfig.json │ ├── .eleventy.js │ ├── package.json │ ├── package-lock.json │ ├── src │ │ └── index.ts │ └── README.md ├── music │ ├── tsconfig.json │ ├── src │ │ ├── createPage.ts │ │ ├── render.ts │ │ └── index.ts │ ├── README.md │ └── package.json └── rehype-transform │ ├── index.d.ts │ ├── test │ ├── svg2ast.spec.js │ └── index.spec.js │ ├── package.json │ ├── lib │ └── svg2ast.js │ ├── README.md │ └── index.js ├── lerna.json ├── assets ├── example_music.png ├── home-example.png ├── example_math(0).png ├── example_math(1).png ├── example_charts(0).png ├── example_charts(1).png ├── example_charts(2).png ├── example_charts(3).png ├── example_charts(4).png ├── example_charts(5).png ├── example_charts(6).png ├── example_charts(7).png ├── example_charts(8).png ├── example_graphviz(0).png ├── example_graphviz(1).png └── example_graphviz(2).png ├── .gitignore ├── package.json ├── readme.md └── tsconfig.json /site/.gitignore: -------------------------------------------------------------------------------- 1 | dist -------------------------------------------------------------------------------- /packages/math/src/types.d.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/charts/.gitignore: -------------------------------------------------------------------------------- 1 | test/svgs/* -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "0.1.10" 6 | } 7 | -------------------------------------------------------------------------------- /packages/types/README.md: -------------------------------------------------------------------------------- 1 | # `@code-blocks/types` 2 | 3 | The type definitions for `@code-blocks` 4 | -------------------------------------------------------------------------------- /assets/example_music.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_music.png -------------------------------------------------------------------------------- /assets/home-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/home-example.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lerna-debug.log 3 | npm-debug.log 4 | packages/*/dist 5 | .idea 6 | .vscode 7 | 8 | -------------------------------------------------------------------------------- /assets/example_math(0).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_math(0).png -------------------------------------------------------------------------------- /assets/example_math(1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_math(1).png -------------------------------------------------------------------------------- /assets/example_charts(0).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_charts(0).png -------------------------------------------------------------------------------- /assets/example_charts(1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_charts(1).png -------------------------------------------------------------------------------- /assets/example_charts(2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_charts(2).png -------------------------------------------------------------------------------- /assets/example_charts(3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_charts(3).png -------------------------------------------------------------------------------- /assets/example_charts(4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_charts(4).png -------------------------------------------------------------------------------- /assets/example_charts(5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_charts(5).png -------------------------------------------------------------------------------- /assets/example_charts(6).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_charts(6).png -------------------------------------------------------------------------------- /assets/example_charts(7).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_charts(7).png -------------------------------------------------------------------------------- /assets/example_charts(8).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_charts(8).png -------------------------------------------------------------------------------- /assets/example_graphviz(0).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_graphviz(0).png -------------------------------------------------------------------------------- /assets/example_graphviz(1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_graphviz(1).png -------------------------------------------------------------------------------- /assets/example_graphviz(2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idris-maps/code-blocks/HEAD/assets/example_graphviz(2).png -------------------------------------------------------------------------------- /packages/prism/prepareLangs.js: -------------------------------------------------------------------------------- 1 | const refractor = require('refractor') 2 | 3 | console.log(` 4 | const languages: string[] = ${JSON.stringify(refractor.listLanguages())} 5 | 6 | export default languages 7 | ` 8 | ) -------------------------------------------------------------------------------- /packages/from-md/test/test.md: -------------------------------------------------------------------------------- 1 | # Test 2 | 3 | ## a `test` code block 4 | 5 | ```test 6 | inside a test code block 7 | ``` 8 | 9 | ## another code block 10 | 11 | ```other 12 | inside a "other" code block 13 | ``` -------------------------------------------------------------------------------- /packages/types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ] 10 | } -------------------------------------------------------------------------------- /packages/charts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "./test" 12 | ] 13 | } -------------------------------------------------------------------------------- /packages/math/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "./test" 12 | ] 13 | } -------------------------------------------------------------------------------- /packages/parser/src/index.ts: -------------------------------------------------------------------------------- 1 | import _getMeta from './getMeta' 2 | import _parseDsv from './parseDsv' 3 | import _parseJson from './parseJson' 4 | 5 | export const getMeta = _getMeta 6 | export const parseDsv = _parseDsv 7 | export const parseJson = _parseJson 8 | -------------------------------------------------------------------------------- /packages/parser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "./test" 12 | ] 13 | } -------------------------------------------------------------------------------- /packages/prism/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "./test" 12 | ] 13 | } -------------------------------------------------------------------------------- /packages/tables/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "./test" 12 | ] 13 | } -------------------------------------------------------------------------------- /packages/from-html/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "./test" 12 | ] 13 | } -------------------------------------------------------------------------------- /packages/from-md/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "./test" 12 | ] 13 | } -------------------------------------------------------------------------------- /packages/graphviz/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "./test" 12 | ] 13 | } -------------------------------------------------------------------------------- /packages/eleventy-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "./test" 12 | ] 13 | } -------------------------------------------------------------------------------- /packages/music/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "./test", 12 | "./src/assets" 13 | ], 14 | } -------------------------------------------------------------------------------- /packages/parser/src/parseJson.ts: -------------------------------------------------------------------------------- 1 | import { pipe, trim } from 'ramda' 2 | 3 | export const replace = (toRemove: string, toAdd: string) => 4 | (string: string) => 5 | string.split(toRemove).join(toAdd) 6 | 7 | export default (content: string): T => 8 | pipe(trim, replace('"', '"'), JSON.parse)(content) 9 | -------------------------------------------------------------------------------- /packages/parser/src/getMeta.ts: -------------------------------------------------------------------------------- 1 | import frontmatter from 'front-matter' 2 | import { Meta } from '@code-blocks/types' 3 | 4 | export default (codeblock: string) => { 5 | const { attributes, body } = frontmatter(codeblock.trim()) 6 | return { 7 | meta: attributes, 8 | content: body.trim(), 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/eleventy-plugin/.eleventy.js: -------------------------------------------------------------------------------- 1 | const codeblocks = require('./dist').default 2 | 3 | module.exports = function(renderers) { 4 | const _renderers = renderers.map(d => d.default ? d.default : d) 5 | return function(eleventyConfig) { 6 | eleventyConfig.addTransform('codeblocks-eleventy-plugin', codeblocks(_renderers)) 7 | } 8 | } -------------------------------------------------------------------------------- /packages/rehype-transform/index.d.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from '@code-blocks/types' 2 | import { Transformer } from 'unified' 3 | export interface RendererWithLanguages { 4 | default: Renderer 5 | acceptedLanguages: string[] 6 | } 7 | declare const _default: (renderers: RendererWithLanguages[]) => (tree: any) => Promise 8 | export default _default; 9 | -------------------------------------------------------------------------------- /packages/from-md/test/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'fs' 2 | import test from 'ava' 3 | import fromMD from '../src/index' 4 | 5 | const md = readFileSync(__dirname + '/test.md', 'utf-8') 6 | 7 | test('from-md', t => { 8 | t.is(fromMD(md, ['test']).filter(d => d.type === 'code').length, 1) 9 | t.is(fromMD(md, '*').filter(d => d.type === 'code').length, 2) 10 | }) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root", 3 | "private": true, 4 | "devDependencies": { 5 | "@types/node": "^14.0.11", 6 | "ava": "^3.8.2", 7 | "lerna": "^4.0.0", 8 | "ts-node": "^8.10.2", 9 | "typescript": "^3.9.5" 10 | }, 11 | "scripts": { 12 | "publish": "lerna run build && lerna publish" 13 | }, 14 | "homepage": "https://code-blocks.surge.sh" 15 | } 16 | -------------------------------------------------------------------------------- /packages/graphviz/test/index.spec.ts: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import renderer, { acceptedLanguages } from '../src/index' 3 | 4 | test('graphviz renderer', async t => { 5 | const { type, content } = await renderer(acceptedLanguages)({ 6 | type: 'code', 7 | language: acceptedLanguages[0], 8 | content: 'digraph { a -> b }', 9 | }) 10 | t.is(type, 'other') 11 | t.is(typeof content, 'string') 12 | t.true(content.includes(' ` 6 | 7 | 8 |
9 | 10 | 11 | 12 | ` 13 | 14 | export default async () => { 15 | const lib = await promisify(readFile)(resolve(__dirname, 'assets', 'abc.js'), 'utf-8') 16 | return template(lib) 17 | } 18 | -------------------------------------------------------------------------------- /site/src/_includes/header.njk: -------------------------------------------------------------------------------- 1 |
2 |

3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {{title}} 14 |

15 |
-------------------------------------------------------------------------------- /packages/parser/test/parseJson.spec.ts: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import parseJson from '../src/parseJson' 3 | 4 | const json = `{"hello":"world"}` 5 | const withQuotes = `{"hello":"world"}` 6 | const withBackslash = `{\"hello\":\"world\"}` 7 | const expected = { hello: 'world' } 8 | const notJson = 'Hello world' 9 | 10 | test('parser parseJson', t => { 11 | t.deepEqual(parseJson(json), expected) 12 | t.deepEqual(parseJson(withQuotes), expected) 13 | t.deepEqual(parseJson(withBackslash), expected) 14 | try { 15 | parseJson(notJson) 16 | t.fail('Should throw error if not json') 17 | } catch (err) { 18 | t.pass() 19 | } 20 | }) -------------------------------------------------------------------------------- /packages/from-md/README.md: -------------------------------------------------------------------------------- 1 | # `@code-blocks/from-md` 2 | 3 | Extracts code blocks from markdown. 4 | 5 | ## Usage 6 | 7 | ```ts 8 | import fromMD from '@code-blocks/from-md' 9 | 10 | fromMD(someHTML, ['line-chart', 'csv-table']) 11 | ``` 12 | 13 | Takes tow arguments: 14 | 15 | * `md` a string containing markdown 16 | * `languages` an array of languages to extract 17 | 18 | Returns an array of parts: 19 | 20 | ```ts 21 | export interface PartCode { 22 | type: 'code' 23 | language: string 24 | content: string 25 | } 26 | 27 | export interface PartOther { 28 | type: 'other' 29 | content: string 30 | } 31 | 32 | export type Part = PartCode | PartOther 33 | ``` -------------------------------------------------------------------------------- /packages/from-html/README.md: -------------------------------------------------------------------------------- 1 | # `@code-blocks/from-html` 2 | 3 | Extracts code blocks from HTML. 4 | 5 | ## Usage 6 | 7 | ```ts 8 | import fromHTML from '@code-blocks/from-html' 9 | 10 | fromHTML(someHTML, ['line-chart', 'csv-table']) 11 | ``` 12 | 13 | Takes two arguments: 14 | 15 | * `html` a string containing HTML 16 | * `languages` an array of languages to extract 17 | 18 | Returns an array of parts: 19 | 20 | ```ts 21 | export interface PartCode { 22 | type: 'code' 23 | language: string 24 | content: string 25 | } 26 | 27 | export interface PartOther { 28 | type: 'other' 29 | content: string 30 | } 31 | 32 | export type Part = PartCode | PartOther 33 | ``` -------------------------------------------------------------------------------- /packages/types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/types", 3 | "version": "0.1.0", 4 | "description": "Types...", 5 | "author": "idris-maps", 6 | "license": "GPLv2", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "files": [ 10 | "index.d.ts" 11 | ], 12 | "scripts": { 13 | "test": "echo \"@code-blocks/types has no tests\"", 14 | "build": "tsc" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/idris-maps/code-blocks.git" 19 | }, 20 | "homepage": "https://github.com/idris-maps/code-blocks/tree/master/packages/types", 21 | "publishConfig": { 22 | "access": "public" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/charts/src/vega.ts: -------------------------------------------------------------------------------- 1 | import { View, parse } from 'vega' 2 | import { compile } from 'vega-lite' 3 | 4 | const removeWidthAndHeight = (svg: string) => { 5 | const [svgTag, ...rest] = svg.split('>') 6 | const svgAttrs = svgTag.split(' ') 7 | return [ 8 | svgAttrs.filter(d => !d.startsWith('width=') && !d.startsWith('height=')).join(' '), 9 | ...rest, 10 | ].join('>') 11 | } 12 | 13 | export const renderVega = async (json: any) => { 14 | const view = new View(parse(json)) 15 | return removeWidthAndHeight(await view.toSVG()) 16 | } 17 | 18 | export const renderVegalite = async (json: any) => { 19 | const { spec } = compile(json) 20 | return await renderVega(spec) 21 | } 22 | -------------------------------------------------------------------------------- /site/.eleventy.js: -------------------------------------------------------------------------------- 1 | const cleanCSS = require('clean-css') 2 | 3 | const codeblocks = require('@code-blocks/eleventy-plugin') 4 | 5 | const charts = require('@code-blocks/charts') 6 | const graphviz = require('@code-blocks/graphviz') 7 | const highlight = require('@code-blocks/prism') 8 | const math = require('@code-blocks/math') 9 | const music = require('@code-blocks/music') 10 | const tables = require('@code-blocks/tables') 11 | 12 | module.exports = function(eleventyConfig) { 13 | eleventyConfig.addFilter('cssmin', function(code) { 14 | return new cleanCSS({}).minify(code).styles 15 | }) 16 | 17 | eleventyConfig.addPlugin(codeblocks([ 18 | charts, 19 | graphviz, 20 | highlight, 21 | math, 22 | music, 23 | tables, 24 | ])) 25 | } -------------------------------------------------------------------------------- /packages/parser/README.md: -------------------------------------------------------------------------------- 1 | # `@code-blocks/parser` 2 | 3 | Parses code blocks, with or without front-matter, as JSON or DSV. 4 | 5 | ## Usage 6 | 7 | ```ts 8 | import { 9 | getMeta, 10 | parseDsv, 11 | parseJson, 12 | } from '@code-blocks/parser' 13 | ``` 14 | 15 | ### `getMeta` 16 | 17 | Extracts meta data from front-matter. Takes the content of a code block and returns an object with two keys `meta` (a JSON object with the meta data) and `content` (the rest of the code block). 18 | 19 | ### `parseDsv` 20 | 21 | Parses the content as delimiter separated values. Takes the separator as argument and returns a function that takes the content of the code block and returns an array of JSON objects. 22 | 23 | ### `parseJson` 24 | 25 | Parses the content as JSON. Takes the content as only argument and returns a JSON object. -------------------------------------------------------------------------------- /site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "site", 3 | "version": "1.0.0", 4 | "description": "@code-blocks documentation", 5 | "scripts": { 6 | "dev": "rm -rf dist && npx eleventy --input=src --output=dist --serve --formats=md", 7 | "build": "rm -rf dist && npx eleventy --input=src --output=dist --formats=md", 8 | "deploy": "surge dist code-blocks.surge.sh", 9 | "publish": "npm run build && npm run deploy" 10 | }, 11 | "devDependencies": { 12 | "@code-blocks/charts": "^0.1.0", 13 | "@code-blocks/eleventy-plugin": "^0.1.0", 14 | "@code-blocks/graphviz": "^0.1.5", 15 | "@code-blocks/math": "^0.1.5", 16 | "@code-blocks/music": "^0.1.3", 17 | "@code-blocks/prism": "^0.1.2", 18 | "@code-blocks/tables": "^0.1.0", 19 | "clean-css": "^4.2.3", 20 | "eleventy": "^1.0.6" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /site/src/_includes/footer.njk: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/math/README.md: -------------------------------------------------------------------------------- 1 | # @code-blocks/math 2 | 3 | ## Install 4 | 5 | ```bash 6 | npm install @code-blocks/math 7 | ``` 8 | 9 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](https://github.com/idris-maps/code-blocks). 10 | 11 | ## Usage 12 | 13 | This library uses [mathup](https://runarberg.github.io/mathup/) under the hood. For more information about the syntax, checkout their website. 14 | 15 | **language: `mathup`** 16 | 17 | ``` 18 | grad f(x,y) = ((del f)/(del x) (x, y), (del f)/(del y)(x,y)) 19 | ``` 20 | 21 | ![Math example 0](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_math(0).png) 22 | 23 | ``` 24 | ||(bf x)||^2 = [x_1 ; x_2 ; x_3]*[x_1 ; x_2 ; x_3] 25 | ``` 26 | 27 | ![Math example 1](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_math(1).png) -------------------------------------------------------------------------------- /packages/math/test/index.spec.ts: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import renderer, { acceptedLanguages } from '../src/index' 3 | 4 | const content = ` 5 | 1 + 1 = 2 6 | ` 7 | 8 | const contentWithOptions = ` 9 | --- 10 | className: test 11 | dir: rtl 12 | --- 13 | 1 + 1 = 2 14 | ` 15 | 16 | const render = (content: string) => renderer(acceptedLanguages)({ 17 | type: 'code', 18 | language: acceptedLanguages[0], 19 | content, 20 | }) 21 | 22 | test('mathup renderer', async t => { 23 | const withoutOptions = await render(content) 24 | t.is(withoutOptions.type, 'other') 25 | t.is(typeof withoutOptions.content, 'string') 26 | t.true(withoutOptions.content.includes(' src/languages.ts", 17 | "build": "npm run prepare:languages && tsc" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/idris-maps/code-blocks.git" 22 | }, 23 | "homepage": "https://code-blocks.surge.sh/prism", 24 | "dependencies": { 25 | "refractor": "^3.1.0", 26 | "rehype": "^11.0.0" 27 | }, 28 | "devDependencies": { 29 | "@code-blocks/types": "^0.1.0", 30 | "@types/refractor": "^2.8.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /site/src/math.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout.njk 3 | title: "@code-blocks/math" 4 | short: "MathML" 5 | description: "Use mathup in markdown code blocks" 6 | tags: renderer 7 | --- 8 | 9 | ## Install 10 | 11 | ```bash 12 | npm install @code-blocks/math 13 | ``` 14 | 15 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](/). 16 | 17 | ## Usage 18 | 19 | This library uses [mathup](https://runarberg.github.io/mathup/) under the hood. For more information about the syntax, checkout their website. 20 | 21 | **language: `mathup`** 22 | 23 | ``` 24 | grad f(x,y) = ((del f)/(del x) (x, y), (del f)/(del y)(x,y)) 25 | ``` 26 | 27 | ```mathup 28 | grad f(x,y) = ((del f)/(del x) (x, y), (del f)/(del y)(x,y)) 29 | ``` 30 | 31 | ``` 32 | ||(bf x)||^2 = [x_1 ; x_2 ; x_3]*[x_1 ; x_2 ; x_3] 33 | ``` 34 | 35 | ```mathup 36 | ||(bf x)||^2 = [x_1 ; x_2 ; x_3]*[x_1 ; x_2 ; x_3] 37 | ``` -------------------------------------------------------------------------------- /packages/from-md/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/from-md", 3 | "version": "0.1.0", 4 | "description": "Get code blocks from markdown", 5 | "author": "idris-maps", 6 | "license": "GPLv2", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "files": [ 10 | "dist" 11 | ], 12 | "publishConfig": { 13 | "access": "public" 14 | }, 15 | "scripts": { 16 | "test": "ava", 17 | "build": "tsc", 18 | "test:verbose": "ava --verbose" 19 | }, 20 | "ava": { 21 | "extensions": [ 22 | "ts" 23 | ], 24 | "require": [ 25 | "ts-node/register" 26 | ] 27 | }, 28 | "devDependencies": { 29 | "@code-blocks/types": "^0.1.0" 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "https://github.com/idris-maps/code-blocks.git" 34 | }, 35 | "homepage": "https://github.com/idris-maps/code-blocks/tree/master/packages/from-md" 36 | } 37 | -------------------------------------------------------------------------------- /packages/tables/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/tables", 3 | "version": "0.1.8", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@code-blocks/tables", 9 | "version": "0.1.6", 10 | "license": "GPLv2", 11 | "dependencies": { 12 | "xml-string": "^2.0.2" 13 | } 14 | }, 15 | "node_modules/xml-string": { 16 | "version": "2.0.2", 17 | "resolved": "https://registry.npmjs.org/xml-string/-/xml-string-2.0.2.tgz", 18 | "integrity": "sha512-QIMl7dVRuOsFTVfbzzXLOKVtz9lLyohHA/6uYQVcfGvuiaECxHygNixZpBRJ3Y5744/avrW/Vx8r/Ol4ebkRRQ==" 19 | } 20 | }, 21 | "dependencies": { 22 | "xml-string": { 23 | "version": "2.0.2", 24 | "resolved": "https://registry.npmjs.org/xml-string/-/xml-string-2.0.2.tgz", 25 | "integrity": "sha512-QIMl7dVRuOsFTVfbzzXLOKVtz9lLyohHA/6uYQVcfGvuiaECxHygNixZpBRJ3Y5744/avrW/Vx8r/Ol4ebkRRQ==" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /site/src/_includes/layout.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {{title}} 12 | {% set css %} 13 | {% include "style.css" %} 14 | {% include "prism.css" %} 15 | {% endset %} 16 | 19 | 20 | 21 | {% include "header.njk" %} 22 |
23 | {{ content | safe }} 24 |
25 | {% include "footer.njk" %} 26 | 27 | 28 | -------------------------------------------------------------------------------- /packages/rehype-transform/test/svg2ast.spec.js: -------------------------------------------------------------------------------- 1 | const test = require('ava') 2 | const svg2ast = require('../lib/svg2ast') 3 | 4 | const svg = '
' 5 | const expectedSvgProperties = { viewBox: '0 0 100 100' } 6 | const expectedCircleProperties = { 7 | cx: '50', 8 | cy: '50', 9 | r: '50', 10 | } 11 | 12 | const code = '
some code
' 13 | 14 | test('rehype-wrapper svg2ast', t => { 15 | const { properties, children } = svg2ast(svg) 16 | t.true(properties.className.includes('chart')) 17 | t.deepEqual(children[0].properties, expectedSvgProperties) 18 | t.true(children[0].children[0].tagName === 'circle') 19 | t.deepEqual(children[0].children[0].properties, expectedCircleProperties) 20 | }) 21 | 22 | test('rehype-wrapper svg2ast with code block', t => { 23 | const { children } = svg2ast(code) 24 | t.is(children[0].tagName, 'pre') 25 | }) -------------------------------------------------------------------------------- /packages/music/README.md: -------------------------------------------------------------------------------- 1 | # @code-blocks/music 2 | 3 | ## Install 4 | 5 | ```bash 6 | npm install @code-blocks/music 7 | ``` 8 | 9 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](https://github.com/idris-maps/code-blocks). 10 | 11 | ## Usage 12 | 13 | This library uses [abc.js](https://www.abcjs.net/) under the hood. For more information about the syntax, checkout their website. 14 | 15 | **language: `music-abc`** 16 | 17 | ``` 18 | X: 1 19 | T: Cooley's 20 | M: 4/4 21 | L: 1/8 22 | K: Emin 23 | |:D2|"Em"EB{c}BA B2 EB|~B2 AB dBAG|\ 24 | "D"FDAD BDAD|FDAD dAFD| 25 | "Em"EBBA B2 EB|B2 AB defg|\ 26 | "D"afe^c dBAF|"Em"DEFD E2:| 27 | |:gf|"Em"eB B2 efge|eB B2 gedB|\ 28 | "D"A2 FA DAFA|A2 FA defg| 29 | "Em"eB B2 eBgB|eB B2 defg|\ 30 | "D"afe^c dBAF|"Em"DEFD E2:| 31 | ``` 32 | 33 | ![Music sheet example](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_music.png) 34 | -------------------------------------------------------------------------------- /packages/tables/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/tables", 3 | "version": "0.1.8", 4 | "description": "Create tables from csv code blocks", 5 | "author": "idris-maps", 6 | "license": "GPLv2", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "directories": { 10 | "dist": "dist" 11 | }, 12 | "files": [ 13 | "dist" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/idris-maps/code-blocks.git" 21 | }, 22 | "scripts": { 23 | "test": "echo \"There are no tests for table\"", 24 | "build": "tsc" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/idris-maps/code-blocks/issues" 28 | }, 29 | "homepage": "https://code-blocks.surge.sh/tables", 30 | "dependencies": { 31 | "@code-blocks/parser": "^0.1.8", 32 | "@code-blocks/types": "^0.1.0", 33 | "xml-string": "^2.0.2" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/charts/src/pie.ts: -------------------------------------------------------------------------------- 1 | import { renderVegalite } from './vega' 2 | import { Meta, DsvDataItem } from '@code-blocks/types' 3 | 4 | interface Config { 5 | width: string 6 | height: string 7 | [key: string]: any 8 | } 9 | 10 | const defaultConfig: Config = { 11 | width: '400', 12 | height: '200', 13 | } 14 | 15 | export default async ( 16 | { head, data }: { head: string[], data: DsvDataItem[] }, 17 | meta: Meta = {} 18 | ) => { 19 | const pieConfig = { ...defaultConfig, ...meta } 20 | const spec = { 21 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json", 22 | "width": pieConfig.width, 23 | "height": pieConfig.height, 24 | "data": { 25 | "values": data, 26 | }, 27 | "mark": "arc", 28 | "encoding": { 29 | "theta": {"field": head[1], "type": "quantitative"}, 30 | "color": {"field": head[0], "type": "nominal"} 31 | }, 32 | "view": {"stroke": null} 33 | } 34 | return await renderVegalite(spec) 35 | } 36 | -------------------------------------------------------------------------------- /packages/from-md/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Part, LanguagesToParse, parseAllLanguages } from '@code-blocks/types' 2 | 3 | export default (md: string, languages: LanguagesToParse): Part[] => 4 | md.split('```') 5 | .map((d, i) => 6 | i % 2 === 0 7 | ? { isCode: false, content: d } 8 | : { isCode: true, content: d } 9 | ) 10 | .map(({ isCode, content }) => { 11 | if (isCode) { 12 | const [first, ...rest] = content.split('\n') 13 | const language = first.trim() 14 | if (parseAllLanguages(languages) || languages.includes(language)) { 15 | return { 16 | type: 'code', 17 | language, 18 | content: rest.join('\n').trim(), 19 | } 20 | } 21 | return { 22 | type: 'other', 23 | content: '```' + `${language}\n` + rest.join('\n') + '```' 24 | } 25 | } 26 | return { 27 | type: 'other', 28 | content, 29 | } 30 | }) 31 | -------------------------------------------------------------------------------- /packages/math/src/mathup.ts: -------------------------------------------------------------------------------- 1 | import { Meta } from '@code-blocks/types' 2 | const mathup = require('mathup') 3 | 4 | interface MathUpOptions { 5 | decimalMark?: string 6 | colSep?: string 7 | rowSep?: string 8 | display?: string 9 | dir?: string 10 | bare?: boolean 11 | } 12 | 13 | const defaultOptions: MathUpOptions = { 14 | decimalMark: ".", 15 | colSep: ",", 16 | rowSep: ";", 17 | display: "inline", 18 | dir: "ltr", 19 | bare: false, 20 | }; 21 | 22 | const metaToOptions = (meta?: Meta): MathUpOptions => 23 | meta 24 | ? Object.keys(defaultOptions) 25 | .reduce((r, key) => { 26 | const value = meta[key] 27 | if (!value) { return r } 28 | if (key === 'bare') { 29 | return { ...r, bare: value === 'true' } 30 | } 31 | return { ...r, [key]: value } 32 | }, {}) 33 | : {} 34 | 35 | export default (expression: string, meta?: Meta): string => 36 | mathup(expression, { ...defaultOptions, ...metaToOptions(meta) }) 37 | -------------------------------------------------------------------------------- /packages/parser/test/parseDsv.spec.ts: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import parseDsv from '../src/parseDsv' 3 | 4 | const head = ['Foo', 'Bar', 'Baz'] 5 | const body = [ 6 | ['Hello', 1, true], 7 | ['World', 2, false], 8 | ] 9 | 10 | const expected = [ 11 | { 'Foo': 'Hello', 'Bar': 1, 'Baz': true }, 12 | { 'Foo': 'World', 'Bar': 2, 'Baz': false }, 13 | ] 14 | 15 | const toString = (separator: string, data: any[][]): string => 16 | data.map(line => line.join(separator)).join('\n') 17 | 18 | const csv = toString(',', [head, ...body]) 19 | const tsv = toString('\t', [head, ...body]) 20 | const semicolonSeparatedValues = toString(';', [head, ...body]) 21 | const notDsv = 'Not a dsv' 22 | 23 | test('parser parseDsv', t => { 24 | t.deepEqual(parseDsv(',')(csv).data, expected) 25 | t.deepEqual(parseDsv('\t')(tsv).data, expected) 26 | t.deepEqual(parseDsv(';')(semicolonSeparatedValues).data, expected) 27 | try { 28 | parseDsv(',')(notDsv) 29 | t.fail() 30 | } catch (err) { 31 | t.pass() 32 | } 33 | }) -------------------------------------------------------------------------------- /packages/types/src/index.ts: -------------------------------------------------------------------------------- 1 | export interface PartCode { 2 | type: 'code' 3 | language: string 4 | content: string 5 | } 6 | 7 | export interface PartOther { 8 | type: 'other' 9 | content: string 10 | } 11 | 12 | export type Part = PartCode | PartOther 13 | 14 | export const isPartCode = (part: Part): part is PartCode => 15 | part.type === 'code' && Boolean(part.language) 16 | 17 | export const isPartOther = (part: Part): part is PartOther => 18 | part.type === 'other' 19 | 20 | export const isPart = (d: any): d is Part => 21 | d && d.type && d.content && (isPartCode(d) || isPartOther(d)) 22 | 23 | export type LanguagesToParse = string[] | '*' 24 | 25 | export const parseAllLanguages = (d: LanguagesToParse): d is '*' => 26 | d === '*' 27 | 28 | export interface DsvDataItem { 29 | [key: string]: boolean | number | string 30 | } 31 | 32 | export interface Meta { 33 | [key: string]: any 34 | } 35 | 36 | export type Renderer = (languages: LanguagesToParse) => 37 | (part: Part) => Promise 38 | -------------------------------------------------------------------------------- /packages/charts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/charts", 3 | "version": "0.1.9", 4 | "description": "Create svg charts from code blocks", 5 | "author": "idris-maps", 6 | "license": "GPLv2", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "directories": { 10 | "dist": "dist" 11 | }, 12 | "files": [ 13 | "dist" 14 | ], 15 | "scripts": { 16 | "test": "ava", 17 | "build": "tsc", 18 | "test:verbose": "ava" 19 | }, 20 | "dependencies": { 21 | "@code-blocks/parser": "^0.1.8", 22 | "@code-blocks/types": "^0.1.0", 23 | "vega": "^5.20.2", 24 | "vega-lite": "^5.1.0" 25 | }, 26 | "ava": { 27 | "extensions": [ 28 | "ts" 29 | ], 30 | "require": [ 31 | "ts-node/register" 32 | ] 33 | }, 34 | "publishConfig": { 35 | "access": "public" 36 | }, 37 | "repository": { 38 | "type": "git", 39 | "url": "https://github.com/idris-maps/code-blocks.git" 40 | }, 41 | "homepage": "https://code-blocks.surge.sh/charts" 42 | } 43 | -------------------------------------------------------------------------------- /packages/charts/src/bar.ts: -------------------------------------------------------------------------------- 1 | import { renderVegalite } from './vega' 2 | import { Meta, DsvDataItem } from '@code-blocks/types' 3 | 4 | interface Config { 5 | width: string 6 | height: string 7 | color: string 8 | [key: string]: any 9 | } 10 | 11 | const defaultConfig: Config = { 12 | width: '400', 13 | height: '200', 14 | color: 'steelblue', 15 | } 16 | 17 | export default async ( 18 | { head, data }: { head: string[], data: DsvDataItem[] }, 19 | meta: Meta = {} 20 | ) => { 21 | const barConfig = { ...defaultConfig, ...meta } 22 | const spec = { 23 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json", 24 | "width": barConfig.width, 25 | "height": barConfig.height, 26 | "data": { 27 | "values": data, 28 | }, 29 | "mark": "bar", 30 | "encoding": { 31 | "x": {"field": head[0], "type": "ordinal" }, 32 | "y": {"field": head[1], "type": "quantitative"}, 33 | "color": { "value": barConfig.color } 34 | } 35 | } 36 | return await renderVegalite(spec) 37 | } 38 | -------------------------------------------------------------------------------- /packages/music/src/render.ts: -------------------------------------------------------------------------------- 1 | import { JSDOM } from 'jsdom' 2 | import createPage from './createPage' 3 | 4 | const replace = (toRemove: string, toAdd: string) => 5 | (string: string) => 6 | string.split(toRemove).join(toAdd) 7 | 8 | export default async (abc: string) => { 9 | const tune = replace('"', '"')(abc) 10 | const page = await createPage() 11 | const dom = new JSDOM(page, { runScripts: 'dangerously' }) 12 | 13 | dom.window.ABCJS.renderAbc('paper', tune) 14 | const div = dom.window.document.body.getElementsByTagName('div')[0] 15 | 16 | // remove font-family 17 | Array.from(div.getElementsByTagName('text')) 18 | .forEach(d => d.removeAttribute('font-family')) 19 | 20 | // set viewBox 21 | const svg = div.getElementsByTagName('svg')[0] 22 | const width = svg.getAttribute('width') 23 | const height = svg.getAttribute('height') 24 | svg.setAttribute('viewBox', `0 0 ${width} ${height}`) 25 | svg.removeAttribute('width') 26 | svg.removeAttribute('height') 27 | 28 | return div.innerHTML 29 | } -------------------------------------------------------------------------------- /packages/parser/test/getMeta.spec.ts: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import getMeta from '../src/getMeta' 3 | 4 | const stringContent = ` 5 | Hello world 6 | ` 7 | 8 | const jsonContent = `{ 9 | "message": "hello world" 10 | }` 11 | 12 | const expectedMeta = { 13 | test: 'yes', 14 | num: 1, 15 | bool: true, 16 | } 17 | 18 | const withFM = (content: string) => ` 19 | --- 20 | test: yes 21 | num: 1 22 | bool: true 23 | --- 24 | ${content} 25 | ` 26 | 27 | const withEmptyFM = (content: string) => ` 28 | --- 29 | --- 30 | ${content} 31 | ` 32 | 33 | const withoutFM = (content: string) => ` 34 | ${content} 35 | ` 36 | 37 | test('parser getMeta', t => { 38 | t.deepEqual(getMeta(withFM(stringContent)).meta, expectedMeta) 39 | t.deepEqual(getMeta(withFM(jsonContent)).meta, expectedMeta) 40 | 41 | t.deepEqual(getMeta(withEmptyFM(stringContent)).meta, {}) 42 | t.deepEqual(getMeta(withEmptyFM(jsonContent)).meta, {}) 43 | 44 | t.deepEqual(getMeta(withoutFM(stringContent)).meta, {}) 45 | t.deepEqual(getMeta(withoutFM(jsonContent)).meta, {}) 46 | }) -------------------------------------------------------------------------------- /packages/music/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/music", 3 | "version": "0.1.8", 4 | "description": "Create music sheets from code blocks", 5 | "author": "idris-maps", 6 | "license": "GPLv2", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "files": [ 10 | "dist" 11 | ], 12 | "publishConfig": { 13 | "access": "public" 14 | }, 15 | "scripts": { 16 | "build": "tsc && npm run cp-assets", 17 | "cp-assets": "cp -r src/assets dist/assets", 18 | "get-abc": "curl https://raw.githubusercontent.com/paulrosen/abcjs/master/bin/abcjs_basic_5.10.3-min.js > src/assets/abc.js" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/idris-maps/code-blocks.git" 23 | }, 24 | "homepage": "https://code-blocks.surge.sh/music", 25 | "dependencies": { 26 | "@code-blocks/parser": "^0.1.8", 27 | "jsdom": "^16.3.0" 28 | }, 29 | "devDependencies": { 30 | "@code-blocks/types": "^0.1.0", 31 | "@types/jsdom": "^16.2.3", 32 | "ts-node": "^8.10.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/from-html/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/from-html", 3 | "version": "0.1.8", 4 | "description": "Get code blocks from HTML", 5 | "author": "idris-maps", 6 | "license": "GPLv2", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "directories": { 10 | "dist": "dist" 11 | }, 12 | "files": [ 13 | "dist" 14 | ], 15 | "scripts": { 16 | "test": "ava", 17 | "build": "tsc", 18 | "test:verbose": "ava --verbose" 19 | }, 20 | "dependencies": { 21 | "@code-blocks/types": "^0.1.0", 22 | "ramda": "^0.27.0" 23 | }, 24 | "devDependencies": { 25 | "@types/ramda": "^0.27.6" 26 | }, 27 | "ava": { 28 | "extensions": [ 29 | "ts" 30 | ], 31 | "require": [ 32 | "ts-node/register" 33 | ] 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "https://github.com/idris-maps/code-blocks.git" 38 | }, 39 | "homepage": "https://github.com/idris-maps/code-blocks/tree/master/packages/from-html", 40 | "publishConfig": { 41 | "access": "public" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/charts/src/multiline.ts: -------------------------------------------------------------------------------- 1 | import { renderVegalite } from './vega' 2 | import { Meta, DsvDataItem } from '@code-blocks/types' 3 | 4 | interface Config { 5 | width: string 6 | height: string 7 | temporal?: boolean 8 | [key: string]: any 9 | } 10 | 11 | const defaultConfig: Config = { 12 | width: '400', 13 | height: '200', 14 | } 15 | 16 | export default async ( 17 | { head, data }: { head: string[], data: DsvDataItem[] }, 18 | meta: Meta = {} 19 | ) => { 20 | const multilineConfig = { ...defaultConfig, ...meta } 21 | const spec = { 22 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json", 23 | "width": multilineConfig.width, 24 | "height": multilineConfig.height, 25 | "data": { 26 | "values": data, 27 | }, 28 | "mark": "line", 29 | "encoding": { 30 | "x": {"field": head[0], "type": multilineConfig.temporal ? "temporal" : "ordinal" }, 31 | "y": {"field": head[1], "type": "quantitative"}, 32 | "color": {"field": head[2], "type": "nominal"} 33 | } 34 | } 35 | return await renderVegalite(spec) 36 | } 37 | -------------------------------------------------------------------------------- /packages/parser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/parser", 3 | "version": "0.1.8", 4 | "description": "Code block parser", 5 | "author": "idris-maps", 6 | "license": "GPLv2", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "directories": { 10 | "dist": "dist" 11 | }, 12 | "files": [ 13 | "dist" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "scripts": { 19 | "test": "ava", 20 | "build": "tsc", 21 | "test:verbose": "ava --verbose" 22 | }, 23 | "dependencies": { 24 | "front-matter": "^4.0.2", 25 | "ramda": "^0.27.0" 26 | }, 27 | "ava": { 28 | "extensions": [ 29 | "ts" 30 | ], 31 | "require": [ 32 | "ts-node/register" 33 | ] 34 | }, 35 | "devDependencies": { 36 | "@code-blocks/types": "^0.1.0", 37 | "@types/ramda": "^0.27.6" 38 | }, 39 | "repository": { 40 | "type": "git", 41 | "url": "https://github.com/idris-maps/code-blocks.git" 42 | }, 43 | "homepage": "https://github.com/idris-maps/code-blocks/tree/master/packages/parser" 44 | } 45 | -------------------------------------------------------------------------------- /site/src/tables.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout.njk 3 | title: "@code-blocks/tables" 4 | short: "HTML tables" 5 | description: "Easy HTML tables in markdown with code blocks" 6 | tags: renderer 7 | --- 8 | 9 | ## Install 10 | 11 | ```bash 12 | npm install @code-blocks/tables 13 | ``` 14 | 15 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](/). 16 | 17 | ## Usage 18 | 19 | Because creating tables in pure markdown can be painful... 20 | 21 | **language: `csv-table`** 22 | 23 | ``` 24 | Letters, Amount 25 | A,28 26 | B,55 27 | C,43 28 | D,91 29 | E,81 30 | F,53 31 | ``` 32 | 33 | ```csv-table 34 | Letters, Amount 35 | A,28 36 | B,55 37 | C,43 38 | D,91 39 | E,81 40 | F,53 41 | ``` 42 | 43 | If other than `,` set the separator in the options: 44 | 45 | ``` 46 | --- 47 | separator: \t 48 | --- 49 | Letters\tAmount 50 | A\t28 51 | B\t55 52 | C\t43 53 | D\t91 54 | E\t81 55 | F\t53 56 | ``` 57 | 58 | ```csv-table 59 | --- 60 | separator: \t 61 | --- 62 | Letters\tAmount 63 | A\t28 64 | B\t55 65 | C\t43 66 | D\t91 67 | E\t81 68 | F\t53 69 | ``` -------------------------------------------------------------------------------- /packages/music/src/index.ts: -------------------------------------------------------------------------------- 1 | import render from './render' 2 | import { Renderer, Part, LanguagesToParse, isPartCode } from '@code-blocks/types' 3 | import { getMeta } from '@code-blocks/parser' 4 | 5 | const wrapInDiv = (svg: string, className: string = 'music-sheet') => 6 | `
${svg}
` 7 | 8 | export const acceptedLanguages = [ 9 | 'music-abc', 10 | 'music-sheet', 11 | ] 12 | 13 | const renderer: Renderer = (languages: LanguagesToParse = '*') => { 14 | const languagesToLookFor = Array.isArray(languages) 15 | ? languages.filter(language => acceptedLanguages.includes(language)) 16 | : acceptedLanguages 17 | 18 | return async (part: Part) => { 19 | 20 | if (!isPartCode(part)) { return part } 21 | if (!languagesToLookFor.includes(part.language)) { return part } 22 | 23 | const { meta, content } = getMeta(part.content) 24 | 25 | try { 26 | return { type: 'other', content: wrapInDiv(await render(content), meta.className) } 27 | } catch (err) { 28 | return part 29 | } 30 | } 31 | } 32 | 33 | export default renderer 34 | -------------------------------------------------------------------------------- /packages/charts/src/area.ts: -------------------------------------------------------------------------------- 1 | import { renderVegalite } from './vega' 2 | import { Meta, DsvDataItem } from '@code-blocks/types' 3 | 4 | interface Config { 5 | width: string 6 | height: string 7 | color: string 8 | temporal?: boolean 9 | [key: string]: any 10 | } 11 | 12 | const defaultConfig: Config = { 13 | width: '400', 14 | height: '200', 15 | color: 'steelblue', 16 | } 17 | 18 | export default async ( 19 | { head, data }: { head: string[], data: DsvDataItem[] }, 20 | meta: Meta = {} 21 | ) => { 22 | const lineConfig = { ...defaultConfig, ...meta } 23 | const spec = { 24 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json", 25 | "width": lineConfig.width, 26 | "height": lineConfig.height, 27 | "data": { 28 | "values": data, 29 | }, 30 | "mark": "area", 31 | "encoding": { 32 | "x": {"field": head[0], "type": lineConfig.temporal ? "temporal" : "ordinal" }, 33 | "y": {"field": head[1], "type": "quantitative"}, 34 | "color": { "value": lineConfig.color } 35 | } 36 | } 37 | return await renderVegalite(spec) 38 | } 39 | -------------------------------------------------------------------------------- /packages/charts/src/line.ts: -------------------------------------------------------------------------------- 1 | import { renderVegalite } from './vega' 2 | import { Meta, DsvDataItem } from '@code-blocks/types' 3 | 4 | interface Config { 5 | width: string 6 | height: string 7 | color: string 8 | temporal?: boolean 9 | [key: string]: any 10 | } 11 | 12 | const defaultConfig: Config = { 13 | width: '400', 14 | height: '200', 15 | color: 'steelblue', 16 | } 17 | 18 | export default async ( 19 | { head, data }: { head: string[], data: DsvDataItem[] }, 20 | meta: Meta = {} 21 | ) => { 22 | const lineConfig = { ...defaultConfig, ...meta } 23 | const spec = { 24 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json", 25 | "width": lineConfig.width, 26 | "height": lineConfig.height, 27 | "data": { 28 | "values": data, 29 | }, 30 | "mark": "line", 31 | "encoding": { 32 | "x": {"field": head[0], "type": lineConfig.temporal ? "temporal" : "ordinal" }, 33 | "y": {"field": head[1], "type": "quantitative"}, 34 | "color": { "value": lineConfig.color } 35 | } 36 | } 37 | return await renderVegalite(spec) 38 | } 39 | -------------------------------------------------------------------------------- /packages/eleventy-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/eleventy-plugin", 3 | "version": "0.1.8", 4 | "description": "An eleventy plugin to parse code blocks", 5 | "keywords": [ 6 | "eleventy", 7 | "11ty", 8 | "eleventy-plugin", 9 | "codeblock" 10 | ], 11 | "author": "idris-maps", 12 | "homepage": "https://code-blocks.surge.sh", 13 | "license": "GPLv2", 14 | "main": ".eleventy.js", 15 | "directories": { 16 | "dist": "dist" 17 | }, 18 | "files": [ 19 | "**/*" 20 | ], 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/idris-maps/code-blocks.git" 27 | }, 28 | "scripts": { 29 | "test": "echo \"There are no tests for eleventy-plugin\"", 30 | "build": "tsc" 31 | }, 32 | "bugs": { 33 | "url": "https://github.com/idris-maps/code-blocks/issues" 34 | }, 35 | "devDependencies": { 36 | "typescript": "^3.9.7" 37 | }, 38 | "dependencies": { 39 | "@code-blocks/from-html": "^0.1.8", 40 | "@code-blocks/types": "^0.1.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/math/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer, LanguagesToParse, Part, isPartCode } from '@code-blocks/types' 2 | import { getMeta } from '@code-blocks/parser' 3 | import mathup from './mathup' 4 | 5 | export const acceptedLanguages = ['mathup'] 6 | 7 | const wrapInDiv = (svg: string, className: string = 'mathup') => 8 | `
${svg}
` 9 | 10 | const renderer: Renderer = (languages: LanguagesToParse) => { 11 | const languagesToLookFor = Array.isArray(languages) 12 | ? languages.filter(language => acceptedLanguages.includes(language)) 13 | : acceptedLanguages 14 | 15 | return async (part: Part) => { 16 | if (!isPartCode(part)) { return part } 17 | if (!languagesToLookFor.includes(part.language)) { return part } 18 | 19 | const { meta, content } = getMeta(part.content) 20 | try { 21 | return { 22 | type: 'other', 23 | content: wrapInDiv(await mathup(content, meta), meta.className), 24 | } 25 | } catch (err) { 26 | return part 27 | } 28 | } 29 | } 30 | 31 | export default renderer 32 | -------------------------------------------------------------------------------- /packages/eleventy-plugin/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/eleventy-plugin", 3 | "version": "0.1.8", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@code-blocks/eleventy-plugin", 9 | "version": "0.1.7", 10 | "license": "GPLv2", 11 | "devDependencies": { 12 | "typescript": "^3.9.7" 13 | } 14 | }, 15 | "node_modules/typescript": { 16 | "version": "3.9.7", 17 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", 18 | "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", 19 | "dev": true, 20 | "bin": { 21 | "tsc": "bin/tsc", 22 | "tsserver": "bin/tsserver" 23 | }, 24 | "engines": { 25 | "node": ">=4.2.0" 26 | } 27 | } 28 | }, 29 | "dependencies": { 30 | "typescript": { 31 | "version": "3.9.7", 32 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", 33 | "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", 34 | "dev": true 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/tables/README.md: -------------------------------------------------------------------------------- 1 | # @code-blocks/tables 2 | 3 | ## Install 4 | 5 | ```bash 6 | npm install @code-blocks/tables 7 | ``` 8 | 9 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](https://github.com/idris-maps/code-blocks). 10 | 11 | ## Usage 12 | 13 | Because creating tables in pure markdown can be painful... 14 | 15 | **language: `csv-table`** 16 | 17 | ``` 18 | Letters, Amount 19 | A,28 20 | B,55 21 | C,43 22 | D,91 23 | E,81 24 | F,53 25 | ``` 26 | 27 | | Letters | Amount | 28 | |---------|--------| 29 | | A | 28 | 30 | | B | 55 | 31 | | C | 43 | 32 | | D | 91 | 33 | | E | 81 | 34 | | F | 53 | 35 | 36 | If other than `,` set the separator in the options: 37 | 38 | ``` 39 | --- 40 | separator: \t 41 | --- 42 | Letters\tAmount 43 | A\t28 44 | B\t55 45 | C\t43 46 | D\t91 47 | E\t81 48 | F\t53 49 | ``` 50 | 51 | | Letters | Amount | 52 | |---------|--------| 53 | | A | 28 | 54 | | B | 55 | 55 | | C | 43 | 56 | | D | 91 | 57 | | E | 81 | 58 | | F | 53 | 59 | -------------------------------------------------------------------------------- /packages/rehype-transform/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/rehype-transform", 3 | "version": "0.1.10", 4 | "description": "A rehype transform to render code blocks", 5 | "author": "idris-maps", 6 | "license": "GPLv2", 7 | "main": "index.js", 8 | "types": "index.d.ts", 9 | "directories": { 10 | "lib": "lib" 11 | }, 12 | "files": [ 13 | "lib" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "scripts": { 19 | "test": "ava --verbose" 20 | }, 21 | "dependencies": { 22 | "@code-blocks/types": "^0.1.0", 23 | "hast-util-from-parse5": "^6.0.0", 24 | "hast-util-to-string": "^1.0.4", 25 | "parse5": "^6.0.1", 26 | "unist-util-visit": "^2.0.3" 27 | }, 28 | "devDependencies": { 29 | "@code-blocks/charts": "^0.1.9", 30 | "ava": "^3.10.1", 31 | "rehype-stringify": "^8.0.0", 32 | "remark-parse": "^10.0.0", 33 | "remark-rehype": "^7.0.0", 34 | "unified": "^9.1.0" 35 | }, 36 | "repository": { 37 | "type": "git", 38 | "url": "https://github.com/idris-maps/code-blocks.git" 39 | }, 40 | "homepage": "https://code-blocks.surge.sh" 41 | } 42 | -------------------------------------------------------------------------------- /packages/math/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/math", 3 | "version": "0.1.8", 4 | "description": "Create MathML from code blocks", 5 | "author": "idris-maps", 6 | "license": "GPLv2", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "directories": { 10 | "dist": "dist" 11 | }, 12 | "files": [ 13 | "dist" 14 | ], 15 | "scripts": { 16 | "test": "ava", 17 | "build": "tsc", 18 | "test:verbose": "ava --verbose" 19 | }, 20 | "dependencies": { 21 | "@code-blocks/parser": "^0.1.8", 22 | "@code-blocks/types": "^0.1.0", 23 | "mathup": "^1.0.0-beta.2" 24 | }, 25 | "ava": { 26 | "extensions": [ 27 | "ts" 28 | ], 29 | "require": [ 30 | "ts-node/register" 31 | ] 32 | }, 33 | "publishConfig": { 34 | "access": "public" 35 | }, 36 | "repository": { 37 | "type": "git", 38 | "url": "https://github.com/idris-maps/code-blocks.git" 39 | }, 40 | "homepage": "https://code-blocks.surge.sh/math", 41 | "devDependencies": { 42 | "ava": "^3.12.1", 43 | "typescript": "^4.0.2" 44 | }, 45 | "gitHead": "ab86e49901818ce60f17e37327bc1d2af377c6de" 46 | } 47 | -------------------------------------------------------------------------------- /packages/rehype-transform/lib/svg2ast.js: -------------------------------------------------------------------------------- 1 | 'use-strict' 2 | 3 | const parse5 = require('parse5') 4 | const fromParse5 = require('hast-util-from-parse5') 5 | 6 | const findChildByTag = (tag, children) => 7 | children.find(({ tagName }) => tagName === tag) 8 | 9 | const getChildrenOf = (tag, children) => { 10 | const node = findChildByTag(tag, children) 11 | return node && node.children ? node.children : [] 12 | } 13 | 14 | const getPropertiesOf = (tag, children) => { 15 | const node = findChildByTag(tag, children) 16 | return node && node.properties ? node.properties : {} 17 | } 18 | 19 | const extractDiv = page => { 20 | const rootChildren = page && page.children ? page.children : [] 21 | const inHtml = getChildrenOf('html', rootChildren) 22 | const inBody = getChildrenOf('body', inHtml) 23 | if (inBody[0].tagName === 'pre') { 24 | return { 25 | properties: {}, 26 | children: inBody, 27 | } 28 | } 29 | return { 30 | properties: getPropertiesOf('div', inBody), 31 | children: getChildrenOf('div', inBody), 32 | } 33 | } 34 | 35 | module.exports = svg => 36 | extractDiv( 37 | fromParse5( 38 | parse5.parse( 39 | svg 40 | ) 41 | ) 42 | ) -------------------------------------------------------------------------------- /packages/graphviz/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/graphviz", 3 | "version": "0.1.8", 4 | "description": "Create graphviz diagram from code blocks", 5 | "author": "idris-maps", 6 | "license": "GPLv2", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "directories": { 10 | "dist": "dist" 11 | }, 12 | "files": [ 13 | "dist" 14 | ], 15 | "scripts": { 16 | "test": "ava", 17 | "build": "tsc", 18 | "test:verbose": "ava --verbose" 19 | }, 20 | "dependencies": { 21 | "@code-blocks/parser": "^0.1.8", 22 | "@code-blocks/types": "^0.1.0", 23 | "parse5": "^6.0.1", 24 | "viz.js": "^2.1.2" 25 | }, 26 | "ava": { 27 | "extensions": [ 28 | "ts" 29 | ], 30 | "require": [ 31 | "ts-node/register" 32 | ] 33 | }, 34 | "publishConfig": { 35 | "access": "public" 36 | }, 37 | "repository": { 38 | "type": "git", 39 | "url": "https://github.com/idris-maps/code-blocks.git" 40 | }, 41 | "homepage": "https://code-blocks.surge.sh/graphviz", 42 | "devDependencies": { 43 | "@types/parse5": "^5.0.3", 44 | "@types/viz.js": "^2.1.0", 45 | "ava": "^3.11.0", 46 | "typescript": "^3.9.7" 47 | }, 48 | "gitHead": "ab86e49901818ce60f17e37327bc1d2af377c6de" 49 | } 50 | -------------------------------------------------------------------------------- /packages/parser/src/parseDsv.ts: -------------------------------------------------------------------------------- 1 | import { trim, isNil, path } from 'ramda' 2 | import { DsvDataItem } from '@code-blocks/types' 3 | 4 | const castType = (cell: string): boolean | number | string => { 5 | if (cell === 'true') { return true } 6 | if (cell === 'false') { return false } 7 | const num = Number(cell) 8 | if (!Number.isNaN(num)) { return num } 9 | return cell 10 | } 11 | 12 | const separateLine = (separator: string) => 13 | (line: string) => 14 | line 15 | .split(separator) 16 | .map(trim) 17 | 18 | export default (separator: string) => 19 | (content: string): { data: DsvDataItem[], head: string[] } => { 20 | const [head, ...body] = content.split('\n').map(separateLine(separator)) 21 | const data = body 22 | .map(line => 23 | head.reduce((r, key, i) => ({ 24 | ...r, 25 | [String(key)]: castType(line[i]), 26 | }), {}) 27 | ) 28 | .filter(d => 29 | Object.keys(d).length === head.length 30 | && Object.keys(d).every(key => !isNil(path([key], d))) 31 | ) 32 | 33 | if (data.length === 0) { 34 | throw new Error(` 35 | Could not parse as DSV with "${separator}" separator: 36 | ${content} 37 | `) 38 | } 39 | return { head, data } 40 | } 41 | -------------------------------------------------------------------------------- /site/src/music.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout.njk 3 | title: "@code-blocks/music" 4 | short: "Music" 5 | description: "Draw music sheets in markdown code blocks" 6 | tags: renderer 7 | --- 8 | 9 | ## Install 10 | 11 | ```bash 12 | npm install @code-blocks/music 13 | ``` 14 | 15 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](/). 16 | 17 | ## Usage 18 | 19 | This library uses [abc.js](https://www.abcjs.net/) under the hood. For more information about the syntax, checkout their website. 20 | 21 | **language: `music-abc`** 22 | 23 | ``` 24 | X: 1 25 | T: Cooley's 26 | M: 4/4 27 | L: 1/8 28 | K: Emin 29 | |:D2|"Em"EB{c}BA B2 EB|~B2 AB dBAG|\ 30 | "D"FDAD BDAD|FDAD dAFD| 31 | "Em"EBBA B2 EB|B2 AB defg|\ 32 | "D"afe^c dBAF|"Em"DEFD E2:| 33 | |:gf|"Em"eB B2 efge|eB B2 gedB|\ 34 | "D"A2 FA DAFA|A2 FA defg| 35 | "Em"eB B2 eBgB|eB B2 defg|\ 36 | "D"afe^c dBAF|"Em"DEFD E2:| 37 | ``` 38 | 39 | ```music-abc 40 | X: 1 41 | T: Cooley's 42 | M: 4/4 43 | L: 1/8 44 | K: Emin 45 | |:D2|"Em"EB{c}BA B2 EB|~B2 AB dBAG|\ 46 | "D"FDAD BDAD|FDAD dAFD| 47 | "Em"EBBA B2 EB|B2 AB defg|\ 48 | "D"afe^c dBAF|"Em"DEFD E2:| 49 | |:gf|"Em"eB B2 efge|eB B2 gedB|\ 50 | "D"A2 FA DAFA|A2 FA defg| 51 | "Em"eB B2 eBgB|eB B2 defg|\ 52 | "D"afe^c dBAF|"Em"DEFD E2:| 53 | ``` 54 | -------------------------------------------------------------------------------- /packages/eleventy-plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer, Part, isPartOther, PartCode } from '@code-blocks/types' 2 | import fromHtml from '@code-blocks/from-html' 3 | 4 | const loopRenderers = (i: number, renderers: Renderer[], part: Part, cb: (part: Part) => void) => { 5 | if (isPartOther(part)) { return cb(part) } 6 | const renderer = renderers[i] 7 | if (i === renderers.length) { return cb(part) } 8 | if (!renderer) { return cb(part) } 9 | renderer('*')(part) 10 | .then(newPart => loopRenderers(i + 1, renderers, newPart, cb)) 11 | .catch(err => { throw err }) 12 | } 13 | 14 | const renderPart = (renderers: Renderer[]) => 15 | async (part: Part): Promise => 16 | new Promise((resolve, reject) => { 17 | try { 18 | loopRenderers(0, renderers, part, renderedPart => resolve(renderedPart)) 19 | } catch (err) { 20 | throw err 21 | } 22 | }) 23 | 24 | const stringifyUnrenderedCodeBlock = ({ language, content }: PartCode) => 25 | `
${content}
` 26 | 27 | const stringifyPart = (part: Part) => 28 | isPartOther(part) 29 | ? part.content 30 | : stringifyUnrenderedCodeBlock(part) 31 | 32 | export default (renderers: Renderer[]) => 33 | async (content: string) => { 34 | const parts = fromHtml(content, '*') 35 | return (await Promise.all(parts.map(renderPart(renderers)))) 36 | .map(stringifyPart) 37 | .join('\n') 38 | } 39 | -------------------------------------------------------------------------------- /packages/from-html/test/index.spec.ts: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import { Part, isPartCode, isPartOther } from '@code-blocks/types' 3 | import { path } from 'ramda' 4 | import fromHTML from '../src/index' 5 | 6 | const inside = `inside code block` 7 | 8 | const tagsInOneLine = ` 9 |

Before

10 |

11 | ${inside}
12 | 
13 |

After

14 | ` 15 | 16 | const allInOneLine = `

Before

${inside}

After

` 17 | 18 | const onMultipleLines = ` 19 |

Before

20 |
21 |   
22 |     ${inside}
23 |   
24 | 
25 |

After

26 | ` 27 | 28 | const getFirstCodeBlock = (parts: Part[]) => 29 | path(['content'], parts.find(isPartCode)) 30 | 31 | const otherLanguage = ` 32 |

Before

33 |

34 | ${inside}
35 | 
36 |

After

37 | ` 38 | 39 | test('from-html', t => { 40 | t.is(getFirstCodeBlock(fromHTML(tagsInOneLine, ['test'])), inside) 41 | t.is(getFirstCodeBlock(fromHTML(allInOneLine, ['test'])), inside) 42 | t.is(getFirstCodeBlock(fromHTML(onMultipleLines, ['test'])), inside) 43 | 44 | t.true( 45 | fromHTML(otherLanguage, ['test']).every(isPartOther), 46 | 'should ignore not defined languages' 47 | ) 48 | t.is( 49 | getFirstCodeBlock(fromHTML(otherLanguage, '*')), 50 | inside, 51 | 'should parse if languages set to all' 52 | ) 53 | }) -------------------------------------------------------------------------------- /packages/graphviz/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer, LanguagesToParse, Part, isPartCode } from '@code-blocks/types' 2 | import { getMeta } from '@code-blocks/parser' 3 | import render from './render' 4 | 5 | export const acceptedLanguages = ['graphviz'] 6 | 7 | const wrapInDiv = (svg: string, className: string = 'diagram') => 8 | `
${svg}
` 9 | 10 | const replace = (toRemove: string, toAdd: string) => 11 | (string: string) => 12 | string.split(toRemove).join(toAdd) 13 | 14 | const replaceQuotes = replace('"', '"') 15 | const replaceGt = replace('>', '>') 16 | const replaceLt = replace('<', '<') 17 | 18 | const fixContent = (content: string) => 19 | replaceQuotes( 20 | replaceGt( 21 | replaceLt(content) 22 | ) 23 | ) 24 | 25 | const renderer: Renderer = (languages: LanguagesToParse) => { 26 | const languagesToLookFor = Array.isArray(languages) 27 | ? languages.filter(language => acceptedLanguages.includes(language)) 28 | : acceptedLanguages 29 | 30 | return async (part: Part) => { 31 | if (!isPartCode(part)) { return part } 32 | if (!languagesToLookFor.includes(part.language)) { return part } 33 | 34 | const { meta, content } = getMeta(part.content) 35 | try { 36 | return { 37 | type: 'other', 38 | content: wrapInDiv(await render(fixContent(content), meta), meta.className), 39 | } 40 | } catch (err) { 41 | return part 42 | } 43 | } 44 | } 45 | 46 | export default renderer 47 | -------------------------------------------------------------------------------- /packages/rehype-transform/test/index.spec.js: -------------------------------------------------------------------------------- 1 | const test = require('ava') 2 | const unified = require('unified') 3 | const markdown = require('remark-parse') 4 | const remark2rehype = require('remark-rehype') 5 | const html = require('rehype-stringify') 6 | const plugin = require('../index') 7 | const charts = require('@code-blocks/charts') 8 | 9 | const md = ` 10 | \`\`\`pie-chart 11 | Fruit,Amount 12 | Banana,2 13 | Apple,1 14 | \`\`\` 15 | ` 16 | 17 | const runWithOption = options => { 18 | const process = md => 19 | new Promise((resolve, reject) => 20 | unified() 21 | .use(markdown) 22 | .use(remark2rehype) 23 | .use(plugin, options) 24 | .use(html) 25 | .process(md, (err, file) => err ? reject(err) : resolve(file.contents)) 26 | ) 27 | 28 | return process(md) 29 | } 30 | 31 | test('without options', async t => { 32 | try { 33 | await runWithOption() 34 | t.fail('should throw error') 35 | } catch (err) { 36 | t.pass('should throw error') 37 | } 38 | }) 39 | 40 | test('with an invalid renderer', async t => { 41 | try { 42 | await runWithOption(['Not a renderer']) 43 | t.fail('should throw error') 44 | } catch (err) { 45 | t.pass('should throw error') 46 | } 47 | }) 48 | 49 | test('with a renderer', async t => { 50 | try { 51 | const result = await runWithOption([charts]) 52 | t.true(result.includes(' 11 | Object.keys(d).includes('nodeName') 12 | 13 | const findSvg = (node: Node) => 14 | (node.childNodes || []).find((d: Node) => d.nodeName === 'svg') 15 | 16 | const removeTextNodes = (node: Node): Node => { 17 | if (node.childNodes && Array.isArray(node.childNodes)) { 18 | return { 19 | ...node, 20 | childNodes: node.childNodes.filter(d => d.value !== '\n').map(removeTextNodes) 21 | } 22 | } 23 | return node 24 | } 25 | 26 | const removeSize = (node: Node): Node => { 27 | if (node.attrs && Array.isArray(node.attrs)) { 28 | return { 29 | ...node, 30 | attrs: node.attrs.filter((d: any) => !['width', 'height'].includes(d.name)) 31 | } 32 | } 33 | return node 34 | } 35 | 36 | const addParent = (node: Node) => ({ 37 | nodeName: 'parent', 38 | childNodes: [node], 39 | }) 40 | 41 | const fixSvg = (node: Node): string => 42 | // @ts-ignore 43 | serialize( 44 | addParent( 45 | removeTextNodes( 46 | removeSize( 47 | findSvg(node) 48 | ) 49 | ) 50 | ) 51 | ) 52 | 53 | export default async (data: string, options?: any) => { 54 | const viz = new Viz({ Module, render }) 55 | const svg = await viz.renderString(data, options) 56 | const node = parseFragment(svg) 57 | if (isNode(node)) { 58 | return fixSvg(node) 59 | } 60 | return svg 61 | } 62 | -------------------------------------------------------------------------------- /packages/from-html/src/index.ts: -------------------------------------------------------------------------------- 1 | import { flatten } from 'ramda' 2 | import { Part, parseAllLanguages, LanguagesToParse } from '@code-blocks/types' 3 | 4 | interface PreSplit { 5 | isPre: boolean 6 | content: string 7 | } 8 | 9 | const splitPre = (html: string): PreSplit[] => 10 | flatten( 11 | html.split('
').map((d, i) => {
12 |       if (i === 0) { return [{ isPre: false, content: d }] }
13 |       const [before, after] = d.split('
') 14 | return [ 15 | { isPre: true, content: before }, 16 | { isPre: false, content: after }, 17 | ] 18 | }) 19 | ) 20 | 21 | const hasLanguage = (d: string) => d.includes('class="language-') 22 | 23 | const parsePreSplit = (languages: LanguagesToParse) => 24 | ({ isPre, content }: PreSplit): Part => { 25 | if (!isPre) { 26 | return { 27 | type: 'other', 28 | content, 29 | } 30 | } 31 | const [_, noCode] = content.split('') 33 | const code = rest.join('>').split('')[0] 34 | const language = hasLanguage(codeAttributes) 35 | ? codeAttributes.split('class="language-')[1].split('"')[0] 36 | : '' 37 | if (parseAllLanguages(languages) || languages.includes(language)) { 38 | return { 39 | type: 'code', 40 | language, 41 | content: code.trim(), 42 | } 43 | } 44 | return { 45 | type: 'other', 46 | content: `
${content}
`, 47 | } 48 | } 49 | 50 | export default (html: string, languages: LanguagesToParse) => { 51 | return splitPre(html).map(parsePreSplit(languages)) 52 | } 53 | -------------------------------------------------------------------------------- /packages/prism/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer, LanguagesToParse, Part, isPartCode } from '@code-blocks/types' 2 | import { registered, highlight } from 'refractor' 3 | import languages from './languages' 4 | import rehype from 'rehype' 5 | 6 | export const acceptedLanguages = languages 7 | 8 | const replace = (toRemove: string, toAdd: string) => 9 | (string: string) => 10 | string.split(toRemove).join(toAdd) 11 | 12 | const replaceQuotes = replace('"', '"') 13 | const replaceGt = replace('>', '>') 14 | const replaceLt = replace('<', '<') 15 | const replaceAmp = replace('&', '&') 16 | 17 | const fixContent = (content: string) => 18 | replaceQuotes( 19 | replaceGt( 20 | replaceLt( 21 | replaceAmp(content) 22 | ) 23 | ) 24 | ) 25 | 26 | const renderer: Renderer = (languages: LanguagesToParse = '*') => { 27 | 28 | return async (part: Part) => { 29 | 30 | if (!isPartCode(part)) { return part } 31 | 32 | const { language, content } = part 33 | 34 | if (!registered(language)) { return part } 35 | 36 | try { 37 | const nodes = highlight(fixContent(content), language) 38 | const innerHTML = rehype() 39 | .stringify({type: 'root', children: nodes}) 40 | .toString() 41 | return { 42 | type: 'other', 43 | content: [ 44 | `
`,
45 |           ``,
46 |           innerHTML,
47 |           ``,
48 |           `
`, 49 | ].join(''), 50 | } 51 | } catch (err) { 52 | return part 53 | } 54 | } 55 | } 56 | 57 | export default renderer 58 | -------------------------------------------------------------------------------- /packages/tables/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer, Part, LanguagesToParse, isPartCode } from '@code-blocks/types' 2 | import { getMeta, parseDsv } from '@code-blocks/parser' 3 | import createXml from 'xml-string' 4 | 5 | const renderTable = (separator: string) => 6 | (code: string) => { 7 | const { meta, content } = getMeta(code) 8 | const { head, data } = parseDsv(meta.separator || separator)(content) 9 | 10 | const div = createXml.create('div').attr({ 'class': meta.className || 'table-container' }) 11 | const table = div.child('table') 12 | 13 | const thead = table.child('thead').child('tr') 14 | head.forEach(headLabel => { thead.child('th').data(headLabel) }) 15 | 16 | const tbody = table.child('tbody') 17 | data.forEach(row => { 18 | const tr = tbody.child('tr') 19 | head.forEach(key => { 20 | tr.child('td').data(String(row[key])) 21 | }) 22 | }) 23 | 24 | return div.outer() 25 | } 26 | 27 | export const acceptedLanguages = [ 28 | 'csv-table', 29 | ] 30 | 31 | const renderer: Renderer = (languages: LanguagesToParse) => { 32 | const languagesToLookFor = Array.isArray(languages) 33 | ? languages.filter(language => acceptedLanguages.includes(language)) 34 | : acceptedLanguages 35 | 36 | return async (part: Part) => { 37 | 38 | if (!isPartCode(part)) { return part } 39 | if (!languagesToLookFor.includes(part.language)) { return part } 40 | 41 | try { 42 | const content = renderTable(',')(part.content) 43 | return { type: 'other', content } 44 | } catch (err) { 45 | return part 46 | } 47 | } 48 | } 49 | 50 | export default renderer 51 | -------------------------------------------------------------------------------- /packages/rehype-transform/README.md: -------------------------------------------------------------------------------- 1 | # @code-blocks/rehype-transform 2 | 3 | A rehype transform to render code blocks 4 | 5 | ## Usage 6 | 7 | Install the transform: 8 | 9 | ```bash 10 | npm install @code-blocks/rehype-transform --save 11 | ``` 12 | 13 | Install the renderers you need, for example: 14 | 15 | ```bash 16 | npm install @code-blocks/charts --save 17 | ``` 18 | 19 | An use it: 20 | 21 | ```js 22 | const unified = require('unified') 23 | const stream = require('unified-stream') 24 | const markdown = require('remark-parse') 25 | const remark2rehype = require('remark-rehype') 26 | const html = require('rehype-stringify') 27 | 28 | // the rehype transform 29 | const codeblocks = require('@code-blocks/rehype-transform') 30 | 31 | // some renderers 32 | const charts = require('@code-blocks/charts') 33 | const graphviz = require('@code-blocks/graphviz') 34 | 35 | const processor = unified() 36 | .use(markdown) 37 | .use(remark2rehype) 38 | // add the transform and the renderers in an array as options 39 | .use(codeblocks, [charts, graphviz]) 40 | .use(html) 41 | 42 | process.stdin.pipe(stream(processor)).pipe(process.stdout) 43 | ``` 44 | 45 | Available renderers: 46 | 47 | * [@code-blocks/charts](https://github.com/idris-maps/code-blocks/tree/master/packages/charts) 48 | * [@code-blocks/graphviz](https://github.com/idris-maps/code-blocks/tree/master/packages/graphviz) 49 | * [@code-blocks/math](https://github.com/idris-maps/code-blocks/tree/master/packages/math) 50 | * [@code-blocks/music](https://github.com/idris-maps/code-blocks/tree/master/packages/music) 51 | * [@code-blocks/tables](https://github.com/idris-maps/code-blocks/tree/master/packages/tables) 52 | * [@code-blocks/prism](https://github.com/idris-maps/code-blocks/tree/master/packages/prism) -------------------------------------------------------------------------------- /packages/eleventy-plugin/README.md: -------------------------------------------------------------------------------- 1 | # @code-blocks/eleventy-plugin 2 | 3 | An eleventy plugin to parse code blocks 4 | 5 | ## Usage 6 | 7 | Install the plugin: 8 | 9 | ```bash 10 | npm install @code-blocks/eleventy-plugin --save 11 | ``` 12 | 13 | Install the renderers you need, for example: 14 | 15 | ```bash 16 | npm install @code-blocks/music --save 17 | ``` 18 | 19 | In the `.eleventy.js` configuration file: 20 | 21 | ```js 22 | // the plugin 23 | const codeblocks = require('@code-blocks/eleventy-plugin') 24 | 25 | // some renderers 26 | const math = require('@code-blocks/math') 27 | const music = require('@code-blocks/music') 28 | 29 | module.exports = function(eleventyConfig) { 30 | // pass the renderers to the plugin 31 | eleventyConfig.addPlugin(codeblocks([ 32 | math, 33 | music, 34 | ])) 35 | } 36 | ``` 37 | 38 | Available renderers: 39 | 40 | * [@code-blocks/charts](https://github.com/idris-maps/code-blocks/tree/master/packages/charts) 41 | * [@code-blocks/graphviz](https://github.com/idris-maps/code-blocks/tree/master/packages/graphviz) 42 | * [@code-blocks/math](https://github.com/idris-maps/code-blocks/tree/master/packages/math) 43 | * [@code-blocks/music](https://github.com/idris-maps/code-blocks/tree/master/packages/music) 44 | * [@code-blocks/tables](https://github.com/idris-maps/code-blocks/tree/master/packages/tables) 45 | * [@code-blocks/prism](https://github.com/idris-maps/code-blocks/tree/master/packages/prism) 46 | 47 | There is already an official syntax [highlighting plugin](https://www.11ty.dev/docs/plugins/syntaxhighlight/) for eleventy. If you are just going to highlight code blocks, use that instead. However, if you are using other `@code-blocks` renderers, it will break the official plugin. That is why there is a `@code-blocks/prism` renderer. 48 | -------------------------------------------------------------------------------- /packages/charts/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer, LanguagesToParse, Part, isPartCode, DsvDataItem, Meta } from '@code-blocks/types' 2 | import { getMeta, parseDsv, parseJson } from '@code-blocks/parser' 3 | import areaChart from './area' 4 | import barChart from './bar' 5 | import lineChart from './line' 6 | import multilineChart from './multiline' 7 | import pieChart from './pie' 8 | import { renderVega, renderVegalite } from './vega' 9 | 10 | const wrapInDiv = (svg: string, className: string = 'chart') => 11 | `
${svg}
` 12 | 13 | type DsvRenderer = (dsv: { head: string[], data: DsvDataItem[] }, meta: Meta) => Promise 14 | 15 | const renderDsvChart = (dsvRenderer: DsvRenderer) => (content: string, meta: Meta = {}) => { 16 | return dsvRenderer(parseDsv(',')(content), meta) 17 | } 18 | 19 | const chartRenderers = [ 20 | { language: 'area-chart', render: renderDsvChart(areaChart) }, 21 | { language: 'bar-chart', render: renderDsvChart(barChart) }, 22 | { language: 'line-chart', render: renderDsvChart(lineChart) }, 23 | { language: 'multiline-chart', render: renderDsvChart(multilineChart) }, 24 | { language: 'pie-chart', render: renderDsvChart(pieChart) }, 25 | { language: 'vega', render: (content: string) => renderVega(parseJson(content)) }, 26 | { language: 'vegalite', render: (content: string) => renderVegalite(parseJson(content)) }, 27 | ] 28 | 29 | export const acceptedLanguages = chartRenderers.map(d => d.language) 30 | 31 | const renderer: Renderer = (languages: LanguagesToParse = '*') => { 32 | 33 | const languagesToLookFor = Array.isArray(languages) 34 | ? languages.filter(language => acceptedLanguages.includes(language)) 35 | : acceptedLanguages 36 | 37 | return async (part: Part) => { 38 | 39 | if (!isPartCode(part)) { return part } 40 | if (!languagesToLookFor.includes(part.language)) { return part } 41 | 42 | const func = chartRenderers.find(({ language }) => language === part.language) 43 | if (!func) { return part } 44 | const { meta, content } = getMeta(part.content) 45 | return { type: 'other', content: wrapInDiv(await func.render(content, meta), meta.className) } 46 | } 47 | } 48 | 49 | export default renderer 50 | -------------------------------------------------------------------------------- /packages/from-html/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/from-html", 3 | "version": "0.1.8", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@code-blocks/from-html", 9 | "version": "0.1.0", 10 | "license": "GPLv2", 11 | "dependencies": { 12 | "ramda": "^0.27.0" 13 | }, 14 | "devDependencies": { 15 | "@types/ramda": "^0.27.6" 16 | } 17 | }, 18 | "node_modules/@types/ramda": { 19 | "version": "0.27.6", 20 | "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.27.6.tgz", 21 | "integrity": "sha512-ephagb0ZIAJSoS5I/qMS4Mqo1b/Nd50pWM+o1QO/dz8NF//GsCGPTLDVRqgXlVncy74KShfHzE5rPZXTeek4PA==", 22 | "dev": true, 23 | "dependencies": { 24 | "ts-toolbelt": "^6.3.3" 25 | } 26 | }, 27 | "node_modules/ramda": { 28 | "version": "0.27.0", 29 | "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.0.tgz", 30 | "integrity": "sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA==" 31 | }, 32 | "node_modules/ts-toolbelt": { 33 | "version": "6.9.4", 34 | "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.9.4.tgz", 35 | "integrity": "sha512-muRZZqfOTOVvLk5cdnp7YWm6xX+kD/WL2cS/L4zximBRcbQSuMoTbQQ2ZZBVMs1gB0EZw1qThP+HrIQB35OmEw==", 36 | "dev": true 37 | } 38 | }, 39 | "dependencies": { 40 | "@types/ramda": { 41 | "version": "0.27.6", 42 | "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.27.6.tgz", 43 | "integrity": "sha512-ephagb0ZIAJSoS5I/qMS4Mqo1b/Nd50pWM+o1QO/dz8NF//GsCGPTLDVRqgXlVncy74KShfHzE5rPZXTeek4PA==", 44 | "dev": true, 45 | "requires": { 46 | "ts-toolbelt": "^6.3.3" 47 | } 48 | }, 49 | "ramda": { 50 | "version": "0.27.0", 51 | "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.0.tgz", 52 | "integrity": "sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA==" 53 | }, 54 | "ts-toolbelt": { 55 | "version": "6.9.4", 56 | "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.9.4.tgz", 57 | "integrity": "sha512-muRZZqfOTOVvLk5cdnp7YWm6xX+kD/WL2cS/L4zximBRcbQSuMoTbQQ2ZZBVMs1gB0EZw1qThP+HrIQB35OmEw==", 58 | "dev": true 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/charts/test/charts.spec.ts: -------------------------------------------------------------------------------- 1 | import test, { Implementation } from 'ava' 2 | import areaChart from '../src/area' 3 | import barChart from '../src/bar' 4 | import lineChart from '../src/line' 5 | import pieChart from '../src/pie' 6 | import multiLineChart from '../src/multiline' 7 | import { Meta, DsvDataItem } from '@code-blocks/types' 8 | import { writeFile } from 'fs' 9 | import { promisify } from 'util' 10 | import { resolve } from 'path' 11 | 12 | const saveSvg = (svg: string, fileName: string) => 13 | promisify(writeFile)(resolve(__dirname, 'svgs', `${fileName}.svg`), svg, 'utf-8') 14 | 15 | const getTemporalData = () => 16 | Array.from(Array(5)) 17 | .map((_, i) => ({ 18 | 'Day': `2020-0${i}-01`, 19 | 'Value': Math.round(Math.random() * 20), 20 | })) 21 | 22 | const head = ['Fruit', 'Amount'] 23 | const data: DsvDataItem[] = [ 24 | { 'Fruit': 'Apple', 'Amount': 1 }, 25 | { 'Fruit': 'Banana', 'Amount': 2 }, 26 | ] 27 | 28 | const temporalHead = ['Day', 'Value'] 29 | const temporalData = getTemporalData() 30 | 31 | const multilineHead = ['Day', 'Value', 'Stock'] 32 | const multilineData = [ 33 | ...getTemporalData().map(d => ({ ...d, 'Stock': 'AAA' })), 34 | ...getTemporalData().map(d => ({ ...d, 'Stock': 'BBB' })), 35 | ] 36 | 37 | const isSvg = (d: any) => 38 | typeof d === 'string' && d.startsWith(') => void, 42 | fileName: string, 43 | data: DsvDataItem[], 44 | head: string[], 45 | func: ({ head, data }: { head: string[], data: DsvDataItem[] }, meta?: Meta) => Promise, 46 | meta: Meta = {}, 47 | ) => { 48 | test(`charts ${fileName}`, async t => { 49 | const result = await func({ data, head }, meta) 50 | await saveSvg(result, fileName) 51 | t.true(isSvg(result), fileName) 52 | }) 53 | } 54 | 55 | check(test, 'area', data, head, areaChart) 56 | check(test, 'area-temp', temporalData, temporalHead, areaChart, { temporal: true }) 57 | check(test, 'bar', data, head, barChart) 58 | check(test, 'line', data, head, lineChart) 59 | check(test, 'line-temp', temporalData, temporalHead, lineChart, { temporal: true }) 60 | check(test, 'pie', data, head, pieChart) 61 | check(test, 'multiline', multilineData, multilineHead, multiLineChart, { temporal: true }) 62 | -------------------------------------------------------------------------------- /packages/rehype-transform/index.js: -------------------------------------------------------------------------------- 1 | const visit = require('unist-util-visit') 2 | const nodeToString = require('hast-util-to-string') 3 | const svg2ast = require('./lib/svg2ast') 4 | 5 | module.exports = (renderers) => { 6 | 7 | validateRenderers(renderers) 8 | 9 | return async (tree) => { 10 | let promises = [] 11 | visit(tree, 'element', visitor) 12 | await Promise.all(promises) 13 | return null 14 | 15 | function visitor(node, index, parent) { 16 | if (!parent || parent.tagName !== 'pre' || node.tagName !== 'code') { 17 | return 18 | } 19 | 20 | const lang = getLanguage(node) 21 | const renderer = getRenderer(renderers, lang) 22 | if (!renderer) { 23 | return 24 | } 25 | 26 | try { 27 | const p = renderer({ 28 | type: 'code', 29 | language: lang, 30 | content: nodeToString(node), 31 | }) 32 | .then(({ content }) => svg2ast(content)) 33 | .then(({ properties, children }) => { 34 | parent.tagName = 'div' 35 | parent.properties = properties 36 | parent.children = children 37 | }) 38 | promises.push(p) 39 | return true 40 | } catch (err) { 41 | return 42 | } 43 | } 44 | } 45 | } 46 | 47 | function getLanguage(node) { 48 | const className = node.properties.className || [] 49 | 50 | for (const classListItem of className) { 51 | if (classListItem.slice(0, 9) === 'language-') { 52 | return classListItem.slice(9).toLowerCase() 53 | } 54 | } 55 | 56 | return null 57 | } 58 | 59 | function validateRenderers(renderers) { 60 | if(!Array.isArray(renderers)) { 61 | throw new Error(` 62 | codeblocks must have an array of renderers 63 | 64 | https://github.com/idris-maps/code-blocks/tree/master/packages/rehype-transform 65 | `) 66 | } 67 | 68 | for (let i = 0; i < renderers.length; i++) { 69 | const d = renderers[i] 70 | if (!d.default || !d.acceptedLanguages || !Array.isArray(d.acceptedLanguages)) { 71 | throw new Error(` 72 | renderer[${i}] is invalid 73 | `) 74 | } 75 | } 76 | } 77 | 78 | function getRenderer(renderers, lang) { 79 | const hasLanguageArray = d => 80 | d.acceptedLanguages 81 | && Array.isArray(d.acceptedLanguages) 82 | 83 | const found = renderers.find(d => hasLanguageArray(d) && d.acceptedLanguages.includes(lang)) 84 | 85 | return found 86 | ? found.default([lang]) 87 | : undefined 88 | } -------------------------------------------------------------------------------- /site/src/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout.njk 3 | title: "@code-blocks" 4 | description: "Use markdown code blocks to render, charts, diagrams, math, music sheets and HTML tables" 5 | --- 6 | 7 | Use markdown code blocks to render: 8 | 9 | * [Charts](/charts) 10 | * [Graphviz diagrams](/graphviz) 11 | * [MathML](/math) 12 | * [Music sheets](/music) 13 | * [HTML tables](/tables) 14 | 15 | and [highlight code](/prism). 16 | 17 | `@code-blocks` can be used either as a [rehype](https://github.com/rehypejs/rehype) transform or as an [eleventy](https://www.11ty.dev/) plugin. 18 | 19 | ## Example 20 | 21 | A code block with `music-abc` as language and the following content: 22 | 23 | ``` 24 | DDAA|BBA2| 25 | ``` 26 | 27 | will be rendered as: 28 | 29 | ```music-abc 30 | DDAA|BBA2| 31 | ``` 32 | 33 | ## Usage with [rehype](https://github.com/rehypejs/rehype) 34 | 35 | Install the transform: 36 | 37 | ```bash 38 | npm install @code-blocks/rehype-transform --save 39 | ``` 40 | 41 | Install the renderers you need, for example: 42 | 43 | ```bash 44 | npm install @code-blocks/charts --save 45 | ``` 46 | 47 | An use it: 48 | 49 | ```js 50 | const unified = require('unified') 51 | const stream = require('unified-stream') 52 | const markdown = require('remark-parse') 53 | const remark2rehype = require('remark-rehype') 54 | const html = require('rehype-stringify') 55 | 56 | // the rehype transform 57 | const codeblocks = require('@code-blocks/rehype-transform') 58 | 59 | // some renderers 60 | const charts = require('@code-blocks/charts') 61 | const graphviz = require('@code-blocks/graphviz') 62 | 63 | const processor = unified() 64 | .use(markdown) 65 | .use(remark2rehype) 66 | // add the transform and the renderers in an array as options 67 | .use(codeblocks, [charts, graphviz]) 68 | .use(html) 69 | 70 | process.stdin.pipe(stream(processor)).pipe(process.stdout) 71 | ``` 72 | 73 | ## Usage with [eleventy](https://www.11ty.dev/) 74 | 75 | Install the plugin: 76 | 77 | ```bash 78 | npm install @code-blocks/eleventy-plugin --save 79 | ``` 80 | 81 | Install the renderers you need, for example: 82 | 83 | ```bash 84 | npm install @code-blocks/music --save 85 | ``` 86 | 87 | 88 | In the `.eleventy.js` configuration file: 89 | 90 | ```js 91 | // the plugin 92 | const codeblocks = require('@code-blocks/eleventy-plugin') 93 | 94 | // some renderers 95 | const math = require('@code-blocks/math') 96 | const music = require('@code-blocks/music') 97 | 98 | module.exports = function(eleventyConfig) { 99 | // pass the renderers to the plugin 100 | eleventyConfig.addPlugin(codeblocks([ 101 | math, 102 | music, 103 | ])) 104 | } 105 | ``` 106 | -------------------------------------------------------------------------------- /site/src/_includes/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --bg: #333; 3 | --bg-dark: #272822; 4 | --main: white; 5 | --primary: #a6e22e; 6 | --primary-dark: #67852d; 7 | --border: rgb(126, 126, 126); 8 | } 9 | 10 | html, body { 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; 17 | font-size: 25px; 18 | background-color: var(--bg); 19 | color: var(--main) 20 | } 21 | 22 | @media (max-width: 800px) { body { font-size: 20px; } } 23 | @media (max-width: 450px) { body { font-size: 16px; } } 24 | @media (max-width: 350px) { body { font-size: 14px; } } 25 | 26 | header { display: flex; background-color: var(--bg-dark); margin-bottom: 3em; } 27 | header a { text-decoration: none; } 28 | header svg { height: 1em; } 29 | header .ticks { fill: var(--primary) } 30 | header .ticks-background { fill: var(--primary-dark) } 31 | @media (max-width: 600px) { 32 | header h1 span { font-size: 0.7em; } 33 | } 34 | @media (max-width: 400px) { 35 | header h1 span { font-size: 0.6em; } 36 | } 37 | 38 | footer { background-color: var(--bg-dark); padding: 1em; } 39 | footer .current a { color: var(--main); text-decoration: none; } 40 | footer ul { list-style-type: none; } 41 | footer .links { width: 100%; text-align: center; } 42 | footer .links svg { height: 2em; margin-top: 2em; } 43 | @media (min-width: 1000px) { 44 | footer ul { display: flex; justify-content: space-evenly; } 45 | } 46 | 47 | main { 48 | width: 90%; 49 | max-width: 1200px; 50 | margin: auto; 51 | margin-bottom: 3em; 52 | } 53 | 54 | h2 { 55 | margin-top: 3em; 56 | margin-bottom: 1em; 57 | } 58 | 59 | p code, 60 | li code { 61 | background: var(--bg-dark); 62 | color: var(--primary); 63 | padding: .2em; 64 | border-radius: .5em; 65 | font-size: .7em; 66 | } 67 | 68 | pre { 69 | border: 1px solid var(--border); 70 | } 71 | 72 | a { 73 | color: var(--primary); 74 | text-decoration-style: dotted; 75 | text-decoration-thickness: 0.05em; 76 | } 77 | 78 | table { 79 | border-collapse: collapse; 80 | width: 100%; 81 | } 82 | 83 | td, th { 84 | border: 1px solid var(--border); 85 | padding: 0.5rem; 86 | text-align: left; 87 | } 88 | 89 | tbody tr:hover { 90 | background-color: var(--primary); 91 | color: var(--bg); 92 | } 93 | 94 | .chart { 95 | background: var(--main); 96 | max-width: 1000px; 97 | margin: auto; 98 | } 99 | 100 | .music-sheet { 101 | background-color: var(--main); 102 | } 103 | 104 | .graphviz-example-1 { 105 | margin: auto; 106 | max-width: 150px; 107 | } 108 | 109 | .mathup { 110 | text-align: center; 111 | } 112 | -------------------------------------------------------------------------------- /site/src/_includes/prism.css: -------------------------------------------------------------------------------- 1 | /** 2 | * okaidia theme for JavaScript, CSS and HTML 3 | * Loosely based on Monokai textmate theme by http://www.monokai.nl/ 4 | * @author ocodia 5 | */ 6 | 7 | pre { 8 | background: #272822; 9 | padding: 0.8em; 10 | border-radius: 0.5em; 11 | font-size: 0.8em; 12 | overflow-x: auto; 13 | } 14 | 15 | code { 16 | color: inherit; 17 | font-size: 0.7em; 18 | background: #f0f0f0; 19 | padding: 0.2em; 20 | border-radius: 0.2em; 21 | } 22 | 23 | code[class*="language-"], 24 | pre[class*="language-"] { 25 | color: #f8f8f2; 26 | background: #272822; 27 | text-shadow: 0 1px rgba(0, 0, 0, 0.3); 28 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 29 | font-size: 1em; 30 | text-align: left; 31 | white-space: pre; 32 | word-spacing: normal; 33 | word-break: normal; 34 | word-wrap: normal; 35 | line-height: 1.5; 36 | 37 | -moz-tab-size: 4; 38 | -o-tab-size: 4; 39 | tab-size: 4; 40 | 41 | -webkit-hyphens: none; 42 | -moz-hyphens: none; 43 | -ms-hyphens: none; 44 | hyphens: none; 45 | } 46 | 47 | /* Code blocks */ 48 | pre[class*="language-"] { 49 | padding: 1em; 50 | margin: .5em 0; 51 | overflow: auto; 52 | border-radius: 0.3em; 53 | } 54 | 55 | :not(pre) > code[class*="language-"], 56 | pre[class*="language-"] { 57 | background: #272822; 58 | } 59 | 60 | /* Inline code */ 61 | :not(pre) > code[class*="language-"] { 62 | padding: .1em; 63 | border-radius: .3em; 64 | white-space: normal; 65 | } 66 | 67 | .token.comment, 68 | .token.prolog, 69 | .token.doctype, 70 | .token.cdata { 71 | color: slategray; 72 | } 73 | 74 | .token.punctuation { 75 | color: #f8f8f2; 76 | } 77 | 78 | .namespace { 79 | opacity: .7; 80 | } 81 | 82 | .token.property, 83 | .token.tag, 84 | .token.constant, 85 | .token.symbol, 86 | .token.deleted { 87 | color: #f92672; 88 | } 89 | 90 | .token.boolean, 91 | .token.number { 92 | color: #ae81ff; 93 | } 94 | 95 | .token.selector, 96 | .token.attr-name, 97 | .token.string, 98 | .token.char, 99 | .token.builtin, 100 | .token.inserted { 101 | color: #a6e22e; 102 | } 103 | 104 | .token.operator, 105 | .token.entity, 106 | .token.url, 107 | .language-css .token.string, 108 | .style .token.string, 109 | .token.variable { 110 | color: #f8f8f2; 111 | } 112 | 113 | .token.atrule, 114 | .token.attr-value, 115 | .token.function, 116 | .token.class-name { 117 | color: #e6db74; 118 | } 119 | 120 | .token.keyword { 121 | color: #66d9ef; 122 | } 123 | 124 | .token.regex, 125 | .token.important { 126 | color: #fd971f; 127 | } 128 | 129 | .token.important, 130 | .token.bold { 131 | font-weight: bold; 132 | } 133 | .token.italic { 134 | font-style: italic; 135 | } 136 | 137 | .token.entity { 138 | cursor: help; 139 | } 140 | -------------------------------------------------------------------------------- /packages/prism/src/languages.ts: -------------------------------------------------------------------------------- 1 | 2 | const languages: string[] = ["plain","plaintext","text","txt","markup","html","mathml","svg","xml","ssml","atom","rss","css","clike","javascript","js","abap","abnf","actionscript","ada","agda","al","antlr4","g4","apacheconf","sql","apex","apl","applescript","aql","c","cpp","arduino","arff","asciidoc","adoc","asm6502","csharp","cs","dotnet","aspnet","autohotkey","autoit","bash","shell","basic","batch","bbcode","shortcode","birb","bison","bnf","rbnf","brainfuck","brightscript","bro","bsl","oscript","cfscript","cfc","chaiscript","cil","clojure","cmake","cobol","coffeescript","coffee","concurnas","conc","coq","ruby","rb","crystal","csp","csv","cypher","d","dart","dataweave","dax","dhall","diff","markup-templating","django","jinja2","dns-zone-file","dns-zone","docker","dockerfile","dot","gv","ebnf","editorconfig","eiffel","ejs","eta","elixir","elm","erb","erlang","lua","etlua","excel-formula","xls","xlsx","factor","false","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","gamemakerlanguage","go","graphql","groovy","haml","handlebars","hbs","haskell","hs","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","icu-message-format","idris","idr","iecst","ignore","gitignore","hgignore","npmignore","inform7","ini","io","j","java","javadoclike","javadoc","javastacktrace","jexl","jolie","jq","typescript","ts","jsdoc","json","webmanifest","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","kt","kts","kumir","kum","latex","tex","context","php","latte","less","scheme","lilypond","ly","liquid","lisp","elisp","emacs","emacs-lisp","livescript","llvm","log","lolcode","makefile","markdown","md","matlab","mel","mizar","mongodb","monkey","moonscript","moon","n1ql","n4js","n4jsd","nand2tetris-hdl","naniscript","nani","nasm","neon","nevod","nginx","nim","nix","nsis","objectivec","objc","ocaml","opencl","openqasm","qasm","oz","parigp","parser","pascal","objectpascal","pascaligo","pcaxis","px","peoplecode","pcode","perl","phpdoc","plsql","powerquery","pq","mscript","powershell","processing","prolog","promql","properties","protobuf","psl","pug","puppet","pure","purebasic","pbfasm","purescript","purs","python","py","q","qml","qore","qsharp","qs","r","racket","rkt","reason","regex","rego","renpy","rpy","rest","rip","roboconf","robotframework","robot","rust","sas","sass","scala","scss","shell-session","shellsession","sh-session","smali","smalltalk","smarty","sml","smlnj","solidity","sol","solution-file","sln","soy","turtle","trig","sparql","rq","splunk-spl","sqf","squirrel","stan","stylus","swift","t4-templating","t4-cs","t4","vbnet","t4-vb","yaml","yml","tap","tcl","textile","toml","tsx","tt2","twig","typoscript","tsconfig","unrealscript","uscript","uc","uri","url","v","vala","velocity","verilog","vhdl","vim","visual-basic","vb","vba","warpscript","wasm","wiki","wolfram","mathematica","wl","nb","xeora","xeoracube","xojo","xquery","yang","zig"] 3 | 4 | export default languages 5 | 6 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # @code-blocks 2 | 3 | Use markdown code blocks to render: 4 | 5 | * [Charts](https://github.com/idris-maps/code-blocks/tree/master/packages/charts) 6 | * [Graphviz diagrams](https://github.com/idris-maps/code-blocks/tree/master/packages/graphviz) 7 | * [MathML](https://github.com/idris-maps/code-blocks/tree/master/packages/math) 8 | * [Music sheets](https://github.com/idris-maps/code-blocks/tree/master/packages/music) 9 | * [HTML tables](https://github.com/idris-maps/code-blocks/tree/master/packages/tables) 10 | 11 | and [highlight code](https://github.com/idris-maps/code-blocks/tree/master/packages/prism). 12 | 13 | `@code-blocks` can be used either as a [rehype](https://github.com/rehypejs/rehype) transform or as an [eleventy](https://www.11ty.dev/) plugin. 14 | 15 | ## Example 16 | 17 | A code block with `music-abc` as language and the following content: 18 | 19 | ``` 20 | DDAA|BBA2| 21 | ``` 22 | 23 | will be rendered as: 24 | 25 | ![Music sheet example](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/home-example.png) 26 | 27 | ## Usage with [rehype](https://github.com/rehypejs/rehype) 28 | 29 | Install the transform: 30 | 31 | ```bash 32 | npm install @code-blocks/rehype-transform --save 33 | ``` 34 | 35 | Install the renderers you need, for example: 36 | 37 | ```bash 38 | npm install @code-blocks/charts --save 39 | ``` 40 | 41 | An use it: 42 | 43 | ```js 44 | const unified = require('unified') 45 | const stream = require('unified-stream') 46 | const markdown = require('remark-parse') 47 | const remark2rehype = require('remark-rehype') 48 | const html = require('rehype-stringify') 49 | 50 | // the rehype transform 51 | const codeblocks = require('@code-blocks/rehype-transform') 52 | 53 | // some renderers 54 | const charts = require('@code-blocks/charts') 55 | const graphviz = require('@code-blocks/graphviz') 56 | 57 | const processor = unified() 58 | .use(markdown) 59 | .use(remark2rehype) 60 | // add the transform and the renderers in an array as options 61 | .use(codeblocks, [charts, graphviz]) 62 | .use(html) 63 | 64 | process.stdin.pipe(stream(processor)).pipe(process.stdout) 65 | ``` 66 | 67 | ## Usage with [eleventy](https://www.11ty.dev/) 68 | 69 | Install the plugin: 70 | 71 | ```bash 72 | npm install @code-blocks/eleventy-plugin --save 73 | ``` 74 | 75 | Install the renderers you need, for example: 76 | 77 | ```bash 78 | npm install @code-blocks/music --save 79 | ``` 80 | 81 | 82 | In the `.eleventy.js` configuration file: 83 | 84 | ```js 85 | // the plugin 86 | const codeblocks = require('@code-blocks/eleventy-plugin') 87 | 88 | // some renderers 89 | const math = require('@code-blocks/math') 90 | const music = require('@code-blocks/music') 91 | 92 | module.exports = function(eleventyConfig) { 93 | // pass the renderers to the plugin 94 | eleventyConfig.addPlugin(codeblocks([ 95 | math, 96 | music, 97 | ])) 98 | } 99 | ``` 100 | -------------------------------------------------------------------------------- /packages/prism/README.md: -------------------------------------------------------------------------------- 1 | # @code-blocks/prism 2 | 3 | ## Install 4 | 5 | ```bash 6 | npm install @code-blocks/prism 7 | ``` 8 | 9 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](https://github.com/idris-maps/code-blocks). 10 | 11 | ## Usage 12 | 13 | There is already an official syntax [highlighting plugin](https://www.11ty.dev/docs/plugins/syntaxhighlight/) for eleventy. If you are just going to highlight code blocks, use that instead. However, if you are using other `@code-blocks` renderers, it will break the official plugin. 14 | 15 | This library only transforms code blocks into `` elements for [prism](https://prismjs.com/), you will need to add one of their [CSS themes](https://github.com/PrismJS/prism/tree/master/themes) to your page. 16 | 17 | **Supported languages** 18 | 19 | `abap` `abnf` `actionscript` `ada` `adoc` `agda` `al` `antlr4` `apacheconf` `apl` `applescript` `aql` `arduino` `arff` `asciidoc` `asm6502` `aspnet` `atom` `autohotkey` `autoit` `bash` `basic` `batch` `bbcode` `bison` `bnf` `brainfuck` `brightscript` `bro` `c` `cil` `clike` `clojure` `cmake` `coffee` `coffeescript` `conc` `concurnas` `context` `cpp` `crystal` `cs` `csharp` `csp` `css` `cypher` `d` `dart` `dax` `dhall` `diff` `django` `dns-zone` `dns-zone-file` `docker` `dockerfile` `dotnet` `ebnf` `editorconfig` `eiffel` `ejs` `elisp` `elixir` `elm` `emacs` `emacs-lisp` `erb` `erlang` `eta` `etlua` `excel-formula` `factor` `firestore-security-rules` `flow` `fortran` `fsharp` `ftl` `g4` `gamemakerlanguage` `gcode` `gdscript` `gedcom` `gherkin` `git` `gitignore` `glsl` `gml` `go` `graphql` `groovy` `haml` `handlebars` `haskell` `haxe` `hcl` `hgignore` `hlsl` `hpkp` `hs` `hsts` `html` `http` `ichigojam` `icon` `iecst` `ignore` `inform7` `ini` `io` `j` `java` `javadoc` `javadoclike` `javascript` `javastacktrace` `jinja2` `jolie` `jq` `js` `jsdoc` `json` `json5` `jsonp` `jsstacktrace` `jsx` `julia` `keyman` `kotlin` `kt` `kts` `latex` `latte` `less` `lilypond` `liquid` `lisp` `livescript` `llvm` `lolcode` `lua` `ly` `makefile` `markdown` `markup` `markup-templating` `mathml` `matlab` `md` `mel` `mizar` `monkey` `moon` `moonscript` `mscript` `n1ql` `n4js` `n4jsd` `nand2tetris-hdl` `nasm` `neon` `nginx` `nim` `nix` `npmignore` `nsis` `objc` `objectivec` `objectpascal` `ocaml` `opencl` `oz` `parigp` `parser` `pascal` `pascaligo` `pbfasm` `pcaxis` `pcode` `peoplecode` `perl` `php` `phpdoc` `plsql` `powerquery` `powershell` `pq` `processing` `prolog` `properties` `protobuf` `pug` `puppet` `pure` `purebasic` `px` `py` `python` `q` `qml` `qore` `r` `racket` `rb` `rbnf` `reason` `regex` `renpy` `rest` `rip` `rkt` `roboconf` `robot` `robotframework` `rpy` `rq` `rss` `ruby` `rust` `sas` `sass` `scala` `scheme` `scss` `shell` `shell-session` `shortcode` `sln` `smali` `smalltalk` `smarty` `sol` `solidity` `solution-file` `soy` `sparql` `splunk-spl` `sqf` `sql` `ssml` `stylus` `svg` `swift` `t4` `t4-cs` `t4-templating` `t4-vb` `tap` `tcl` `tex` `textile` `toml` `trig` `ts` `tsx` `tt2` `turtle` `twig` `typescript` `uc` `unrealscript` `uscript` `vala` `vb` `vba` `vbnet` `velocity` `verilog` `vhdl` `vim` `visual-basic` `warpscript` `wasm` `webmanifest` `wiki` `xeora` `xeoracube` `xls` `xlsx` `xml` `xojo` `xquery` `yaml` `yang` `yml` `zig` -------------------------------------------------------------------------------- /site/src/prism.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout.njk 3 | title: "@code-blocks/prism" 4 | short: "Code highlighting" 5 | description: "Highlight markdown code blocks with prism" 6 | tags: renderer 7 | --- 8 | 9 | ## Install 10 | 11 | ```bash 12 | npm install @code-blocks/prism 13 | ``` 14 | 15 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](/). 16 | 17 | ## Usage 18 | 19 | There is already an official syntax [highlighting plugin](https://www.11ty.dev/docs/plugins/syntaxhighlight/) for eleventy. If you are just going to highlight code blocks, use that instead. However, if you are using other `@code-blocks` renderers, it will break the official plugin. 20 | 21 | This library only transforms code blocks into `` elements for [prism](https://prismjs.com/), you will need to add one of their [CSS themes](https://github.com/PrismJS/prism/tree/master/themes) to your page. 22 | 23 | **Supported languages** 24 | 25 | `abap` `abnf` `actionscript` `ada` `adoc` `agda` `al` `antlr4` `apacheconf` `apl` `applescript` `aql` `arduino` `arff` `asciidoc` `asm6502` `aspnet` `atom` `autohotkey` `autoit` `bash` `basic` `batch` `bbcode` `bison` `bnf` `brainfuck` `brightscript` `bro` `c` `cil` `clike` `clojure` `cmake` `coffee` `coffeescript` `conc` `concurnas` `context` `cpp` `crystal` `cs` `csharp` `csp` `css` `cypher` `d` `dart` `dax` `dhall` `diff` `django` `dns-zone` `dns-zone-file` `docker` `dockerfile` `dotnet` `ebnf` `editorconfig` `eiffel` `ejs` `elisp` `elixir` `elm` `emacs` `emacs-lisp` `erb` `erlang` `eta` `etlua` `excel-formula` `factor` `firestore-security-rules` `flow` `fortran` `fsharp` `ftl` `g4` `gamemakerlanguage` `gcode` `gdscript` `gedcom` `gherkin` `git` `gitignore` `glsl` `gml` `go` `graphql` `groovy` `haml` `handlebars` `haskell` `haxe` `hcl` `hgignore` `hlsl` `hpkp` `hs` `hsts` `html` `http` `ichigojam` `icon` `iecst` `ignore` `inform7` `ini` `io` `j` `java` `javadoc` `javadoclike` `javascript` `javastacktrace` `jinja2` `jolie` `jq` `js` `jsdoc` `json` `json5` `jsonp` `jsstacktrace` `jsx` `julia` `keyman` `kotlin` `kt` `kts` `latex` `latte` `less` `lilypond` `liquid` `lisp` `livescript` `llvm` `lolcode` `lua` `ly` `makefile` `markdown` `markup` `markup-templating` `mathml` `matlab` `md` `mel` `mizar` `monkey` `moon` `moonscript` `mscript` `n1ql` `n4js` `n4jsd` `nand2tetris-hdl` `nasm` `neon` `nginx` `nim` `nix` `npmignore` `nsis` `objc` `objectivec` `objectpascal` `ocaml` `opencl` `oz` `parigp` `parser` `pascal` `pascaligo` `pbfasm` `pcaxis` `pcode` `peoplecode` `perl` `php` `phpdoc` `plsql` `powerquery` `powershell` `pq` `processing` `prolog` `properties` `protobuf` `pug` `puppet` `pure` `purebasic` `px` `py` `python` `q` `qml` `qore` `r` `racket` `rb` `rbnf` `reason` `regex` `renpy` `rest` `rip` `rkt` `roboconf` `robot` `robotframework` `rpy` `rq` `rss` `ruby` `rust` `sas` `sass` `scala` `scheme` `scss` `shell` `shell-session` `shortcode` `sln` `smali` `smalltalk` `smarty` `sol` `solidity` `solution-file` `soy` `sparql` `splunk-spl` `sqf` `sql` `ssml` `stylus` `svg` `swift` `t4` `t4-cs` `t4-templating` `t4-vb` `tap` `tcl` `tex` `textile` `toml` `trig` `ts` `tsx` `tt2` `turtle` `twig` `typescript` `uc` `unrealscript` `uscript` `vala` `vb` `vba` `vbnet` `velocity` `verilog` `vhdl` `vim` `visual-basic` `warpscript` `wasm` `webmanifest` `wiki` `xeora` `xeoracube` `xls` `xlsx` `xml` `xojo` `xquery` `yaml` `yang` `yml` `zig` -------------------------------------------------------------------------------- /packages/graphviz/README.md: -------------------------------------------------------------------------------- 1 | # @code-blocks/graphviz 2 | 3 | ## Install 4 | 5 | ```bash 6 | npm install @code-blocks/graphviz 7 | ``` 8 | 9 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](https://github.com/idris-maps/code-blocks). 10 | 11 | ## Usage 12 | 13 | **language: `graphviz`** 14 | 15 | This package uses [viz.js](https://github.com/mdaines/viz.js). Try the online editor, [here](http://viz-js.com/). For information on the syntax, checkout the [graphviz documentation](https://graphviz.org/). 16 | 17 | ### A basic example 18 | 19 | ``` 20 | digraph G {Hello->World} 21 | ``` 22 | 23 | ![Graphviz example 0](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_graphviz(0).png) 24 | 25 | 26 | ### A more complex example 27 | 28 | ``` 29 | digraph world { 30 | size="7,7"; 31 | {rank=same; S8 S24 S1 S35 S30;} 32 | {rank=same; T8 T24 T1 T35 T30;} 33 | {rank=same; 43 37 36 10 2;} 34 | {rank=same; 25 9 38 40 13 17 12 18;} 35 | {rank=same; 26 42 11 3 33 19 39 14 16;} 36 | {rank=same; 4 31 34 21 41 28 20;} 37 | {rank=same; 27 5 22 32 29 15;} 38 | {rank=same; 6 23;} 39 | {rank=same; 7;} 40 | 41 | S8 -> 9; 42 | S24 -> 25; 43 | S24 -> 27; 44 | S1 -> 2; 45 | S1 -> 10; 46 | S35 -> 43; 47 | S35 -> 36; 48 | S30 -> 31; 49 | S30 -> 33; 50 | 9 -> 42; 51 | 9 -> T1; 52 | 25 -> T1; 53 | 25 -> 26; 54 | 27 -> T24; 55 | 2 -> {3 ; 16 ; 17 ; T1 ; 18} 56 | 10 -> { 11 ; 14 ; T1 ; 13; 12;} 57 | 31 -> T1; 58 | 31 -> 32; 59 | 33 -> T30; 60 | 33 -> 34; 61 | 42 -> 4; 62 | 26 -> 4; 63 | 3 -> 4; 64 | 16 -> 15; 65 | 17 -> 19; 66 | 18 -> 29; 67 | 11 -> 4; 68 | 14 -> 15; 69 | 37 -> {39 ; 41 ; 38 ; 40;} 70 | 13 -> 19; 71 | 12 -> 29; 72 | 43 -> 38; 73 | 43 -> 40; 74 | 36 -> 19; 75 | 32 -> 23; 76 | 34 -> 29; 77 | 39 -> 15; 78 | 41 -> 29; 79 | 38 -> 4; 80 | 40 -> 19; 81 | 4 -> 5; 82 | 19 -> {21 ; 20 ; 28;} 83 | 5 -> {6 ; T35 ; 23;} 84 | 21 -> 22; 85 | 20 -> 15; 86 | 28 -> 29; 87 | 6 -> 7; 88 | 15 -> T1; 89 | 22 -> T35; 90 | 22 -> 23; 91 | 29 -> T30; 92 | 7 -> T8; 93 | 23 -> T24; 94 | 23 -> T1; 95 | } 96 | ``` 97 | 98 | ![Graphviz example 1](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_graphviz(1).png) 99 | 100 | ### A sequence diagram 101 | 102 | ``` 103 | digraph SEQ_DIAGRAM { 104 | graph [overlap=true, splines=line, nodesep=1.0, ordering=out]; 105 | edge [arrowhead=none]; 106 | node [shape=none, width=0, height=0, label=""]; 107 | 108 | { 109 | rank=same; 110 | node[shape=rectangle, height=0.7, width=2]; 111 | api_a[label="API A"]; 112 | api_b[label="API B"]; 113 | api_c[label="API C"]; 114 | } 115 | // Draw vertical lines 116 | { 117 | edge [style=dashed, weight=6]; 118 | api_a -> a1 -> a2 -> a3; 119 | a3 -> a4 [penwidth=5, style=solid]; 120 | a4 -> a5; 121 | } 122 | { 123 | edge [style=dashed, weight=6]; 124 | api_b -> b1 -> b2 -> b3 -> b4; 125 | b4 -> b5 [penwidth=5; style=solid]; 126 | } 127 | { 128 | edge [style=dashed, weight=6]; 129 | api_c -> c1; 130 | c1-> c2 [penwidth=5, style=solid]; 131 | c2 -> c3 -> c4 -> c5; 132 | } 133 | // Draws activations 134 | { rank=same; a1 -> b1 [label="activate()"]; b1 -> c1 [arrowhead=normal]; } 135 | { rank=same; a2 -> b2 [style=invis]; b2 -> c2 [label="refund()", arrowhead=normal, dir=back]; } 136 | { rank=same; a3 -> b3 [arrowhead=normal, dir=back, label="place_order()"]; b3 -> c3; } 137 | { rank=same; a4 -> b4 [label="distribute()", arrowhead=normal]; } 138 | { rank=same; a5 -> b5 [style=invis]; b5 -> c5 [label="bill_order()", arrowhead=normal]; } 139 | } 140 | ``` 141 | 142 | ![Graphviz example 2](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_graphviz(2).png) 143 | 144 | Based on [this stackoverflow answer](https://stackoverflow.com/questions/1491322/graphviz-top-to-bottom-and-left-to-right). -------------------------------------------------------------------------------- /packages/parser/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/parser", 3 | "version": "0.1.8", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@code-blocks/parser", 9 | "version": "0.1.0", 10 | "license": "GPLv2", 11 | "dependencies": { 12 | "front-matter": "^4.0.2", 13 | "ramda": "^0.27.0" 14 | }, 15 | "devDependencies": { 16 | "@types/ramda": "^0.27.6" 17 | } 18 | }, 19 | "node_modules/@types/ramda": { 20 | "version": "0.27.6", 21 | "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.27.6.tgz", 22 | "integrity": "sha512-ephagb0ZIAJSoS5I/qMS4Mqo1b/Nd50pWM+o1QO/dz8NF//GsCGPTLDVRqgXlVncy74KShfHzE5rPZXTeek4PA==", 23 | "dev": true, 24 | "dependencies": { 25 | "ts-toolbelt": "^6.3.3" 26 | } 27 | }, 28 | "node_modules/argparse": { 29 | "version": "1.0.10", 30 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 31 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 32 | "dependencies": { 33 | "sprintf-js": "~1.0.2" 34 | } 35 | }, 36 | "node_modules/esprima": { 37 | "version": "4.0.1", 38 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 39 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 40 | "bin": { 41 | "esparse": "bin/esparse.js", 42 | "esvalidate": "bin/esvalidate.js" 43 | }, 44 | "engines": { 45 | "node": ">=4" 46 | } 47 | }, 48 | "node_modules/front-matter": { 49 | "version": "4.0.2", 50 | "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", 51 | "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", 52 | "dependencies": { 53 | "js-yaml": "^3.13.1" 54 | } 55 | }, 56 | "node_modules/js-yaml": { 57 | "version": "3.14.0", 58 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", 59 | "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", 60 | "dependencies": { 61 | "argparse": "^1.0.7", 62 | "esprima": "^4.0.0" 63 | }, 64 | "bin": { 65 | "js-yaml": "bin/js-yaml.js" 66 | } 67 | }, 68 | "node_modules/ramda": { 69 | "version": "0.27.0", 70 | "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.0.tgz", 71 | "integrity": "sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA==" 72 | }, 73 | "node_modules/sprintf-js": { 74 | "version": "1.0.3", 75 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 76 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 77 | }, 78 | "node_modules/ts-toolbelt": { 79 | "version": "6.9.4", 80 | "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.9.4.tgz", 81 | "integrity": "sha512-muRZZqfOTOVvLk5cdnp7YWm6xX+kD/WL2cS/L4zximBRcbQSuMoTbQQ2ZZBVMs1gB0EZw1qThP+HrIQB35OmEw==", 82 | "dev": true 83 | } 84 | }, 85 | "dependencies": { 86 | "@types/ramda": { 87 | "version": "0.27.6", 88 | "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.27.6.tgz", 89 | "integrity": "sha512-ephagb0ZIAJSoS5I/qMS4Mqo1b/Nd50pWM+o1QO/dz8NF//GsCGPTLDVRqgXlVncy74KShfHzE5rPZXTeek4PA==", 90 | "dev": true, 91 | "requires": { 92 | "ts-toolbelt": "^6.3.3" 93 | } 94 | }, 95 | "argparse": { 96 | "version": "1.0.10", 97 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 98 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 99 | "requires": { 100 | "sprintf-js": "~1.0.2" 101 | } 102 | }, 103 | "esprima": { 104 | "version": "4.0.1", 105 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 106 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" 107 | }, 108 | "front-matter": { 109 | "version": "4.0.2", 110 | "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", 111 | "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", 112 | "requires": { 113 | "js-yaml": "^3.13.1" 114 | } 115 | }, 116 | "js-yaml": { 117 | "version": "3.14.0", 118 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", 119 | "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", 120 | "requires": { 121 | "argparse": "^1.0.7", 122 | "esprima": "^4.0.0" 123 | } 124 | }, 125 | "ramda": { 126 | "version": "0.27.0", 127 | "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.0.tgz", 128 | "integrity": "sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA==" 129 | }, 130 | "sprintf-js": { 131 | "version": "1.0.3", 132 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 133 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 134 | }, 135 | "ts-toolbelt": { 136 | "version": "6.9.4", 137 | "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.9.4.tgz", 138 | "integrity": "sha512-muRZZqfOTOVvLk5cdnp7YWm6xX+kD/WL2cS/L4zximBRcbQSuMoTbQQ2ZZBVMs1gB0EZw1qThP+HrIQB35OmEw==", 139 | "dev": true 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Basic Options */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 8 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 9 | // "lib": [], /* Specify library files to be included in the compilation. */ 10 | // "allowJs": true, /* Allow javascript files to be compiled. */ 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 13 | "declaration": true, /* Generates corresponding '.d.ts' file. */ 14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | // "outDir": "./", /* Redirect output structure to the directory. */ 18 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "composite": true, /* Enable project compilation */ 20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 21 | // "removeComments": true, /* Do not emit comments to output. */ 22 | // "noEmit": true, /* Do not emit outputs. */ 23 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 26 | 27 | /* Strict Type-Checking Options */ 28 | "strict": true, /* Enable all strict type-checking options. */ 29 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 30 | // "strictNullChecks": true, /* Enable strict null checks. */ 31 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 32 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 33 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 34 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 35 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 36 | 37 | /* Additional Checks */ 38 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 39 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 40 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 41 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 42 | 43 | /* Module Resolution Options */ 44 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 45 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 46 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 47 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 48 | // "typeRoots": [], /* List of folders to include type definitions from. */ 49 | // "types": [], /* Type declaration files to be included in compilation. */ 50 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 51 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 52 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 53 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 54 | 55 | /* Source Map Options */ 56 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 58 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 59 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 60 | 61 | /* Experimental Options */ 62 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 63 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 64 | 65 | /* Advanced Options */ 66 | "skipLibCheck": true, /* Skip type checking of declaration files. */ 67 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /site/src/graphviz.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout.njk 3 | title: "@code-blocks/graphviz" 4 | short: "Graphviz diagrams" 5 | description: "Draw graphviz diagrams in markdown code blocks" 6 | tags: renderer 7 | --- 8 | 9 | ## Install 10 | 11 | ```bash 12 | npm install @code-blocks/graphviz 13 | ``` 14 | 15 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](/). 16 | 17 | ## Usage 18 | 19 | **language: `graphviz`** 20 | 21 | This package uses [viz.js](https://github.com/mdaines/viz.js). Try the online editor, [here](http://viz-js.com/). For information on the syntax, checkout the [graphviz documentation](https://graphviz.org/). 22 | 23 | ### A basic example 24 | 25 | ``` 26 | digraph G {Hello->World} 27 | ``` 28 | 29 | ```graphviz 30 | --- 31 | className: graphviz-example-1 32 | --- 33 | digraph G {Hello->World} 34 | ``` 35 | 36 | ### A more complex example 37 | 38 | ``` 39 | digraph world { 40 | size="7,7"; 41 | {rank=same; S8 S24 S1 S35 S30;} 42 | {rank=same; T8 T24 T1 T35 T30;} 43 | {rank=same; 43 37 36 10 2;} 44 | {rank=same; 25 9 38 40 13 17 12 18;} 45 | {rank=same; 26 42 11 3 33 19 39 14 16;} 46 | {rank=same; 4 31 34 21 41 28 20;} 47 | {rank=same; 27 5 22 32 29 15;} 48 | {rank=same; 6 23;} 49 | {rank=same; 7;} 50 | 51 | S8 -> 9; 52 | S24 -> 25; 53 | S24 -> 27; 54 | S1 -> 2; 55 | S1 -> 10; 56 | S35 -> 43; 57 | S35 -> 36; 58 | S30 -> 31; 59 | S30 -> 33; 60 | 9 -> 42; 61 | 9 -> T1; 62 | 25 -> T1; 63 | 25 -> 26; 64 | 27 -> T24; 65 | 2 -> {3 ; 16 ; 17 ; T1 ; 18} 66 | 10 -> { 11 ; 14 ; T1 ; 13; 12;} 67 | 31 -> T1; 68 | 31 -> 32; 69 | 33 -> T30; 70 | 33 -> 34; 71 | 42 -> 4; 72 | 26 -> 4; 73 | 3 -> 4; 74 | 16 -> 15; 75 | 17 -> 19; 76 | 18 -> 29; 77 | 11 -> 4; 78 | 14 -> 15; 79 | 37 -> {39 ; 41 ; 38 ; 40;} 80 | 13 -> 19; 81 | 12 -> 29; 82 | 43 -> 38; 83 | 43 -> 40; 84 | 36 -> 19; 85 | 32 -> 23; 86 | 34 -> 29; 87 | 39 -> 15; 88 | 41 -> 29; 89 | 38 -> 4; 90 | 40 -> 19; 91 | 4 -> 5; 92 | 19 -> {21 ; 20 ; 28;} 93 | 5 -> {6 ; T35 ; 23;} 94 | 21 -> 22; 95 | 20 -> 15; 96 | 28 -> 29; 97 | 6 -> 7; 98 | 15 -> T1; 99 | 22 -> T35; 100 | 22 -> 23; 101 | 29 -> T30; 102 | 7 -> T8; 103 | 23 -> T24; 104 | 23 -> T1; 105 | } 106 | ``` 107 | 108 | ```graphviz 109 | digraph world { 110 | size="7,7"; 111 | {rank=same; S8 S24 S1 S35 S30;} 112 | {rank=same; T8 T24 T1 T35 T30;} 113 | {rank=same; 43 37 36 10 2;} 114 | {rank=same; 25 9 38 40 13 17 12 18;} 115 | {rank=same; 26 42 11 3 33 19 39 14 16;} 116 | {rank=same; 4 31 34 21 41 28 20;} 117 | {rank=same; 27 5 22 32 29 15;} 118 | {rank=same; 6 23;} 119 | {rank=same; 7;} 120 | 121 | S8 -> 9; 122 | S24 -> 25; 123 | S24 -> 27; 124 | S1 -> 2; 125 | S1 -> 10; 126 | S35 -> 43; 127 | S35 -> 36; 128 | S30 -> 31; 129 | S30 -> 33; 130 | 9 -> 42; 131 | 9 -> T1; 132 | 25 -> T1; 133 | 25 -> 26; 134 | 27 -> T24; 135 | 2 -> {3 ; 16 ; 17 ; T1 ; 18} 136 | 10 -> { 11 ; 14 ; T1 ; 13; 12;} 137 | 31 -> T1; 138 | 31 -> 32; 139 | 33 -> T30; 140 | 33 -> 34; 141 | 42 -> 4; 142 | 26 -> 4; 143 | 3 -> 4; 144 | 16 -> 15; 145 | 17 -> 19; 146 | 18 -> 29; 147 | 11 -> 4; 148 | 14 -> 15; 149 | 37 -> {39 ; 41 ; 38 ; 40;} 150 | 13 -> 19; 151 | 12 -> 29; 152 | 43 -> 38; 153 | 43 -> 40; 154 | 36 -> 19; 155 | 32 -> 23; 156 | 34 -> 29; 157 | 39 -> 15; 158 | 41 -> 29; 159 | 38 -> 4; 160 | 40 -> 19; 161 | 4 -> 5; 162 | 19 -> {21 ; 20 ; 28;} 163 | 5 -> {6 ; T35 ; 23;} 164 | 21 -> 22; 165 | 20 -> 15; 166 | 28 -> 29; 167 | 6 -> 7; 168 | 15 -> T1; 169 | 22 -> T35; 170 | 22 -> 23; 171 | 29 -> T30; 172 | 7 -> T8; 173 | 23 -> T24; 174 | 23 -> T1; 175 | } 176 | ``` 177 | 178 | ### A sequence diagram 179 | 180 | ``` 181 | digraph SEQ_DIAGRAM { 182 | graph [overlap=true, splines=line, nodesep=1.0, ordering=out]; 183 | edge [arrowhead=none]; 184 | node [shape=none, width=0, height=0, label=""]; 185 | 186 | { 187 | rank=same; 188 | node[shape=rectangle, height=0.7, width=2]; 189 | api_a[label="API A"]; 190 | api_b[label="API B"]; 191 | api_c[label="API C"]; 192 | } 193 | // Draw vertical lines 194 | { 195 | edge [style=dashed, weight=6]; 196 | api_a -> a1 -> a2 -> a3; 197 | a3 -> a4 [penwidth=5, style=solid]; 198 | a4 -> a5; 199 | } 200 | { 201 | edge [style=dashed, weight=6]; 202 | api_b -> b1 -> b2 -> b3 -> b4; 203 | b4 -> b5 [penwidth=5; style=solid]; 204 | } 205 | { 206 | edge [style=dashed, weight=6]; 207 | api_c -> c1; 208 | c1-> c2 [penwidth=5, style=solid]; 209 | c2 -> c3 -> c4 -> c5; 210 | } 211 | // Draws activations 212 | { rank=same; a1 -> b1 [label="activate()"]; b1 -> c1 [arrowhead=normal]; } 213 | { rank=same; a2 -> b2 [style=invis]; b2 -> c2 [label="refund()", arrowhead=normal, dir=back]; } 214 | { rank=same; a3 -> b3 [arrowhead=normal, dir=back, label="place_order()"]; b3 -> c3; } 215 | { rank=same; a4 -> b4 [label="distribute()", arrowhead=normal]; } 216 | { rank=same; a5 -> b5 [style=invis]; b5 -> c5 [label="bill_order()", arrowhead=normal]; } 217 | } 218 | ``` 219 | 220 | ```graphviz 221 | digraph SEQ_DIAGRAM { 222 | graph [overlap=true, splines=line, nodesep=1.0, ordering=out]; 223 | edge [arrowhead=none]; 224 | node [shape=none, width=0, height=0, label=""]; 225 | 226 | { 227 | rank=same; 228 | node[shape=rectangle, height=0.7, width=2]; 229 | api_a[label="API A"]; 230 | api_b[label="API B"]; 231 | api_c[label="API C"]; 232 | } 233 | // Draw vertical lines 234 | { 235 | edge [style=dashed, weight=6]; 236 | api_a -> a1 -> a2 -> a3; 237 | a3 -> a4 [penwidth=5, style=solid]; 238 | a4 -> a5; 239 | } 240 | { 241 | edge [style=dashed, weight=6]; 242 | api_b -> b1 -> b2 -> b3 -> b4; 243 | b4 -> b5 [penwidth=5; style=solid]; 244 | } 245 | { 246 | edge [style=dashed, weight=6]; 247 | api_c -> c1; 248 | c1-> c2 [penwidth=5, style=solid]; 249 | c2 -> c3 -> c4 -> c5; 250 | } 251 | // Draws activations 252 | { rank=same; a1 -> b1 [label="activate()"]; b1 -> c1 [arrowhead=normal]; } 253 | { rank=same; a2 -> b2 [style=invis]; b2 -> c2 [label="refund()", arrowhead=normal, dir=back]; } 254 | { rank=same; a3 -> b3 [arrowhead=normal, dir=back, label="place_order()"]; b3 -> c3; } 255 | { rank=same; a4 -> b4 [label="distribute()", arrowhead=normal]; } 256 | { rank=same; a5 -> b5 [style=invis]; b5 -> c5 [label="bill_order()", arrowhead=normal]; } 257 | } 258 | ``` 259 | 260 | Based on [this stackoverflow answer](https://stackoverflow.com/questions/1491322/graphviz-top-to-bottom-and-left-to-right). -------------------------------------------------------------------------------- /packages/charts/README.md: -------------------------------------------------------------------------------- 1 | # @code-blocks/charts 2 | 3 | ## Install 4 | 5 | ```bash 6 | npm install @code-blocks/charts 7 | ``` 8 | 9 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](https://github.com/idris-maps/code-blocks). 10 | 11 | ## Bar chart 12 | 13 | **language: `bar-chart`** 14 | 15 | ``` 16 | Letters,Amount 17 | A,28 18 | B,55 19 | C,43 20 | D,91 21 | E,81 22 | F,53 23 | ``` 24 | 25 | renders as: 26 | 27 | ![Charts example 0](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_charts(0).png) 28 | 29 | 30 | ### Options 31 | 32 | * `width` (defaults to `400`) 33 | * `height` (defaults to `200`) 34 | * `color` (defaults to `steelblue`) 35 | * `className` (defaults to `chart`) 36 | 37 | The same bar chart using options: 38 | 39 | ``` 40 | --- 41 | width: 500 42 | height: 100 43 | color: indianred 44 | --- 45 | Letters,Amount 46 | A,28 47 | B,55 48 | C,43 49 | D,91 50 | E,81 51 | F,53 52 | ``` 53 | 54 | ![Charts example 1](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_charts(1).png) 55 | 56 | ## Line chart 57 | 58 | **language: `line-chart`** 59 | 60 | ``` 61 | Date,Value 62 | 2010-01-01,28 63 | 2012-02-22,55 64 | 2013-01-13,43 65 | 2015-01-04,91 66 | 2015-01-05,81 67 | 2017-12-06,53 68 | 2018-06-07,19 69 | 2019-11-08,81 70 | 2020-01-09,52 71 | ``` 72 | 73 | ![Charts example 2](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_charts(2).png) 74 | 75 | ### Options 76 | 77 | * `width` (defaults to `400`) 78 | * `height` (defaults to `200`) 79 | * `color` (defaults to `steelblue`) 80 | * `temporal` (defaults to `false`) 81 | * `className` (defaults to `chart`) 82 | 83 | If `temporal` is not `true`, the x axis is assumed to be `nominal`, as in the example above. As we are using dates here, set `temporal` to `true`. 84 | 85 | ``` 86 | --- 87 | temporal: true 88 | --- 89 | Date,Value 90 | 2010-01-01,28 91 | 2012-02-22,55 92 | 2013-01-13,43 93 | 2015-01-04,91 94 | 2015-01-05,81 95 | 2017-12-06,53 96 | 2018-06-07,19 97 | 2019-11-08,81 98 | 2020-01-09,52 99 | ``` 100 | 101 | ![Charts example 3](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_charts(3).png) 102 | 103 | ## Area chart 104 | 105 | **language: `area-chart`** 106 | 107 | ``` 108 | --- 109 | temporal: true 110 | --- 111 | Date,Value 112 | 2010-01-01,28 113 | 2012-02-22,55 114 | 2013-01-13,43 115 | 2015-01-04,91 116 | 2015-01-05,81 117 | 2017-12-06,53 118 | 2018-06-07,19 119 | 2019-11-08,81 120 | 2020-01-09,52 121 | ``` 122 | 123 | ![Charts example 4](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_charts(4).png) 124 | 125 | ### Options 126 | 127 | Area chart options are the same as for line charts. 128 | 129 | ## Multiline chart 130 | 131 | **language: `multiline-chart`** 132 | 133 | ``` 134 | --- 135 | temporal: true 136 | --- 137 | Date,Value,Stock 138 | 2010-01-01,28,AAA 139 | 2012-02-22,55,AAA 140 | 2013-01-13,43,AAA 141 | 2015-01-04,91,AAA 142 | 2010-01-01,80,BBB 143 | 2012-02-22,53,BBB 144 | 2013-01-13,63,BBB 145 | 2015-01-04,34,BBB 146 | 2010-01-01,18,CCC 147 | 2012-02-22,34,CCC 148 | 2013-01-13,55,CCC 149 | 2015-01-04,76,CCC 150 | ``` 151 | 152 | ![Charts example 5](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_charts(5).png) 153 | 154 | For multiline charts, add a third column. Options are the same as for line charts, except you can not choose the color. ¯\\\_(ツ)\_/¯ 155 | 156 | ## Pie chart 157 | 158 | **language: `pie-chart`** 159 | 160 | ``` 161 | Letters,Amount 162 | A,28 163 | B,55 164 | C,43 165 | D,91 166 | ``` 167 | 168 | ![Charts example 6](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_charts(6).png) 169 | 170 | ### Options 171 | 172 | * `width` (defaults to `400`) 173 | * `height` (defaults to `200`) 174 | * `className` (defaults to `chart`) 175 | 176 | ## Vegalite 177 | 178 | All charts are drawn with [vegalite](https://vega.github.io/vega-lite/). You can use that too. 179 | 180 | **language: `vegalite`** 181 | 182 | ```json 183 | { 184 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json", 185 | "width": 400, 186 | "height": 200, 187 | "data": { 188 | "values": [ 189 | {"a": "A", "b": 28}, {"a": "B", "b": 55}, {"a": "C", "b": 43}, 190 | {"a": "D", "b": 91}, {"a": "E", "b": 81}, {"a": "F", "b": 53} 191 | ] 192 | }, 193 | "mark": "bar", 194 | "encoding": { 195 | "x": {"field": "a", "type": "ordinal", "axis": {"labelAngle": 0}}, 196 | "y": {"field": "b", "type": "quantitative"} 197 | } 198 | } 199 | ``` 200 | 201 | ![Charts example 7](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_charts(7).png) 202 | 203 | For more info about vegalite, try their [online editor](https://vega.github.io/editor/#/examples/vega-lite/bar). 204 | 205 | ## Vega 206 | 207 | Vegalite is based on [vega](https://vega.github.io/vega/). 208 | 209 | ⚠️ Charts are rendered as static SVG, interactions will be ignored. 210 | 211 | **language: `vega`** 212 | 213 | ```json 214 | { 215 | "$schema": "https://vega.github.io/schema/vega/v5.json", 216 | "width": 400, 217 | "height": 200, 218 | "padding": 5, 219 | 220 | "data": [ 221 | { 222 | "name": "table", 223 | "values": [ 224 | {"category": "A", "amount": 28}, 225 | {"category": "B", "amount": 55}, 226 | {"category": "C", "amount": 43}, 227 | {"category": "D", "amount": 91}, 228 | {"category": "E", "amount": 81}, 229 | {"category": "F", "amount": 53} 230 | ] 231 | } 232 | ], 233 | 234 | "scales": [ 235 | { 236 | "name": "xscale", 237 | "type": "band", 238 | "domain": {"data": "table", "field": "category"}, 239 | "range": "width", 240 | "padding": 0.05, 241 | "round": true 242 | }, 243 | { 244 | "name": "yscale", 245 | "domain": {"data": "table", "field": "amount"}, 246 | "nice": true, 247 | "range": "height" 248 | } 249 | ], 250 | 251 | "axes": [ 252 | { "orient": "bottom", "scale": "xscale" }, 253 | { "orient": "left", "scale": "yscale" } 254 | ], 255 | 256 | "marks": [ 257 | { 258 | "type": "rect", 259 | "from": {"data":"table"}, 260 | "encode": { 261 | "enter": { 262 | "x": {"scale": "xscale", "field": "category"}, 263 | "width": {"scale": "xscale", "band": 1}, 264 | "y": {"scale": "yscale", "field": "amount"}, 265 | "y2": {"scale": "yscale", "value": 0}, 266 | "fill": {"value": "steelblue"} 267 | } 268 | } 269 | } 270 | ] 271 | } 272 | ``` 273 | 274 | ![Charts example 8](https://raw.githubusercontent.com/idris-maps/code-blocks/master/assets/example_charts(8).png) 275 | -------------------------------------------------------------------------------- /site/src/charts.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout.njk 3 | title: "@code-blocks/charts" 4 | short: "Charts" 5 | description: "Draw charts in markdown code blocks" 6 | tags: renderer 7 | --- 8 | 9 | ## Install 10 | 11 | ```bash 12 | npm install @code-blocks/charts 13 | ``` 14 | 15 | Use with [rehype](https://github.com/rehypejs/rehype) or [eleventy](https://www.11ty.dev/). See how [here](/). 16 | 17 | ## Bar chart 18 | 19 | **language: `bar-chart`** 20 | 21 | ``` 22 | Letters,Amount 23 | A,28 24 | B,55 25 | C,43 26 | D,91 27 | E,81 28 | F,53 29 | ``` 30 | 31 | renders as: 32 | 33 | ```bar-chart 34 | Letters,Amount 35 | A,28 36 | B,55 37 | C,43 38 | D,91 39 | E,81 40 | F,53 41 | ``` 42 | 43 | ### Options 44 | 45 | * `width` (defaults to `400`) 46 | * `height` (defaults to `200`) 47 | * `color` (defaults to `steelblue`) 48 | * `className` (defaults to `chart`) 49 | 50 | The same bar chart using options: 51 | 52 | ``` 53 | --- 54 | width: 500 55 | height: 100 56 | color: indianred 57 | --- 58 | Letters,Amount 59 | A,28 60 | B,55 61 | C,43 62 | D,91 63 | E,81 64 | F,53 65 | ``` 66 | 67 | ```bar-chart 68 | --- 69 | width: 500 70 | height: 100 71 | color: indianred 72 | --- 73 | Letters,Amount 74 | A,28 75 | B,55 76 | C,43 77 | D,91 78 | E,81 79 | F,53 80 | ``` 81 | 82 | ## Line chart 83 | 84 | **language: `line-chart`** 85 | 86 | ``` 87 | Date,Value 88 | 2010-01-01,28 89 | 2012-02-22,55 90 | 2013-01-13,43 91 | 2015-01-04,91 92 | 2015-01-05,81 93 | 2017-12-06,53 94 | 2018-06-07,19 95 | 2019-11-08,81 96 | 2020-01-09,52 97 | ``` 98 | 99 | ```line-chart 100 | Date,Value 101 | 2010-01-01,28 102 | 2012-02-22,55 103 | 2013-01-13,43 104 | 2015-01-04,91 105 | 2015-01-05,81 106 | 2017-12-06,53 107 | 2018-06-07,19 108 | 2019-11-08,81 109 | 2020-01-09,52 110 | ``` 111 | 112 | ### Options 113 | 114 | * `width` (defaults to `400`) 115 | * `height` (defaults to `200`) 116 | * `color` (defaults to `steelblue`) 117 | * `temporal` (defaults to `false`) 118 | * `className` (defaults to `chart`) 119 | 120 | If `temporal` is not `true`, the x axis is assumed to be `nominal`, as in the example above. As we are using dates here, set `temporal` to `true`. 121 | 122 | ``` 123 | --- 124 | temporal: true 125 | --- 126 | Date,Value 127 | 2010-01-01,28 128 | 2012-02-22,55 129 | 2013-01-13,43 130 | 2015-01-04,91 131 | 2015-01-05,81 132 | 2017-12-06,53 133 | 2018-06-07,19 134 | 2019-11-08,81 135 | 2020-01-09,52 136 | ``` 137 | 138 | ```line-chart 139 | --- 140 | temporal: true 141 | --- 142 | Date,Value 143 | 2010-01-01,28 144 | 2012-02-22,55 145 | 2013-01-13,43 146 | 2015-01-04,91 147 | 2015-01-05,81 148 | 2017-12-06,53 149 | 2018-06-07,19 150 | 2019-11-08,81 151 | 2020-01-09,52 152 | ``` 153 | 154 | ## Area chart 155 | 156 | **language: `area-chart`** 157 | 158 | ``` 159 | --- 160 | temporal: true 161 | --- 162 | Date,Value 163 | 2010-01-01,28 164 | 2012-02-22,55 165 | 2013-01-13,43 166 | 2015-01-04,91 167 | 2015-01-05,81 168 | 2017-12-06,53 169 | 2018-06-07,19 170 | 2019-11-08,81 171 | 2020-01-09,52 172 | ``` 173 | 174 | ```area-chart 175 | --- 176 | temporal: true 177 | --- 178 | Date,Value 179 | 2010-01-01,28 180 | 2012-02-22,55 181 | 2013-01-13,43 182 | 2015-01-04,91 183 | 2015-01-05,81 184 | 2017-12-06,53 185 | 2018-06-07,19 186 | 2019-11-08,81 187 | 2020-01-09,52 188 | ``` 189 | 190 | ### Options 191 | 192 | Area chart options are the same as for line charts. 193 | 194 | ## Multiline chart 195 | 196 | **language: `multiline-chart`** 197 | 198 | ``` 199 | --- 200 | temporal: true 201 | --- 202 | Date,Value,Stock 203 | 2010-01-01,28,AAA 204 | 2012-02-22,55,AAA 205 | 2013-01-13,43,AAA 206 | 2015-01-04,91,AAA 207 | 2010-01-01,80,BBB 208 | 2012-02-22,53,BBB 209 | 2013-01-13,63,BBB 210 | 2015-01-04,34,BBB 211 | 2010-01-01,18,CCC 212 | 2012-02-22,34,CCC 213 | 2013-01-13,55,CCC 214 | 2015-01-04,76,CCC 215 | ``` 216 | 217 | ```multiline-chart 218 | --- 219 | temporal: true 220 | --- 221 | Date,Value,Stock 222 | 2010-01-01,28,AAA 223 | 2012-02-22,55,AAA 224 | 2013-01-13,43,AAA 225 | 2015-01-04,91,AAA 226 | 2010-01-01,80,BBB 227 | 2012-02-22,53,BBB 228 | 2013-01-13,63,BBB 229 | 2015-01-04,34,BBB 230 | 2010-01-01,18,CCC 231 | 2012-02-22,34,CCC 232 | 2013-01-13,55,CCC 233 | 2015-01-04,76,CCC 234 | ``` 235 | 236 | For multiline charts, add a third column. Options are the same as for line charts, except you can not choose the color. ¯\\\_(ツ)\_/¯ 237 | 238 | ## Pie chart 239 | 240 | **language: `pie-chart`** 241 | 242 | ``` 243 | Letters,Amount 244 | A,28 245 | B,55 246 | C,43 247 | D,91 248 | ``` 249 | 250 | ```pie-chart 251 | Letters,Amount 252 | A,28 253 | B,55 254 | C,43 255 | D,91 256 | ``` 257 | 258 | ### Options 259 | 260 | * `width` (defaults to `400`) 261 | * `height` (defaults to `200`) 262 | * `className` (defaults to `chart`) 263 | 264 | ## Vegalite 265 | 266 | All charts are drawn with [vegalite](https://vega.github.io/vega-lite/). You can use that too. 267 | 268 | **language: `vegalite`** 269 | 270 | ```json 271 | { 272 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json", 273 | "width": 400, 274 | "height": 200, 275 | "data": { 276 | "values": [ 277 | {"a": "A", "b": 28}, {"a": "B", "b": 55}, {"a": "C", "b": 43}, 278 | {"a": "D", "b": 91}, {"a": "E", "b": 81}, {"a": "F", "b": 53} 279 | ] 280 | }, 281 | "mark": "bar", 282 | "encoding": { 283 | "x": {"field": "a", "type": "ordinal", "axis": {"labelAngle": 0}}, 284 | "y": {"field": "b", "type": "quantitative"} 285 | } 286 | } 287 | ``` 288 | 289 | ```vegalite 290 | { 291 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json", 292 | "width": 400, 293 | "height": 200, 294 | "data": { 295 | "values": [ 296 | {"a": "A", "b": 28}, {"a": "B", "b": 55}, {"a": "C", "b": 43}, 297 | {"a": "D", "b": 91}, {"a": "E", "b": 81}, {"a": "F", "b": 53} 298 | ] 299 | }, 300 | "mark": "bar", 301 | "encoding": { 302 | "x": {"field": "a", "type": "ordinal", "axis": {"labelAngle": 0}}, 303 | "y": {"field": "b", "type": "quantitative"} 304 | } 305 | } 306 | ``` 307 | 308 | For more info about vegalite, try their [online editor](https://vega.github.io/editor/#/examples/vega-lite/bar). 309 | 310 | ## Vega 311 | 312 | Vegalite is based on [vega](https://vega.github.io/vega/). 313 | 314 | ⚠️ Charts are rendered as static SVG, interactions will be ignored. 315 | 316 | **language: `vega`** 317 | 318 | ```json 319 | { 320 | "$schema": "https://vega.github.io/schema/vega/v5.json", 321 | "width": 400, 322 | "height": 200, 323 | "padding": 5, 324 | 325 | "data": [ 326 | { 327 | "name": "table", 328 | "values": [ 329 | {"category": "A", "amount": 28}, 330 | {"category": "B", "amount": 55}, 331 | {"category": "C", "amount": 43}, 332 | {"category": "D", "amount": 91}, 333 | {"category": "E", "amount": 81}, 334 | {"category": "F", "amount": 53} 335 | ] 336 | } 337 | ], 338 | 339 | "scales": [ 340 | { 341 | "name": "xscale", 342 | "type": "band", 343 | "domain": {"data": "table", "field": "category"}, 344 | "range": "width", 345 | "padding": 0.05, 346 | "round": true 347 | }, 348 | { 349 | "name": "yscale", 350 | "domain": {"data": "table", "field": "amount"}, 351 | "nice": true, 352 | "range": "height" 353 | } 354 | ], 355 | 356 | "axes": [ 357 | { "orient": "bottom", "scale": "xscale" }, 358 | { "orient": "left", "scale": "yscale" } 359 | ], 360 | 361 | "marks": [ 362 | { 363 | "type": "rect", 364 | "from": {"data":"table"}, 365 | "encode": { 366 | "enter": { 367 | "x": {"scale": "xscale", "field": "category"}, 368 | "width": {"scale": "xscale", "band": 1}, 369 | "y": {"scale": "yscale", "field": "amount"}, 370 | "y2": {"scale": "yscale", "value": 0}, 371 | "fill": {"value": "steelblue"} 372 | } 373 | } 374 | } 375 | ] 376 | } 377 | ``` 378 | 379 | ```vega 380 | { 381 | "$schema": "https://vega.github.io/schema/vega/v5.json", 382 | "width": 400, 383 | "height": 200, 384 | "padding": 5, 385 | 386 | "data": [ 387 | { 388 | "name": "table", 389 | "values": [ 390 | {"category": "A", "amount": 28}, 391 | {"category": "B", "amount": 55}, 392 | {"category": "C", "amount": 43}, 393 | {"category": "D", "amount": 91}, 394 | {"category": "E", "amount": 81}, 395 | {"category": "F", "amount": 53} 396 | ] 397 | } 398 | ], 399 | 400 | "scales": [ 401 | { 402 | "name": "xscale", 403 | "type": "band", 404 | "domain": {"data": "table", "field": "category"}, 405 | "range": "width", 406 | "padding": 0.05, 407 | "round": true 408 | }, 409 | { 410 | "name": "yscale", 411 | "domain": {"data": "table", "field": "amount"}, 412 | "nice": true, 413 | "range": "height" 414 | } 415 | ], 416 | 417 | "axes": [ 418 | { "orient": "bottom", "scale": "xscale" }, 419 | { "orient": "left", "scale": "yscale" } 420 | ], 421 | 422 | "marks": [ 423 | { 424 | "type": "rect", 425 | "from": {"data":"table"}, 426 | "encode": { 427 | "enter": { 428 | "x": {"scale": "xscale", "field": "category"}, 429 | "width": {"scale": "xscale", "band": 1}, 430 | "y": {"scale": "yscale", "field": "amount"}, 431 | "y2": {"scale": "yscale", "value": 0}, 432 | "fill": {"value": "steelblue"} 433 | } 434 | } 435 | } 436 | ] 437 | } 438 | ``` 439 | -------------------------------------------------------------------------------- /packages/prism/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-blocks/prism", 3 | "version": "0.1.8", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@code-blocks/prism", 9 | "version": "0.1.6", 10 | "license": "GPLv2", 11 | "dependencies": { 12 | "refractor": "^3.1.0", 13 | "rehype": "^11.0.0" 14 | }, 15 | "devDependencies": { 16 | "@code-blocks/types": "^0.1.0", 17 | "@types/refractor": "^2.8.0" 18 | } 19 | }, 20 | "node_modules/@code-blocks/types": { 21 | "version": "0.1.0", 22 | "resolved": "https://registry.npmjs.org/@code-blocks/types/-/types-0.1.0.tgz", 23 | "integrity": "sha512-a3Tm5JuN2xabYgePVjF8uX93efjyhHig+7w5ocvGJg9IQhWtGG96I0Bst1kBDB3DEbEFHDpEuKIgszzUlN6Tyg==", 24 | "dev": true 25 | }, 26 | "node_modules/@types/hast": { 27 | "version": "2.3.2", 28 | "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.2.tgz", 29 | "integrity": "sha512-Op5W7jYgZI7AWKY5wQ0/QNMzQM7dGQPyW1rXKNiymVCy5iTfdPuGu4HhYNOM2sIv8gUfIuIdcYlXmAepwaowow==", 30 | "dependencies": { 31 | "@types/unist": "*" 32 | } 33 | }, 34 | "node_modules/@types/parse5": { 35 | "version": "5.0.3", 36 | "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", 37 | "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" 38 | }, 39 | "node_modules/@types/prismjs": { 40 | "version": "1.16.1", 41 | "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.16.1.tgz", 42 | "integrity": "sha512-RNgcK3FEc1GpeOkamGDq42EYkb6yZW5OWQwTS56NJIB8WL0QGISQglA7En7NUx9RGP8AC52DOe+squqbAckXlA==", 43 | "dev": true 44 | }, 45 | "node_modules/@types/refractor": { 46 | "version": "2.8.0", 47 | "resolved": "https://registry.npmjs.org/@types/refractor/-/refractor-2.8.0.tgz", 48 | "integrity": "sha512-l3wSB96RFZnvB8bnbF8UmYsDD1MQl+u7jtYq+DgI/vo3RD5pdbK3OitGEvMO3DNJhTYmCEhXLVWyyWTddzwNzQ==", 49 | "dev": true, 50 | "dependencies": { 51 | "@types/prismjs": "*" 52 | } 53 | }, 54 | "node_modules/@types/unist": { 55 | "version": "2.0.3", 56 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", 57 | "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" 58 | }, 59 | "node_modules/bail": { 60 | "version": "1.0.5", 61 | "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", 62 | "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", 63 | "funding": { 64 | "type": "github", 65 | "url": "https://github.com/sponsors/wooorm" 66 | } 67 | }, 68 | "node_modules/ccount": { 69 | "version": "1.0.5", 70 | "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz", 71 | "integrity": "sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==", 72 | "funding": { 73 | "type": "github", 74 | "url": "https://github.com/sponsors/wooorm" 75 | } 76 | }, 77 | "node_modules/character-entities": { 78 | "version": "1.2.4", 79 | "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", 80 | "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", 81 | "funding": { 82 | "type": "github", 83 | "url": "https://github.com/sponsors/wooorm" 84 | } 85 | }, 86 | "node_modules/character-entities-html4": { 87 | "version": "1.1.4", 88 | "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", 89 | "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", 90 | "funding": { 91 | "type": "github", 92 | "url": "https://github.com/sponsors/wooorm" 93 | } 94 | }, 95 | "node_modules/character-entities-legacy": { 96 | "version": "1.1.4", 97 | "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", 98 | "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", 99 | "funding": { 100 | "type": "github", 101 | "url": "https://github.com/sponsors/wooorm" 102 | } 103 | }, 104 | "node_modules/character-reference-invalid": { 105 | "version": "1.1.4", 106 | "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", 107 | "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", 108 | "funding": { 109 | "type": "github", 110 | "url": "https://github.com/sponsors/wooorm" 111 | } 112 | }, 113 | "node_modules/comma-separated-tokens": { 114 | "version": "1.0.8", 115 | "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", 116 | "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", 117 | "funding": { 118 | "type": "github", 119 | "url": "https://github.com/sponsors/wooorm" 120 | } 121 | }, 122 | "node_modules/extend": { 123 | "version": "3.0.2", 124 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 125 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 126 | }, 127 | "node_modules/hast-util-from-parse5": { 128 | "version": "6.0.0", 129 | "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.0.tgz", 130 | "integrity": "sha512-3ZYnfKenbbkhhNdmOQqgH10vnvPivTdsOJCri+APn0Kty+nRkDHArnaX9Hiaf8H+Ig+vkNptL+SRY/6RwWJk1Q==", 131 | "dependencies": { 132 | "@types/parse5": "^5.0.0", 133 | "ccount": "^1.0.0", 134 | "hastscript": "^5.0.0", 135 | "property-information": "^5.0.0", 136 | "vfile": "^4.0.0", 137 | "web-namespaces": "^1.0.0" 138 | }, 139 | "funding": { 140 | "type": "opencollective", 141 | "url": "https://opencollective.com/unified" 142 | } 143 | }, 144 | "node_modules/hast-util-is-element": { 145 | "version": "1.0.4", 146 | "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.0.4.tgz", 147 | "integrity": "sha512-NFR6ljJRvDcyPP5SbV7MyPBgF47X3BsskLnmw1U34yL+X6YC0MoBx9EyMg8Jtx4FzGH95jw8+c1VPLHaRA0wDQ==", 148 | "funding": { 149 | "type": "opencollective", 150 | "url": "https://opencollective.com/unified" 151 | } 152 | }, 153 | "node_modules/hast-util-parse-selector": { 154 | "version": "2.2.4", 155 | "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.4.tgz", 156 | "integrity": "sha512-gW3sxfynIvZApL4L07wryYF4+C9VvH3AUi7LAnVXV4MneGEgwOByXvFo18BgmTWnm7oHAe874jKbIB1YhHSIzA==", 157 | "funding": { 158 | "type": "opencollective", 159 | "url": "https://opencollective.com/unified" 160 | } 161 | }, 162 | "node_modules/hast-util-to-html": { 163 | "version": "7.1.1", 164 | "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.1.tgz", 165 | "integrity": "sha512-Ujqj0hGuo3dIQKilkbauAv5teOqPvhaSLEgs1lgApFT0812e114KiffV8XfE4ttR8dRPqxNOIJOMu6SKOVOGlg==", 166 | "dependencies": { 167 | "ccount": "^1.0.0", 168 | "comma-separated-tokens": "^1.0.0", 169 | "hast-util-is-element": "^1.0.0", 170 | "hast-util-whitespace": "^1.0.0", 171 | "html-void-elements": "^1.0.0", 172 | "property-information": "^5.0.0", 173 | "space-separated-tokens": "^1.0.0", 174 | "stringify-entities": "^3.0.1", 175 | "unist-util-is": "^4.0.0", 176 | "xtend": "^4.0.0" 177 | }, 178 | "funding": { 179 | "type": "opencollective", 180 | "url": "https://opencollective.com/unified" 181 | } 182 | }, 183 | "node_modules/hast-util-whitespace": { 184 | "version": "1.0.4", 185 | "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", 186 | "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==", 187 | "funding": { 188 | "type": "opencollective", 189 | "url": "https://opencollective.com/unified" 190 | } 191 | }, 192 | "node_modules/hastscript": { 193 | "version": "5.1.2", 194 | "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.2.tgz", 195 | "integrity": "sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ==", 196 | "dependencies": { 197 | "comma-separated-tokens": "^1.0.0", 198 | "hast-util-parse-selector": "^2.0.0", 199 | "property-information": "^5.0.0", 200 | "space-separated-tokens": "^1.0.0" 201 | }, 202 | "funding": { 203 | "type": "opencollective", 204 | "url": "https://opencollective.com/unified" 205 | } 206 | }, 207 | "node_modules/html-void-elements": { 208 | "version": "1.0.5", 209 | "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", 210 | "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", 211 | "funding": { 212 | "type": "github", 213 | "url": "https://github.com/sponsors/wooorm" 214 | } 215 | }, 216 | "node_modules/is-alphabetical": { 217 | "version": "1.0.4", 218 | "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", 219 | "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", 220 | "funding": { 221 | "type": "github", 222 | "url": "https://github.com/sponsors/wooorm" 223 | } 224 | }, 225 | "node_modules/is-alphanumerical": { 226 | "version": "1.0.4", 227 | "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", 228 | "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", 229 | "dependencies": { 230 | "is-alphabetical": "^1.0.0", 231 | "is-decimal": "^1.0.0" 232 | }, 233 | "funding": { 234 | "type": "github", 235 | "url": "https://github.com/sponsors/wooorm" 236 | } 237 | }, 238 | "node_modules/is-buffer": { 239 | "version": "2.0.4", 240 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", 241 | "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", 242 | "engines": { 243 | "node": ">=4" 244 | } 245 | }, 246 | "node_modules/is-decimal": { 247 | "version": "1.0.4", 248 | "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", 249 | "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", 250 | "funding": { 251 | "type": "github", 252 | "url": "https://github.com/sponsors/wooorm" 253 | } 254 | }, 255 | "node_modules/is-hexadecimal": { 256 | "version": "1.0.4", 257 | "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", 258 | "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", 259 | "funding": { 260 | "type": "github", 261 | "url": "https://github.com/sponsors/wooorm" 262 | } 263 | }, 264 | "node_modules/is-plain-obj": { 265 | "version": "2.1.0", 266 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 267 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 268 | "engines": { 269 | "node": ">=8" 270 | } 271 | }, 272 | "node_modules/parse-entities": { 273 | "version": "2.0.0", 274 | "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", 275 | "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", 276 | "dependencies": { 277 | "character-entities": "^1.0.0", 278 | "character-entities-legacy": "^1.0.0", 279 | "character-reference-invalid": "^1.0.0", 280 | "is-alphanumerical": "^1.0.0", 281 | "is-decimal": "^1.0.0", 282 | "is-hexadecimal": "^1.0.0" 283 | }, 284 | "funding": { 285 | "type": "github", 286 | "url": "https://github.com/sponsors/wooorm" 287 | } 288 | }, 289 | "node_modules/parse5": { 290 | "version": "6.0.1", 291 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", 292 | "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" 293 | }, 294 | "node_modules/prismjs": { 295 | "version": "1.24.1", 296 | "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.24.1.tgz", 297 | "integrity": "sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow==" 298 | }, 299 | "node_modules/property-information": { 300 | "version": "5.5.0", 301 | "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.5.0.tgz", 302 | "integrity": "sha512-RgEbCx2HLa1chNgvChcx+rrCWD0ctBmGSE0M7lVm1yyv4UbvbrWoXp/BkVLZefzjrRBGW8/Js6uh/BnlHXFyjA==", 303 | "dependencies": { 304 | "xtend": "^4.0.0" 305 | }, 306 | "funding": { 307 | "type": "github", 308 | "url": "https://github.com/sponsors/wooorm" 309 | } 310 | }, 311 | "node_modules/refractor": { 312 | "version": "3.4.0", 313 | "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.4.0.tgz", 314 | "integrity": "sha512-dBeD02lC5eytm9Gld2Mx0cMcnR+zhSnsTfPpWqFaMgUMJfC9A6bcN3Br/NaXrnBJcuxnLFR90k1jrkaSyV8umg==", 315 | "dependencies": { 316 | "hastscript": "^6.0.0", 317 | "parse-entities": "^2.0.0", 318 | "prismjs": "~1.24.0" 319 | }, 320 | "funding": { 321 | "type": "github", 322 | "url": "https://github.com/sponsors/wooorm" 323 | } 324 | }, 325 | "node_modules/refractor/node_modules/hastscript": { 326 | "version": "6.0.0", 327 | "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", 328 | "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", 329 | "dependencies": { 330 | "@types/hast": "^2.0.0", 331 | "comma-separated-tokens": "^1.0.0", 332 | "hast-util-parse-selector": "^2.0.0", 333 | "property-information": "^5.0.0", 334 | "space-separated-tokens": "^1.0.0" 335 | }, 336 | "funding": { 337 | "type": "opencollective", 338 | "url": "https://opencollective.com/unified" 339 | } 340 | }, 341 | "node_modules/rehype": { 342 | "version": "11.0.0", 343 | "resolved": "https://registry.npmjs.org/rehype/-/rehype-11.0.0.tgz", 344 | "integrity": "sha512-qXqRqiCFJD5CJ61CSJuNImTFrm3zVkOU9XywHDwrUuvWN74MWt72KJ67c5CM5x8g0vGcOkRVCrYj85vqkmHulQ==", 345 | "dependencies": { 346 | "rehype-parse": "^7.0.0", 347 | "rehype-stringify": "^8.0.0", 348 | "unified": "^9.0.0" 349 | }, 350 | "funding": { 351 | "type": "opencollective", 352 | "url": "https://opencollective.com/unified" 353 | } 354 | }, 355 | "node_modules/rehype-parse": { 356 | "version": "7.0.1", 357 | "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz", 358 | "integrity": "sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw==", 359 | "dependencies": { 360 | "hast-util-from-parse5": "^6.0.0", 361 | "parse5": "^6.0.0" 362 | }, 363 | "funding": { 364 | "type": "opencollective", 365 | "url": "https://opencollective.com/unified" 366 | } 367 | }, 368 | "node_modules/rehype-stringify": { 369 | "version": "8.0.0", 370 | "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-8.0.0.tgz", 371 | "integrity": "sha512-VkIs18G0pj2xklyllrPSvdShAV36Ff3yE5PUO9u36f6+2qJFnn22Z5gKwBOwgXviux4UC7K+/j13AnZfPICi/g==", 372 | "dependencies": { 373 | "hast-util-to-html": "^7.1.1" 374 | }, 375 | "funding": { 376 | "type": "opencollective", 377 | "url": "https://opencollective.com/unified" 378 | } 379 | }, 380 | "node_modules/replace-ext": { 381 | "version": "1.0.0", 382 | "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", 383 | "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", 384 | "engines": { 385 | "node": ">= 0.10" 386 | } 387 | }, 388 | "node_modules/space-separated-tokens": { 389 | "version": "1.1.5", 390 | "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", 391 | "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", 392 | "funding": { 393 | "type": "github", 394 | "url": "https://github.com/sponsors/wooorm" 395 | } 396 | }, 397 | "node_modules/stringify-entities": { 398 | "version": "3.0.1", 399 | "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.0.1.tgz", 400 | "integrity": "sha512-Lsk3ISA2++eJYqBMPKcr/8eby1I6L0gP0NlxF8Zja6c05yr/yCYyb2c9PwXjd08Ib3If1vn1rbs1H5ZtVuOfvQ==", 401 | "dependencies": { 402 | "character-entities-html4": "^1.0.0", 403 | "character-entities-legacy": "^1.0.0", 404 | "is-alphanumerical": "^1.0.0", 405 | "is-decimal": "^1.0.2", 406 | "is-hexadecimal": "^1.0.0" 407 | }, 408 | "funding": { 409 | "type": "github", 410 | "url": "https://github.com/sponsors/wooorm" 411 | } 412 | }, 413 | "node_modules/trough": { 414 | "version": "1.0.5", 415 | "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", 416 | "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", 417 | "funding": { 418 | "type": "github", 419 | "url": "https://github.com/sponsors/wooorm" 420 | } 421 | }, 422 | "node_modules/unified": { 423 | "version": "9.1.0", 424 | "resolved": "https://registry.npmjs.org/unified/-/unified-9.1.0.tgz", 425 | "integrity": "sha512-VXOv7Ic6twsKGJDeZQ2wwPqXs2hM0KNu5Hkg9WgAZbSD1pxhZ7p8swqg583nw1Je2fhwHy6U8aEjiI79x1gvag==", 426 | "dependencies": { 427 | "bail": "^1.0.0", 428 | "extend": "^3.0.0", 429 | "is-buffer": "^2.0.0", 430 | "is-plain-obj": "^2.0.0", 431 | "trough": "^1.0.0", 432 | "vfile": "^4.0.0" 433 | }, 434 | "funding": { 435 | "type": "opencollective", 436 | "url": "https://opencollective.com/unified" 437 | } 438 | }, 439 | "node_modules/unist-util-is": { 440 | "version": "4.0.2", 441 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", 442 | "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==", 443 | "funding": { 444 | "type": "opencollective", 445 | "url": "https://opencollective.com/unified" 446 | } 447 | }, 448 | "node_modules/unist-util-stringify-position": { 449 | "version": "2.0.3", 450 | "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", 451 | "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", 452 | "dependencies": { 453 | "@types/unist": "^2.0.2" 454 | }, 455 | "funding": { 456 | "type": "opencollective", 457 | "url": "https://opencollective.com/unified" 458 | } 459 | }, 460 | "node_modules/vfile": { 461 | "version": "4.2.0", 462 | "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.0.tgz", 463 | "integrity": "sha512-a/alcwCvtuc8OX92rqqo7PflxiCgXRFjdyoGVuYV+qbgCb0GgZJRvIgCD4+U/Kl1yhaRsaTwksF88xbPyGsgpw==", 464 | "dependencies": { 465 | "@types/unist": "^2.0.0", 466 | "is-buffer": "^2.0.0", 467 | "replace-ext": "1.0.0", 468 | "unist-util-stringify-position": "^2.0.0", 469 | "vfile-message": "^2.0.0" 470 | }, 471 | "funding": { 472 | "type": "opencollective", 473 | "url": "https://opencollective.com/unified" 474 | } 475 | }, 476 | "node_modules/vfile-message": { 477 | "version": "2.0.4", 478 | "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", 479 | "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", 480 | "dependencies": { 481 | "@types/unist": "^2.0.0", 482 | "unist-util-stringify-position": "^2.0.0" 483 | }, 484 | "funding": { 485 | "type": "opencollective", 486 | "url": "https://opencollective.com/unified" 487 | } 488 | }, 489 | "node_modules/web-namespaces": { 490 | "version": "1.1.4", 491 | "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", 492 | "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", 493 | "funding": { 494 | "type": "github", 495 | "url": "https://github.com/sponsors/wooorm" 496 | } 497 | }, 498 | "node_modules/xtend": { 499 | "version": "4.0.2", 500 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 501 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 502 | "engines": { 503 | "node": ">=0.4" 504 | } 505 | } 506 | }, 507 | "dependencies": { 508 | "@code-blocks/types": { 509 | "version": "0.1.0", 510 | "resolved": "https://registry.npmjs.org/@code-blocks/types/-/types-0.1.0.tgz", 511 | "integrity": "sha512-a3Tm5JuN2xabYgePVjF8uX93efjyhHig+7w5ocvGJg9IQhWtGG96I0Bst1kBDB3DEbEFHDpEuKIgszzUlN6Tyg==", 512 | "dev": true 513 | }, 514 | "@types/hast": { 515 | "version": "2.3.2", 516 | "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.2.tgz", 517 | "integrity": "sha512-Op5W7jYgZI7AWKY5wQ0/QNMzQM7dGQPyW1rXKNiymVCy5iTfdPuGu4HhYNOM2sIv8gUfIuIdcYlXmAepwaowow==", 518 | "requires": { 519 | "@types/unist": "*" 520 | } 521 | }, 522 | "@types/parse5": { 523 | "version": "5.0.3", 524 | "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", 525 | "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" 526 | }, 527 | "@types/prismjs": { 528 | "version": "1.16.1", 529 | "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.16.1.tgz", 530 | "integrity": "sha512-RNgcK3FEc1GpeOkamGDq42EYkb6yZW5OWQwTS56NJIB8WL0QGISQglA7En7NUx9RGP8AC52DOe+squqbAckXlA==", 531 | "dev": true 532 | }, 533 | "@types/refractor": { 534 | "version": "2.8.0", 535 | "resolved": "https://registry.npmjs.org/@types/refractor/-/refractor-2.8.0.tgz", 536 | "integrity": "sha512-l3wSB96RFZnvB8bnbF8UmYsDD1MQl+u7jtYq+DgI/vo3RD5pdbK3OitGEvMO3DNJhTYmCEhXLVWyyWTddzwNzQ==", 537 | "dev": true, 538 | "requires": { 539 | "@types/prismjs": "*" 540 | } 541 | }, 542 | "@types/unist": { 543 | "version": "2.0.3", 544 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", 545 | "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" 546 | }, 547 | "bail": { 548 | "version": "1.0.5", 549 | "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", 550 | "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" 551 | }, 552 | "ccount": { 553 | "version": "1.0.5", 554 | "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz", 555 | "integrity": "sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==" 556 | }, 557 | "character-entities": { 558 | "version": "1.2.4", 559 | "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", 560 | "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" 561 | }, 562 | "character-entities-html4": { 563 | "version": "1.1.4", 564 | "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", 565 | "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==" 566 | }, 567 | "character-entities-legacy": { 568 | "version": "1.1.4", 569 | "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", 570 | "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" 571 | }, 572 | "character-reference-invalid": { 573 | "version": "1.1.4", 574 | "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", 575 | "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" 576 | }, 577 | "comma-separated-tokens": { 578 | "version": "1.0.8", 579 | "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", 580 | "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" 581 | }, 582 | "extend": { 583 | "version": "3.0.2", 584 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 585 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 586 | }, 587 | "hast-util-from-parse5": { 588 | "version": "6.0.0", 589 | "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.0.tgz", 590 | "integrity": "sha512-3ZYnfKenbbkhhNdmOQqgH10vnvPivTdsOJCri+APn0Kty+nRkDHArnaX9Hiaf8H+Ig+vkNptL+SRY/6RwWJk1Q==", 591 | "requires": { 592 | "@types/parse5": "^5.0.0", 593 | "ccount": "^1.0.0", 594 | "hastscript": "^5.0.0", 595 | "property-information": "^5.0.0", 596 | "vfile": "^4.0.0", 597 | "web-namespaces": "^1.0.0" 598 | } 599 | }, 600 | "hast-util-is-element": { 601 | "version": "1.0.4", 602 | "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.0.4.tgz", 603 | "integrity": "sha512-NFR6ljJRvDcyPP5SbV7MyPBgF47X3BsskLnmw1U34yL+X6YC0MoBx9EyMg8Jtx4FzGH95jw8+c1VPLHaRA0wDQ==" 604 | }, 605 | "hast-util-parse-selector": { 606 | "version": "2.2.4", 607 | "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.4.tgz", 608 | "integrity": "sha512-gW3sxfynIvZApL4L07wryYF4+C9VvH3AUi7LAnVXV4MneGEgwOByXvFo18BgmTWnm7oHAe874jKbIB1YhHSIzA==" 609 | }, 610 | "hast-util-to-html": { 611 | "version": "7.1.1", 612 | "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.1.tgz", 613 | "integrity": "sha512-Ujqj0hGuo3dIQKilkbauAv5teOqPvhaSLEgs1lgApFT0812e114KiffV8XfE4ttR8dRPqxNOIJOMu6SKOVOGlg==", 614 | "requires": { 615 | "ccount": "^1.0.0", 616 | "comma-separated-tokens": "^1.0.0", 617 | "hast-util-is-element": "^1.0.0", 618 | "hast-util-whitespace": "^1.0.0", 619 | "html-void-elements": "^1.0.0", 620 | "property-information": "^5.0.0", 621 | "space-separated-tokens": "^1.0.0", 622 | "stringify-entities": "^3.0.1", 623 | "unist-util-is": "^4.0.0", 624 | "xtend": "^4.0.0" 625 | } 626 | }, 627 | "hast-util-whitespace": { 628 | "version": "1.0.4", 629 | "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", 630 | "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==" 631 | }, 632 | "hastscript": { 633 | "version": "5.1.2", 634 | "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.2.tgz", 635 | "integrity": "sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ==", 636 | "requires": { 637 | "comma-separated-tokens": "^1.0.0", 638 | "hast-util-parse-selector": "^2.0.0", 639 | "property-information": "^5.0.0", 640 | "space-separated-tokens": "^1.0.0" 641 | } 642 | }, 643 | "html-void-elements": { 644 | "version": "1.0.5", 645 | "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", 646 | "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==" 647 | }, 648 | "is-alphabetical": { 649 | "version": "1.0.4", 650 | "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", 651 | "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" 652 | }, 653 | "is-alphanumerical": { 654 | "version": "1.0.4", 655 | "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", 656 | "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", 657 | "requires": { 658 | "is-alphabetical": "^1.0.0", 659 | "is-decimal": "^1.0.0" 660 | } 661 | }, 662 | "is-buffer": { 663 | "version": "2.0.4", 664 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", 665 | "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" 666 | }, 667 | "is-decimal": { 668 | "version": "1.0.4", 669 | "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", 670 | "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" 671 | }, 672 | "is-hexadecimal": { 673 | "version": "1.0.4", 674 | "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", 675 | "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" 676 | }, 677 | "is-plain-obj": { 678 | "version": "2.1.0", 679 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 680 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" 681 | }, 682 | "parse-entities": { 683 | "version": "2.0.0", 684 | "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", 685 | "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", 686 | "requires": { 687 | "character-entities": "^1.0.0", 688 | "character-entities-legacy": "^1.0.0", 689 | "character-reference-invalid": "^1.0.0", 690 | "is-alphanumerical": "^1.0.0", 691 | "is-decimal": "^1.0.0", 692 | "is-hexadecimal": "^1.0.0" 693 | } 694 | }, 695 | "parse5": { 696 | "version": "6.0.1", 697 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", 698 | "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" 699 | }, 700 | "prismjs": { 701 | "version": "1.24.1", 702 | "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.24.1.tgz", 703 | "integrity": "sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow==" 704 | }, 705 | "property-information": { 706 | "version": "5.5.0", 707 | "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.5.0.tgz", 708 | "integrity": "sha512-RgEbCx2HLa1chNgvChcx+rrCWD0ctBmGSE0M7lVm1yyv4UbvbrWoXp/BkVLZefzjrRBGW8/Js6uh/BnlHXFyjA==", 709 | "requires": { 710 | "xtend": "^4.0.0" 711 | } 712 | }, 713 | "refractor": { 714 | "version": "3.4.0", 715 | "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.4.0.tgz", 716 | "integrity": "sha512-dBeD02lC5eytm9Gld2Mx0cMcnR+zhSnsTfPpWqFaMgUMJfC9A6bcN3Br/NaXrnBJcuxnLFR90k1jrkaSyV8umg==", 717 | "requires": { 718 | "hastscript": "^6.0.0", 719 | "parse-entities": "^2.0.0", 720 | "prismjs": "~1.24.0" 721 | }, 722 | "dependencies": { 723 | "hastscript": { 724 | "version": "6.0.0", 725 | "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", 726 | "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", 727 | "requires": { 728 | "@types/hast": "^2.0.0", 729 | "comma-separated-tokens": "^1.0.0", 730 | "hast-util-parse-selector": "^2.0.0", 731 | "property-information": "^5.0.0", 732 | "space-separated-tokens": "^1.0.0" 733 | } 734 | } 735 | } 736 | }, 737 | "rehype": { 738 | "version": "11.0.0", 739 | "resolved": "https://registry.npmjs.org/rehype/-/rehype-11.0.0.tgz", 740 | "integrity": "sha512-qXqRqiCFJD5CJ61CSJuNImTFrm3zVkOU9XywHDwrUuvWN74MWt72KJ67c5CM5x8g0vGcOkRVCrYj85vqkmHulQ==", 741 | "requires": { 742 | "rehype-parse": "^7.0.0", 743 | "rehype-stringify": "^8.0.0", 744 | "unified": "^9.0.0" 745 | } 746 | }, 747 | "rehype-parse": { 748 | "version": "7.0.1", 749 | "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz", 750 | "integrity": "sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw==", 751 | "requires": { 752 | "hast-util-from-parse5": "^6.0.0", 753 | "parse5": "^6.0.0" 754 | } 755 | }, 756 | "rehype-stringify": { 757 | "version": "8.0.0", 758 | "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-8.0.0.tgz", 759 | "integrity": "sha512-VkIs18G0pj2xklyllrPSvdShAV36Ff3yE5PUO9u36f6+2qJFnn22Z5gKwBOwgXviux4UC7K+/j13AnZfPICi/g==", 760 | "requires": { 761 | "hast-util-to-html": "^7.1.1" 762 | } 763 | }, 764 | "replace-ext": { 765 | "version": "1.0.0", 766 | "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", 767 | "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" 768 | }, 769 | "space-separated-tokens": { 770 | "version": "1.1.5", 771 | "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", 772 | "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" 773 | }, 774 | "stringify-entities": { 775 | "version": "3.0.1", 776 | "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.0.1.tgz", 777 | "integrity": "sha512-Lsk3ISA2++eJYqBMPKcr/8eby1I6L0gP0NlxF8Zja6c05yr/yCYyb2c9PwXjd08Ib3If1vn1rbs1H5ZtVuOfvQ==", 778 | "requires": { 779 | "character-entities-html4": "^1.0.0", 780 | "character-entities-legacy": "^1.0.0", 781 | "is-alphanumerical": "^1.0.0", 782 | "is-decimal": "^1.0.2", 783 | "is-hexadecimal": "^1.0.0" 784 | } 785 | }, 786 | "trough": { 787 | "version": "1.0.5", 788 | "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", 789 | "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" 790 | }, 791 | "unified": { 792 | "version": "9.1.0", 793 | "resolved": "https://registry.npmjs.org/unified/-/unified-9.1.0.tgz", 794 | "integrity": "sha512-VXOv7Ic6twsKGJDeZQ2wwPqXs2hM0KNu5Hkg9WgAZbSD1pxhZ7p8swqg583nw1Je2fhwHy6U8aEjiI79x1gvag==", 795 | "requires": { 796 | "bail": "^1.0.0", 797 | "extend": "^3.0.0", 798 | "is-buffer": "^2.0.0", 799 | "is-plain-obj": "^2.0.0", 800 | "trough": "^1.0.0", 801 | "vfile": "^4.0.0" 802 | } 803 | }, 804 | "unist-util-is": { 805 | "version": "4.0.2", 806 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", 807 | "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" 808 | }, 809 | "unist-util-stringify-position": { 810 | "version": "2.0.3", 811 | "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", 812 | "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", 813 | "requires": { 814 | "@types/unist": "^2.0.2" 815 | } 816 | }, 817 | "vfile": { 818 | "version": "4.2.0", 819 | "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.0.tgz", 820 | "integrity": "sha512-a/alcwCvtuc8OX92rqqo7PflxiCgXRFjdyoGVuYV+qbgCb0GgZJRvIgCD4+U/Kl1yhaRsaTwksF88xbPyGsgpw==", 821 | "requires": { 822 | "@types/unist": "^2.0.0", 823 | "is-buffer": "^2.0.0", 824 | "replace-ext": "1.0.0", 825 | "unist-util-stringify-position": "^2.0.0", 826 | "vfile-message": "^2.0.0" 827 | } 828 | }, 829 | "vfile-message": { 830 | "version": "2.0.4", 831 | "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", 832 | "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", 833 | "requires": { 834 | "@types/unist": "^2.0.0", 835 | "unist-util-stringify-position": "^2.0.0" 836 | } 837 | }, 838 | "web-namespaces": { 839 | "version": "1.1.4", 840 | "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", 841 | "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==" 842 | }, 843 | "xtend": { 844 | "version": "4.0.2", 845 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 846 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" 847 | } 848 | } 849 | } 850 | --------------------------------------------------------------------------------