├── .editorconfig ├── .gitattributes ├── .github └── workflows │ └── main.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE.md ├── README.md ├── __snapshots__ └── packages │ ├── remark-bibliography │ └── src │ │ ├── bibjson.spec.ts.md │ │ └── bibjson.spec.ts.snap │ ├── remark-deflist │ └── src │ │ ├── index.spec.ts.md │ │ └── index.spec.ts.snap │ ├── remark-redirect │ └── src │ │ ├── index.spec.ts.md │ │ └── index.spec.ts.snap │ └── remark-supersub │ └── src │ ├── index.spec.ts.md │ └── index.spec.ts.snap ├── lerna.json ├── package-lock.json ├── package.json ├── packages ├── remark-bibliography │ ├── LICENSE.md │ ├── README.md │ ├── examples │ │ ├── example.html │ │ ├── example.json │ │ └── example.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── bibjson.spec.ts │ │ ├── bibjson.ts │ │ ├── citations.spec.ts.bak │ │ ├── citations.ts │ │ ├── index.spec.ts.bak │ │ ├── index.ts │ │ ├── types │ │ │ ├── citeproc.d.ts │ │ │ ├── locales.d.ts │ │ │ └── styles.d.ts │ │ └── utils │ │ │ ├── date.ts │ │ │ └── name.ts │ └── tsconfig.json ├── remark-deflist │ ├── LICENSE.md │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── index.spec.ts │ │ └── index.ts │ └── tsconfig.json ├── remark-meta │ ├── LICENSE.md │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── remark-redirect │ ├── LICENSE.md │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── index.spec.ts │ │ └── index.ts │ └── tsconfig.json └── remark-supersub │ ├── LICENSE.md │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── index.spec.ts │ └── index.ts │ └── tsconfig.json └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | tab_width = 2 10 | trim_trailing_whitespace = true 11 | max_line_length = 80 12 | 13 | [*.md] 14 | insert_final_newline = false 15 | trim_trailing_whitespace = false 16 | indent_size = 4 17 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: main 2 | 3 | on: 4 | - pull_request 5 | - push 6 | 7 | jobs: 8 | main: 9 | name: "${{ matrix.node }}" 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | node: 14 | - 14 15 | - 15 16 | steps: 17 | - uses: actions/checkout@v2 18 | - uses: actions/setup-node@v1 19 | with: 20 | node-version: ${{ matrix.node }} 21 | - run: npm install 22 | - run: npm run test 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.ini 2 | .DS_Store 3 | /node_modules 4 | /packages/*/node_modules 5 | /packages/*/coverage 6 | /packages/*/.nyc_output 7 | /packages/*/lib 8 | /.nyc_output/* 9 | /coverage/* 10 | npm-debug.log 11 | lerna-debug.log 12 | .idea 13 | .c9 14 | .vscode 15 | /tmp 16 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | - Using welcoming and inclusive language 12 | - Being respectful of differing viewpoints and experiences 13 | - Gracefully accepting constructive criticism 14 | - Focusing on what is best for the community 15 | - Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | - The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | - Trolling, insulting/derogatory comments, and personal or political attacks 21 | - Public or private harassment 22 | - Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | - Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting Alex Shaw . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version 1.4, available at [https://contributor-covenant.org/version/1/4](https://contributor-covenant.org/version/1/4/). 44 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright © Alex Shaw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Remark Plugins 2 | 3 | [![CI/CD Status](https://github.com/Symbitic/remark-plugins/workflows/main/badge.svg)](https://github.com/Symbitic/remark-plugins/actions) 4 | [![MIT License](https://img.shields.io/github/license/Symbitic/remark-plugins)](https://github.com/Symbitic/remark-plugins/blob/master/LICENSE.md) 5 | [![stars](https://img.shields.io/github/stars/Symbitic/remark-plugins.svg)](https://github.com/Symbitic/remark-plugins) 6 | 7 | This is a collection of [**remark**](https://remark.js.org) plugins that were developed as part of my other project: [Markbook](https://github.com/Symbitic/markbook) 8 | 9 | Feel free to contribute by submitting pull requests. Just make sure you follow the [Code of Conduct](CODE_OF_CONDUCT.md) and your submissions include unit tests. 10 | 11 | [![BuyMeACoffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://buymeacoff.ee/qh0rXkiCd) 12 | 13 | ## Packages 14 | 15 | * [**remark-bibliography**](packages/remark-bibliography/README.md) 16 | 17 | Adds support for citations syntax and references using an external bibliography. Supports BibJSON and Chicago-style citations. Requires `remark-meta`. 18 | 19 | * [**remark-deflist**](packages/remark-deflist/README.md) 20 | 21 | Adds support for pandoc-style definition lists syntax. 22 | 23 | * [**remark-meta**](packages/remark-meta/README.md) 24 | 25 | Add YAML/TOML metadata to a VFile during processing. Requires [remark-frontmatter](https://npmjs.com/package/remark-frontmatter). 26 | 27 | * [**remark-redirect**](packages/remark-redirect/README.md) 28 | 29 | Changes links that refer to `.md` so that they will refer to `.html` instead (useful for rendering multiple files). Also changes links to `README.md` into `index.html` 30 | 31 | * [**remark-supersub**](packages/remark-supersub/README.md) 32 | 33 | Add support for Subscript and Superscript syntax. 34 | 35 | ## License 36 | 37 | [MIT](LICENSE.md) © Alex Shaw 38 | -------------------------------------------------------------------------------- /__snapshots__/packages/remark-bibliography/src/bibjson.spec.ts.md: -------------------------------------------------------------------------------- 1 | # Snapshot report for `packages/remark-bibliography/src/bibjson.spec.ts` 2 | 3 | The actual snapshot is saved in `bibjson.spec.ts.snap`. 4 | 5 | Generated by [AVA](https://avajs.dev). 6 | 7 | ## bibjson should parse a a basic entry 8 | 9 | > Snapshot 1 10 | 11 | { 12 | gregory2014: { 13 | DOI: '10.1186/1758-2946-3-47', 14 | URL: 'http://www.gameenginebook.com/', 15 | author: [ 16 | { 17 | family: 'Gregory', 18 | given: 'Jason', 19 | }, 20 | ], 21 | id: 'gregory2014', 22 | issued: { 23 | 'date-parts': [ 24 | [ 25 | 2014, 26 | ], 27 | ], 28 | }, 29 | publisher: 'CRC Press', 30 | title: 'Game Engine Architecture, Second Edition.', 31 | type: 'book', 32 | }, 33 | } 34 | -------------------------------------------------------------------------------- /__snapshots__/packages/remark-bibliography/src/bibjson.spec.ts.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Symbitic/remark-plugins/a1bfb2a02cd6c9c2385a732f95ae44f07d03284f/__snapshots__/packages/remark-bibliography/src/bibjson.spec.ts.snap -------------------------------------------------------------------------------- /__snapshots__/packages/remark-deflist/src/index.spec.ts.md: -------------------------------------------------------------------------------- 1 | # Snapshot report for `packages/remark-deflist/src/index.spec.ts` 2 | 3 | The actual snapshot is saved in `index.spec.ts.snap`. 4 | 5 | Generated by [AVA](https://avajs.dev). 6 | 7 | ## remark-deflist should parse a basic definition list 8 | 9 | > Snapshot 1 10 | 11 | '
Term 1
Definition 1
' 12 | 13 | ## remark-deflist should parse a definition list with inline markup 14 | 15 | > Snapshot 1 16 | 17 | '
Term 1
Definition 1
' 18 | 19 | ## remark-deflist should parse a document with other elements 20 | 21 | > Snapshot 1 22 | 23 | `
Definition List
Definition 1
␊ 24 |

This paragraph follows the definition list.

` 25 | 26 | ## remark-deflist should parse a definition list with continuation 27 | 28 | > Snapshot 1 29 | 30 | `
Term 1
Definition␊ 31 | with continuation.
` 32 | 33 | ## remark-deflist should parse a definition list with lazy continuation 34 | 35 | > Snapshot 1 36 | 37 | `
Term 1
Definition␊ 38 | with lazy continuation.
` 39 | 40 | ## remark-deflist should parse a definition list with no space between the term and the descriptions (#7) 41 | 42 | > Snapshot 1 43 | 44 | '
Term 1
Definition bold 1
Definition 2
' 45 | 46 | ## remark-deflist should parse a definition list with multiple descriptions (#9) 47 | 48 | > Snapshot 1 49 | 50 | '
Multiple descriptions
Description 1
Description 2
' 51 | 52 | ## remark-deflist should parse a document with several subsequent definition lists (#10) 53 | 54 | > Snapshot 1 55 | 56 | '
Definition List 1
Description 1
Definition List 2
Description 1
Definition List 3
Description 1
' 57 | -------------------------------------------------------------------------------- /__snapshots__/packages/remark-deflist/src/index.spec.ts.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Symbitic/remark-plugins/a1bfb2a02cd6c9c2385a732f95ae44f07d03284f/__snapshots__/packages/remark-deflist/src/index.spec.ts.snap -------------------------------------------------------------------------------- /__snapshots__/packages/remark-redirect/src/index.spec.ts.md: -------------------------------------------------------------------------------- 1 | # Snapshot report for `packages/remark-redirect/src/index.spec.ts` 2 | 3 | The actual snapshot is saved in `index.spec.ts.snap`. 4 | 5 | Generated by [AVA](https://avajs.dev). 6 | 7 | ## remark-redirect should parse a basic link 8 | 9 | > Snapshot 1 10 | 11 | '

README

' 12 | -------------------------------------------------------------------------------- /__snapshots__/packages/remark-redirect/src/index.spec.ts.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Symbitic/remark-plugins/a1bfb2a02cd6c9c2385a732f95ae44f07d03284f/__snapshots__/packages/remark-redirect/src/index.spec.ts.snap -------------------------------------------------------------------------------- /__snapshots__/packages/remark-supersub/src/index.spec.ts.md: -------------------------------------------------------------------------------- 1 | # Snapshot report for `packages/remark-supersub/src/index.spec.ts` 2 | 3 | The actual snapshot is saved in `index.spec.ts.snap`. 4 | 5 | Generated by [AVA](https://avajs.dev). 6 | 7 | ## remark-supersub should parse a basic supersub list 8 | 9 | > Snapshot 1 10 | 11 | `

21st Century

␊ 12 |

H2O

` 13 | -------------------------------------------------------------------------------- /__snapshots__/packages/remark-supersub/src/index.spec.ts.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Symbitic/remark-plugins/a1bfb2a02cd6c9c2385a732f95ae44f07d03284f/__snapshots__/packages/remark-supersub/src/index.spec.ts.snap -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "packages": [ 4 | "packages/*" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remark-plugins", 3 | "private": true, 4 | "license": "MIT", 5 | "repository": "github:Symbitic/remark-plugins", 6 | "scripts": { 7 | "coverage": "jest --coverage", 8 | "postinstall": "npm run bootstrap", 9 | "bootstrap": "lerna bootstrap", 10 | "build": "lerna run build", 11 | "test": "ava", 12 | "prepublishOnly": "npm run build", 13 | "publish": "lerna publish" 14 | }, 15 | "jest": { 16 | "testMatch": [ 17 | "**/packages/**/*.spec.ts" 18 | ], 19 | "transform": { 20 | "^.+\\.(t|j)sx?$": "ts-jest" 21 | } 22 | }, 23 | "ava": { 24 | "extensions": { 25 | "ts": "module" 26 | }, 27 | "nonSemVerExperiments": { 28 | "configurableModuleFormat": true 29 | }, 30 | "nodeArguments": [ 31 | "--loader=ts-node/esm", 32 | "--no-warnings=ExperimentalWarning" 33 | ], 34 | "snapshotDir": "__snapshots__" 35 | }, 36 | "devDependencies": { 37 | "@types/jest": "^26.0.24", 38 | "@types/js-yaml": "^4.0.2", 39 | "@types/mdast": "^3.0.7", 40 | "@types/node": "^16.6.1", 41 | "@types/unist": "^2.0.6", 42 | "ava": "^3.15.0", 43 | "jest": "^27.0.6", 44 | "lerna": "^4.0.0", 45 | "rehype-stringify": "^9.0.1", 46 | "remark": "^14.0.1", 47 | "remark-parse": "^10.0.0", 48 | "remark-rehype": "^9.0.0", 49 | "rimraf": "^3.0.2", 50 | "ts-jest": "^27.0.4", 51 | "typescript": "^4.3.5", 52 | "unified": "^10.1.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/remark-bibliography/LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright © Alex Shaw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/remark-bibliography/README.md: -------------------------------------------------------------------------------- 1 | # remark-bibliography 2 | 3 | [![CI/CD Status](https://github.com/Symbitic/remark-plugins/workflows/main/badge.svg)](https://github.com/Symbitic/remark-plugins/actions) 4 | [![MIT License](https://img.shields.io/github/license/Symbitic/remark-plugins)](https://github.com/Symbitic/remark-plugins/blob/master/LICENSE.md) 5 | [![stars](https://img.shields.io/github/stars/Symbitic/remark-plugins.svg)](https://github.com/Symbitic/remark-plugins) 6 | 7 | [Remark](https://remark.js.org/) plugin for adding citations and bibliographies to Markdown documents. 8 | 9 | Bibliographies are included by specifying the `bibliography` field in the YAML frontmatter metadata 10 | at the top of each document. Inline citations simply use @ followed by the name of the source. 11 | A complete bibliography will then be appended to the bottom of the output. See the example below for more details. 12 | 13 | This plugin requires [remark-meta](../remark-meta/README.md) to resolve the path to bibliography files. 14 | Files are resolved relative to the path of the markdown file. 15 | 16 | BibJSON is the only format currently supported, but support for other formats like BibTeX, 17 | MODS, and RIS is planned. Pull requests are welcome. 18 | 19 | ## Install 20 | 21 | This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): 22 | Node 12+ is needed to use it and it must be `import`ed instead of `require`d. 23 | 24 | [npm](https://docs.npmjs.com/cli/install): 25 | 26 | ```sh 27 | npm install remark-bibliography 28 | ``` 29 | 30 | ## Example 31 | 32 | Consider the following example: 33 | ``` 34 | --- 35 | bibliography: example.json 36 | locale: en-us 37 | style: chicago 38 | --- 39 | 40 | # Example Bibliography 41 | 42 | Example citation: 43 | 44 | Vulkan has better support for multithreading than OpenGL (@singh2016) 45 | 46 | See the full reference for this citation below: 47 | ``` 48 | 49 | When given a bibliography file [example/example.json](example/example.json), 50 | the result will look something like this: [examples/example.html](examples/example.html) 51 | 52 | ## Configuring 53 | 54 | remark-bibliography is configured using several metadata fields in each document. 55 | 56 | ### `bibliography` 57 | 58 | Required. Specifies the path to the bibliography file, relative to the current file. 59 | 60 | ### `locale` 61 | 62 | Which locale the citations use. Supported options: 63 | `de-de`, `en-gb`, `en-us`, `es-es`, and `fr-fr` (default: `en-us`). 64 | 65 | ### `style` 66 | 67 | Which citation style to use for inline citations and the bibliography. 68 | Supported options: `apa`, `chicago`, `mla`, and `vancouver` (default: `chicago`). 69 | 70 | ## Usage 71 | 72 | ```javascript 73 | import { unified } from 'unified' 74 | import markdown from 'remark-parse' 75 | import html from 'rehype-stringify' 76 | import remark2rehype from 'remark-rehype' 77 | import bibliography from 'remark-bibliography' 78 | import frontmatter from 'remark-frontmatter' 79 | import meta from 'remark-meta' 80 | 81 | unified() 82 | .use(markdown) 83 | .use(frontmatter) 84 | .use(meta) 85 | .use(bibliography) 86 | .use(remark2rehype) 87 | .use(html) 88 | ``` 89 | 90 | ## License 91 | 92 | [MIT](LICENSE.md) © Alex Shaw 93 | -------------------------------------------------------------------------------- /packages/remark-bibliography/examples/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Example Bibliography

4 |

Example citation:

5 |

Vulkan has better support for multithreading than OpenGL (Singh 2016)

6 |

See the full reference for this citation below:

7 |

References

    8 |
  1. Akenine-Moller, Thomas, Eric Haines, and Naty Hoffman. 2008. Real Time Rendering, Third Edition. CRC Press. http://www.realtimerendering.com/.
  2. 9 |
  3. Gregory, Jason. 2014. Game Engine Architecture, Second Edition. CRC Press. https://doi.org/10.1186/1758-2946-3-47.
  4. 10 |
  5. Singh, Parminder. 2016. Vulkan Essentials. Packt Publishing. https://www.packtpub.com/application-development/vulkan-essentials.
  6. 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/remark-bibliography/examples/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "gregory2014": { 3 | "title": "Game Engine Architecture, Second Edition.", 4 | "author": [ 5 | { 6 | "name": "Jason Gregory" 7 | } 8 | ], 9 | "type": "book", 10 | "year": "2014", 11 | "publisher": "CRC Press", 12 | "link": [ 13 | { 14 | "url": "http://www.gameenginebook.com/" 15 | } 16 | ], 17 | "identifier": [ 18 | { 19 | "type": "doi", 20 | "id": "10.1186/1758-2946-3-47" 21 | } 22 | ] 23 | }, 24 | "singh2016": { 25 | "title": "Vulkan Essentials", 26 | "author": [ 27 | { 28 | "name": "Parminder Singh" 29 | } 30 | ], 31 | "type": "book", 32 | "year": "2016", 33 | "publisher": "Packt Publishing", 34 | "link": [ 35 | { 36 | "url": "https://www.packtpub.com/application-development/vulkan-essentials" 37 | } 38 | ] 39 | }, 40 | "moller2008": { 41 | "title": "Real Time Rendering, Third Edition", 42 | "author": [ 43 | { 44 | "name": "Akenine-Moller, Thomas" 45 | }, 46 | { 47 | "name": "Haines, Eric" 48 | }, 49 | { 50 | "name": "Hoffman, Naty" 51 | } 52 | ], 53 | "type": "book", 54 | "year": "2008", 55 | "publisher": "CRC Press", 56 | "link": [ 57 | { 58 | "url": "http://www.realtimerendering.com/" 59 | } 60 | ] 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /packages/remark-bibliography/examples/example.md: -------------------------------------------------------------------------------- 1 | --- 2 | bibliography: example.json 3 | --- 4 | 5 | # Example Bibliography 6 | 7 | Example citation: 8 | 9 | Vulkan has better support for multithreading than OpenGL (@singh2016) 10 | 11 | See the full reference for this citation below: 12 | 13 | -------------------------------------------------------------------------------- /packages/remark-bibliography/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remark-bibliography", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "0.3.0", 9 | "license": "MIT", 10 | "dependencies": { 11 | "citeproc": "^2.4.59", 12 | "locale-de-de": "^0.0.2", 13 | "locale-en-gb": "^0.0.2", 14 | "locale-en-us": "^0.0.2", 15 | "locale-es-es": "^0.0.2", 16 | "locale-fr-fr": "^0.0.2", 17 | "style-apa": "^0.0.2", 18 | "style-chicago": "^0.0.2", 19 | "style-mla": "^0.0.2", 20 | "style-vancouver": "^0.0.2", 21 | "unist-util-visit": "^4.0.0" 22 | } 23 | }, 24 | "node_modules/@types/unist": { 25 | "version": "2.0.6", 26 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", 27 | "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" 28 | }, 29 | "node_modules/citeproc": { 30 | "version": "2.4.59", 31 | "resolved": "https://registry.npmjs.org/citeproc/-/citeproc-2.4.59.tgz", 32 | "integrity": "sha512-BoOk7hu2ORheW2TT//Xj6AFnyP9CuVuQ6THBYTRXO3wEYTMviPbcyXFiZ/tPg5bijvvvVa4gPJRVnipQ0y2aKw==" 33 | }, 34 | "node_modules/locale-de-de": { 35 | "version": "0.0.2", 36 | "resolved": "https://registry.npmjs.org/locale-de-de/-/locale-de-de-0.0.2.tgz", 37 | "integrity": "sha512-foCqbDgfcvdLqKX4hxFfPb6m9KXuvzOdMQT1vjCzwIK4BjqLC7d6TeWxHMaIF5B9tHxKrEb0POI49sJGFNjxHA==" 38 | }, 39 | "node_modules/locale-en-gb": { 40 | "version": "0.0.2", 41 | "resolved": "https://registry.npmjs.org/locale-en-gb/-/locale-en-gb-0.0.2.tgz", 42 | "integrity": "sha512-Z/9xQDlDoMhaIEPMQz9VoB8zbKlI6CgO9ScVl3urJeKJI6qViZNGpS7h/ycBGC0AJcrE3I4J72XmiSgVCyK0kA==" 43 | }, 44 | "node_modules/locale-en-us": { 45 | "version": "0.0.2", 46 | "resolved": "https://registry.npmjs.org/locale-en-us/-/locale-en-us-0.0.2.tgz", 47 | "integrity": "sha512-I02W/LK36C1IDloiFY4ZvK7kIs4C92vCHVEI01rIrJPzzlqcn1NnUxn5d1oiq0pe6JwuzpWwSCYnV0o1WAQP9g==" 48 | }, 49 | "node_modules/locale-es-es": { 50 | "version": "0.0.2", 51 | "resolved": "https://registry.npmjs.org/locale-es-es/-/locale-es-es-0.0.2.tgz", 52 | "integrity": "sha512-Hw0DO46yuMJlGbgzjyiu6Q8OEaSQ+DBWNvhCX7apGC8NJwzY7pNoFUDDm3DtxAZ9W2F/33548/+C7BTOfeF7Eg==" 53 | }, 54 | "node_modules/locale-fr-fr": { 55 | "version": "0.0.2", 56 | "resolved": "https://registry.npmjs.org/locale-fr-fr/-/locale-fr-fr-0.0.2.tgz", 57 | "integrity": "sha512-KS9t0SrAmy2+T74zKNQUsj5Bn1EyLl+/2aIxnD/FCvQrVlADnuuwMvLQRx0W7uU4hmEtRhpsfKTA40mHPbvVXg==" 58 | }, 59 | "node_modules/style-apa": { 60 | "version": "0.0.2", 61 | "resolved": "https://registry.npmjs.org/style-apa/-/style-apa-0.0.2.tgz", 62 | "integrity": "sha512-DSgE7KPxV0Z3o5j4mAOGWp+Dpl9KhPUS5+704lEsVCI0G/LjbnvoINJUWn2llrYR95PH9Dkw0M9fiTt/BwEAoA==" 63 | }, 64 | "node_modules/style-chicago": { 65 | "version": "0.0.2", 66 | "resolved": "https://registry.npmjs.org/style-chicago/-/style-chicago-0.0.2.tgz", 67 | "integrity": "sha512-xQyPhA3eLMmpV2BQ9+OwxYy6RgUIrxbXFxH6Demd8QlBQpXvj5rkZNn3YpEMyvoAinghFjZOGGuaBDCYiZxFxQ==" 68 | }, 69 | "node_modules/style-mla": { 70 | "version": "0.0.2", 71 | "resolved": "https://registry.npmjs.org/style-mla/-/style-mla-0.0.2.tgz", 72 | "integrity": "sha512-uxe00Gcv8W5Rgie8QStLnMlZh4o821UwWclr+SfgMNCRRVF8ncB9wvqU093FcS2QR02V8/YNE0P2ySJ2GFIFSw==" 73 | }, 74 | "node_modules/style-vancouver": { 75 | "version": "0.0.2", 76 | "resolved": "https://registry.npmjs.org/style-vancouver/-/style-vancouver-0.0.2.tgz", 77 | "integrity": "sha512-6DYqSJSRPdPYPZB64LAKjhX6IBpbI8G2QJg0qsgGE6vLMvWG/8tTpuzdIsZPDMPBMnF2jt/1WBqbDZR4VaA2KQ==" 78 | }, 79 | "node_modules/unist-util-is": { 80 | "version": "5.1.1", 81 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", 82 | "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", 83 | "funding": { 84 | "type": "opencollective", 85 | "url": "https://opencollective.com/unified" 86 | } 87 | }, 88 | "node_modules/unist-util-visit": { 89 | "version": "4.0.0", 90 | "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", 91 | "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", 92 | "dependencies": { 93 | "@types/unist": "^2.0.0", 94 | "unist-util-is": "^5.0.0", 95 | "unist-util-visit-parents": "^5.0.0" 96 | }, 97 | "funding": { 98 | "type": "opencollective", 99 | "url": "https://opencollective.com/unified" 100 | } 101 | }, 102 | "node_modules/unist-util-visit-parents": { 103 | "version": "5.0.0", 104 | "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", 105 | "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", 106 | "dependencies": { 107 | "@types/unist": "^2.0.0", 108 | "unist-util-is": "^5.0.0" 109 | }, 110 | "funding": { 111 | "type": "opencollective", 112 | "url": "https://opencollective.com/unified" 113 | } 114 | } 115 | }, 116 | "dependencies": { 117 | "@types/unist": { 118 | "version": "2.0.6", 119 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", 120 | "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" 121 | }, 122 | "citeproc": { 123 | "version": "2.4.59", 124 | "resolved": "https://registry.npmjs.org/citeproc/-/citeproc-2.4.59.tgz", 125 | "integrity": "sha512-BoOk7hu2ORheW2TT//Xj6AFnyP9CuVuQ6THBYTRXO3wEYTMviPbcyXFiZ/tPg5bijvvvVa4gPJRVnipQ0y2aKw==" 126 | }, 127 | "locale-de-de": { 128 | "version": "0.0.2", 129 | "resolved": "https://registry.npmjs.org/locale-de-de/-/locale-de-de-0.0.2.tgz", 130 | "integrity": "sha512-foCqbDgfcvdLqKX4hxFfPb6m9KXuvzOdMQT1vjCzwIK4BjqLC7d6TeWxHMaIF5B9tHxKrEb0POI49sJGFNjxHA==" 131 | }, 132 | "locale-en-gb": { 133 | "version": "0.0.2", 134 | "resolved": "https://registry.npmjs.org/locale-en-gb/-/locale-en-gb-0.0.2.tgz", 135 | "integrity": "sha512-Z/9xQDlDoMhaIEPMQz9VoB8zbKlI6CgO9ScVl3urJeKJI6qViZNGpS7h/ycBGC0AJcrE3I4J72XmiSgVCyK0kA==" 136 | }, 137 | "locale-en-us": { 138 | "version": "0.0.2", 139 | "resolved": "https://registry.npmjs.org/locale-en-us/-/locale-en-us-0.0.2.tgz", 140 | "integrity": "sha512-I02W/LK36C1IDloiFY4ZvK7kIs4C92vCHVEI01rIrJPzzlqcn1NnUxn5d1oiq0pe6JwuzpWwSCYnV0o1WAQP9g==" 141 | }, 142 | "locale-es-es": { 143 | "version": "0.0.2", 144 | "resolved": "https://registry.npmjs.org/locale-es-es/-/locale-es-es-0.0.2.tgz", 145 | "integrity": "sha512-Hw0DO46yuMJlGbgzjyiu6Q8OEaSQ+DBWNvhCX7apGC8NJwzY7pNoFUDDm3DtxAZ9W2F/33548/+C7BTOfeF7Eg==" 146 | }, 147 | "locale-fr-fr": { 148 | "version": "0.0.2", 149 | "resolved": "https://registry.npmjs.org/locale-fr-fr/-/locale-fr-fr-0.0.2.tgz", 150 | "integrity": "sha512-KS9t0SrAmy2+T74zKNQUsj5Bn1EyLl+/2aIxnD/FCvQrVlADnuuwMvLQRx0W7uU4hmEtRhpsfKTA40mHPbvVXg==" 151 | }, 152 | "style-apa": { 153 | "version": "0.0.2", 154 | "resolved": "https://registry.npmjs.org/style-apa/-/style-apa-0.0.2.tgz", 155 | "integrity": "sha512-DSgE7KPxV0Z3o5j4mAOGWp+Dpl9KhPUS5+704lEsVCI0G/LjbnvoINJUWn2llrYR95PH9Dkw0M9fiTt/BwEAoA==" 156 | }, 157 | "style-chicago": { 158 | "version": "0.0.2", 159 | "resolved": "https://registry.npmjs.org/style-chicago/-/style-chicago-0.0.2.tgz", 160 | "integrity": "sha512-xQyPhA3eLMmpV2BQ9+OwxYy6RgUIrxbXFxH6Demd8QlBQpXvj5rkZNn3YpEMyvoAinghFjZOGGuaBDCYiZxFxQ==" 161 | }, 162 | "style-mla": { 163 | "version": "0.0.2", 164 | "resolved": "https://registry.npmjs.org/style-mla/-/style-mla-0.0.2.tgz", 165 | "integrity": "sha512-uxe00Gcv8W5Rgie8QStLnMlZh4o821UwWclr+SfgMNCRRVF8ncB9wvqU093FcS2QR02V8/YNE0P2ySJ2GFIFSw==" 166 | }, 167 | "style-vancouver": { 168 | "version": "0.0.2", 169 | "resolved": "https://registry.npmjs.org/style-vancouver/-/style-vancouver-0.0.2.tgz", 170 | "integrity": "sha512-6DYqSJSRPdPYPZB64LAKjhX6IBpbI8G2QJg0qsgGE6vLMvWG/8tTpuzdIsZPDMPBMnF2jt/1WBqbDZR4VaA2KQ==" 171 | }, 172 | "unist-util-is": { 173 | "version": "5.1.1", 174 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", 175 | "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" 176 | }, 177 | "unist-util-visit": { 178 | "version": "4.0.0", 179 | "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", 180 | "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", 181 | "requires": { 182 | "@types/unist": "^2.0.0", 183 | "unist-util-is": "^5.0.0", 184 | "unist-util-visit-parents": "^5.0.0" 185 | } 186 | }, 187 | "unist-util-visit-parents": { 188 | "version": "5.0.0", 189 | "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", 190 | "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", 191 | "requires": { 192 | "@types/unist": "^2.0.0", 193 | "unist-util-is": "^5.0.0" 194 | } 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /packages/remark-bibliography/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remark-bibliography", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "description": "Remark plugin for adding bibliographies to markdown.", 6 | "author": "Alex Shaw ", 7 | "sideEffects": false, 8 | "type": "module", 9 | "exports": "./lib/index.js", 10 | "types": "lib/index.d.ts", 11 | "files": [ 12 | "lib/" 13 | ], 14 | "keywords": [ 15 | "remark", 16 | "remark-plugin" 17 | ], 18 | "repository": "https://github.com/Symbitic/remark-plugins/tree/master/packages/remark-meta", 19 | "bugs": "https://github.com/Symbitic/remark-plugins/issues", 20 | "scripts": { 21 | "build": "tsc" 22 | }, 23 | "dependencies": { 24 | "citeproc": "^2.4.59", 25 | "locale-de-de": "^0.0.2", 26 | "locale-en-gb": "^0.0.2", 27 | "locale-en-us": "^0.0.2", 28 | "locale-es-es": "^0.0.2", 29 | "locale-fr-fr": "^0.0.2", 30 | "style-apa": "^0.0.2", 31 | "style-chicago": "^0.0.2", 32 | "style-mla": "^0.0.2", 33 | "style-vancouver": "^0.0.2", 34 | "unist-util-visit": "^4.0.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/bibjson.spec.ts: -------------------------------------------------------------------------------- 1 | import test, { ExecutionContext } from 'ava'; 2 | import bibjson from './bibjson.js' 3 | 4 | const basic = `{ 5 | "gregory2014": { 6 | "title": "Game Engine Architecture, Second Edition.", 7 | "author": [ 8 | { 9 | "name": "Jason Gregory" 10 | } 11 | ], 12 | "type": "book", 13 | "year": "2014", 14 | "publisher": "CRC Press", 15 | "link": [ 16 | { 17 | "url": "http://www.gameenginebook.com/" 18 | } 19 | ], 20 | "identifier": [ 21 | { 22 | "type": "doi", 23 | "id": "10.1186/1758-2946-3-47" 24 | } 25 | ] 26 | } 27 | }` 28 | 29 | const fixtures = [ 30 | [ 'a basic entry', basic ] 31 | ] 32 | 33 | async function macro(t: ExecutionContext, input: any) { 34 | const result = bibjson(input) 35 | t.snapshot(result) 36 | } 37 | 38 | macro.title = (name: string) => `bibjson should parse a ${name}`; 39 | 40 | for (const fixture of fixtures) { 41 | const [ name, source ] = fixture 42 | test(name, macro, source); 43 | } 44 | 45 | /* 46 | describe.each(fixtures)('bibjson', (name, source) => { 47 | it(`should parse ${name}`, () => { 48 | expect(bibjson(source)).toMatchSnapshot() 49 | }) 50 | }) 51 | */ 52 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/bibjson.ts: -------------------------------------------------------------------------------- 1 | import parseDate from './utils/date.js' 2 | import parseName from './utils/name.js' 3 | 4 | export type RECORD_TYPE = 'article' | 'book' | 'booklet' | 'proceedings' | 'mastersthesis' 5 | | 'inbook' | 'incollection' | 'conference' | 'inproceedings' | 'phdthesis' 6 | | 'techreport' | 'unpublished' | 'manual' | 'misc'; 7 | 8 | export type IdentifierType = 'pmsid' | 'pmcid' | 'doi' | 'isbn' 9 | 10 | export type JOURNAL_IDENTIFIER = 'ISSN'; 11 | 12 | export interface Person { 13 | id?: string; 14 | name: string; 15 | firstname?: string; 16 | lastname?: string; 17 | alternate?: string[]; 18 | } 19 | 20 | export interface Link { 21 | url: string; 22 | } 23 | 24 | export interface Identifier { 25 | type: IdentifierType; 26 | id: string; 27 | } 28 | 29 | export interface Journal { 30 | name: string; 31 | identifier: Identifier[]; 32 | volume: string; 33 | pages: string; 34 | issue?: string; 35 | firstpage?: string; 36 | lastpage?: string; 37 | } 38 | 39 | interface BibDate { 40 | submitted?: string; 41 | published?: string; 42 | } 43 | 44 | export interface BibJSON { 45 | id?: string; 46 | title: string; 47 | author: Person[]; 48 | publisher?: Person; 49 | reviewer?: Person[]; 50 | editor: Person[]; 51 | type: RECORD_TYPE; 52 | year: string; 53 | link: Link[]; 54 | keywords?: string[]; 55 | date?: BibDate; 56 | journal?: Journal; 57 | } 58 | 59 | const IDENTIFIERS = [ 'PMID', 'PMCID', 'DOI', 'ISBN' ] 60 | 61 | const JOURNAL_IDENTIFIERS = [ 'ISSN' ] 62 | 63 | const RECORD_TYPES = { 64 | article: 'article', 65 | book: 'book', 66 | booklet: 'book', 67 | proceedings: 'book', 68 | mastersthesis: 'thesis', 69 | inbook: 'chapter', 70 | incollection: 'chapter', 71 | conference: 'paper-conference', 72 | inproceedings: 'paper-conference', 73 | online: 'website', 74 | patent: 'patent', 75 | phdthesis: 'thesis', 76 | techreport: 'report', 77 | unpublished: 'manuscript', 78 | manual: undefined, 79 | misc: undefined 80 | } 81 | 82 | function nameProps(person: Person) { 83 | const { 84 | firstname, 85 | lastname 86 | } = person 87 | 88 | if (firstname && lastname) { 89 | return { firstname, lastname } 90 | } else if (person.name) { 91 | return parseName(person.name) 92 | } 93 | } 94 | 95 | function idProps(input: Record, identifiers: string[]) { 96 | let output: any = {} 97 | 98 | for (let prop in input) { 99 | let propName = prop.toLowerCase() 100 | 101 | if (identifiers.includes(propName)) { 102 | output[propName] = input[prop] 103 | } 104 | } 105 | 106 | if (input.identifier) { 107 | for (let { id, type = '' } of input.identifier) { 108 | type = type.toUpperCase() 109 | if (identifiers.includes(type)) { 110 | output[type] = id 111 | } 112 | } 113 | } 114 | 115 | return output 116 | } 117 | 118 | type RecordEntry = [ string, BibJSON ] 119 | 120 | export default function bibjson(data: string) { 121 | const entries: RecordEntry[] = Object.entries(JSON.parse(data)) 122 | const records = entries.map(([ id, input ]) => { 123 | let output: any = { 124 | type: RECORD_TYPES[input.type] || 'book' 125 | } 126 | 127 | if (input.title) { 128 | output.title = input.title 129 | } 130 | if (input.author) { 131 | output.author = input.author.map(nameProps).filter(Boolean) 132 | } 133 | if (input.editor) { 134 | output.editor = input.editor.map(nameProps).filter(Boolean) 135 | } 136 | if (input.publisher) { 137 | output.publisher = input.publisher.name || input.publisher 138 | } 139 | if (input.reviewer) { 140 | if (input.author) { 141 | output['reviewed-author'] = output.author 142 | } 143 | output.author = input.reviewer.map(nameProps).filter(Boolean) 144 | } 145 | if (input.keywords) { 146 | output.keyword = Array.isArray(input.keywords) 147 | ? input.keywords.join() 148 | : input.keywords 149 | } 150 | 151 | if (input.date && Object.keys(input.date).length > 0) { 152 | let dates = input.date 153 | if (dates.submitted) { 154 | output.submitted = parseDate(dates.submitted) 155 | } 156 | if (dates.published) { 157 | output.issued = parseDate(dates.published) 158 | } 159 | } else if (input.year) { 160 | output.issued = { 161 | 'date-parts': [[+input.year]] 162 | } 163 | } 164 | if (input.journal) { 165 | let journal = input.journal 166 | if (journal.name) { 167 | output['container-title'] = journal.name 168 | } 169 | if (journal.volume) { 170 | output.volume = +journal.volume 171 | } 172 | if (journal.issue) { 173 | output.issue = +journal.issue 174 | } 175 | 176 | Object.assign(output, idProps(journal, JOURNAL_IDENTIFIERS)) 177 | 178 | if (journal.firstpage) { 179 | output['page-first'] = journal.firstpage 180 | } 181 | if (journal.pages) { 182 | output.page = journal.pages.replace('--', '-') 183 | } else if (journal.firstpage && journal.lastpage) { 184 | output.page = journal.firstpage + '-' + journal.lastpage 185 | } 186 | } 187 | 188 | if (input.link && typeof input.link[0] === 'object') { 189 | output.URL = input.link[0].url 190 | } 191 | 192 | Object.assign(output, idProps(input, IDENTIFIERS)) 193 | 194 | if (input.id) { 195 | output.id = input.id 196 | } else { 197 | output.id = id 198 | } 199 | 200 | return [ id, output ] 201 | }); 202 | return records 203 | .reduce((acc, val) => Object.assign(acc, { 204 | [val[0]]: val[1] 205 | }), {}) as BibJSON 206 | } 207 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/citations.spec.ts.bak: -------------------------------------------------------------------------------- 1 | import test, { ExecutionContext } from 'ava'; 2 | import citations from './citations.js' 3 | 4 | type Case = [ string, any, Record, any? ] 5 | 6 | const case1: Case = [ 7 | 'replace a citation correctly', 8 | { 9 | type: 'root', 10 | children: [{ 11 | type: 'paragraph', 12 | children: [{ type: 'text', value: 'This is a citation: (@singh2016).' }] 13 | }] 14 | }, 15 | { 16 | gregory2014: { 17 | type: 'book', 18 | title: 'Game Engine Architecture, Second Edition.', 19 | author: [{ given: 'Jason', family: 'Gregory' }], 20 | publisher: 'CRC Press', 21 | issued: { 'date-parts': [ [ 2014 ] ] }, 22 | URL: 'http://www.gameenginebook.com/', 23 | DOI: '10.1186/1758-2946-3-47', 24 | id: 'gregory2014' 25 | }, 26 | singh2016: { 27 | type: 'book', 28 | title: 'Vulkan Essentials', 29 | author: [{ given: 'Parminder', family: 'Singh' }], 30 | publisher: 'Packt Publishing', 31 | issued: { 'date-parts': [ [ 2016 ] ] }, 32 | URL: 'https://www.packtpub.com/application-development/vulkan-essentials', 33 | id: 'singh2016' 34 | }, 35 | moller2008: { 36 | id: 'moller2008', 37 | type: 'book', 38 | title: 'Real Time Rendering, Third Edition', 39 | author: [ 40 | { given: 'Thomas', family: 'Akenine-Moller' }, 41 | { given: 'Eric', family: 'Haines' }, 42 | { given: 'Naty', family: 'Hoffman' } 43 | ], 44 | publisher: 'CRC Press', 45 | issued: { 'date-parts': [ [ 2008 ] ] }, 46 | URL: 'http://www.realtimerendering.com/' 47 | } 48 | } 49 | ] 50 | 51 | const fixtures = [ 52 | case1 53 | ] 54 | 55 | async function macro(t: ExecutionContext, tree: any, items: any, opts?: any) { 56 | const result = citations(tree, items, opts) 57 | t.snapshot(result) 58 | } 59 | 60 | macro.title = (name: string) => `citations should parse a ${name}`; 61 | 62 | for (const fixture of fixtures) { 63 | const [ name, tree, item, opts ] = fixture 64 | test.skip(name, macro, tree, item, opts); 65 | } 66 | /* 67 | describe.each(fixtures)('citations', (name, tree, items, opts) => { 68 | it(`should ${name}`, () => { 69 | expect(citations(tree, items, opts)).toMatchSnapshot() 70 | }) 71 | }) 72 | */ 73 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/citations.ts: -------------------------------------------------------------------------------- 1 | import chicago from 'style-chicago' 2 | import CSL from 'citeproc' 3 | import enUS from 'locale-en-us' 4 | import { visit } from 'unist-util-visit' 5 | import type { Data, Literal, Node, Parent } from 'unist' 6 | 7 | export interface Options { 8 | style: Record; 9 | locale: Record; 10 | } 11 | 12 | export default function citations(root: Node, items: any, opts: Partial = {}) { 13 | const tree = root as Parent, Data>; 14 | const style = opts.style || chicago 15 | const locale = opts.locale || enUS 16 | 17 | const sys = { 18 | retrieveLocale: () => locale, 19 | retrieveItem: (id: string) => items[id] 20 | } 21 | 22 | // Create Citeproc and add items 23 | const citeproc = new CSL.Engine(sys, style) 24 | citeproc.updateItems(Object.keys(items)) 25 | 26 | // Create citations 27 | const citations = Object.entries(items) 28 | .map(([key, val]) => ([ 29 | key, 30 | citeproc.makeCitationCluster([val]) 31 | // .replace(/^\(.+)/)$/, '$1') 32 | ])) 33 | .reduce((acc, val) => Object.assign(acc, { 34 | [val[0]]: val[1] 35 | }), {}) 36 | 37 | // Create bibliography 38 | const bibliography = citeproc.makeBibliography() 39 | const ids = bibliography[0].entry_ids.map((ids: string[]) => ids.join('')) 40 | const bib = bibliography[1] 41 | .map((str: string) => str 42 | .trim() 43 | .replace(/]+>/g, '') 44 | .replace(/<\/div>/g, '') 45 | .replace(/<\/i>/g, '') 46 | .split('') 47 | .map((item, i) => (i % 2 === 0 ? { 48 | type: 'text', 49 | value: item 50 | } : { 51 | type: 'emphasis', 52 | children: [{ type: 'text', value: item }] 53 | })) 54 | ) 55 | 56 | // Add citations to MDAST 57 | Object.entries(citations).forEach(([id, cite]) => { 58 | const key = `(@${id})` 59 | visit(tree, ['text'], (node, i, parent) => { 60 | const { value } = node as Literal 61 | 62 | const contains = value.includes(key) 63 | if (!contains) { 64 | return 65 | } 66 | const values = value.split(key) 67 | const children = [ 68 | { 69 | type: 'text', 70 | value: values[0] 71 | }, 72 | { 73 | type: 'link', 74 | url: `#ref-${id}`, 75 | data: { 76 | hProperties: { 77 | className: 'citation' 78 | } 79 | }, 80 | children: [{ type: 'text', value: cite }] 81 | }, 82 | { 83 | type: 'text', 84 | value: values[1] 85 | } 86 | ] 87 | parent!.children.splice(i!, 1, ...children) 88 | }) 89 | }) 90 | 91 | // Append bibliography to MDAST 92 | tree.children = tree.children.concat({ 93 | type: 'element', 94 | data: { 95 | hName: 'div', 96 | hProperties: { 97 | className: 'references' 98 | } 99 | }, 100 | children: [ 101 | { 102 | type: 'heading', 103 | depth: 2, 104 | children: [ 105 | { 106 | type: 'text', 107 | value: 'References' 108 | } 109 | ] 110 | }, 111 | { 112 | type: 'list', 113 | ordered: true, 114 | spread: false, 115 | data: { 116 | hProperties: { className: 'ref-list' } 117 | }, 118 | children: bib.map((entry, i) => ({ 119 | type: 'listItem', 120 | spread: false, 121 | data: { 122 | hProperties: { id: `ref-${ids[i]}`, className: 'reference' } 123 | }, 124 | children: entry 125 | })) 126 | } 127 | ] 128 | } as any) 129 | 130 | return tree as Node 131 | } 132 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/index.spec.ts.bak: -------------------------------------------------------------------------------- 1 | /* eslint-env jest */ 2 | /* 3 | import bibliography from './index' 4 | import html from 'rehype-stringify' 5 | import markdown from 'remark-parse' 6 | import path from 'path' 7 | import remark2rehype from 'remark-rehype' 8 | import { unified } from 'unified' 9 | 10 | const ASSETS = path.resolve(__dirname, '..', 'examples') 11 | 12 | const parse = (bib: string, str: string) => 13 | unified() 14 | .use(markdown) 15 | .use(() => (_tree, file) => { 16 | file.history = [ path.join(ASSETS, 'examples.md') ] 17 | file.data = { bibliography: bib } 18 | }) 19 | .use(bibliography) 20 | .use(remark2rehype) 21 | .use(html) 22 | .process(str) 23 | .then(data => data.toString()) 24 | 25 | const EXAMPLE1 = `This is a citation: (@singh2016).` 26 | 27 | const tests = [ 28 | [ 'process a basic bibliography', 'example.json', EXAMPLE1 ] 29 | ] 30 | 31 | describe.each(tests)('remark-bibliography', (desc, file, source) => { 32 | it(`should ${desc}`, () => { 33 | return expect(parse(file, source)).resolves.toMatchSnapshot() 34 | }) 35 | }) 36 | */ 37 | test('remark-bibliography', () => { 38 | expect(2+2).toBe(4); 39 | }) 40 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Bibliography & Citations for Remark. 3 | */ 4 | import path from 'path' 5 | import util from 'util' 6 | import fs from 'fs' 7 | 8 | import apa from 'style-apa' 9 | import vancouver from 'style-vancouver' 10 | import mla from 'style-mla' 11 | import chicago from 'style-chicago' 12 | 13 | import deDE from 'locale-de-de' 14 | import enGB from 'locale-en-gb' 15 | import enUS from 'locale-en-us' 16 | import esES from 'locale-es-es' 17 | import frFR from 'locale-fr-fr' 18 | 19 | import bibjson from './bibjson' 20 | import citations from './citations' 21 | 22 | import type { Transformer } from 'unified' 23 | import type { Data, Node } from 'unist' 24 | 25 | const readFile = util.promisify(fs.readFile) 26 | 27 | function format(data: string, ext: string) { 28 | const parsers: Record = { 29 | '.json': bibjson 30 | } 31 | 32 | if (!parsers.hasOwnProperty(ext)) { 33 | return Promise.reject(new Error(`Unrecognized format: ${ext}`)) 34 | } 35 | 36 | const parser = parsers[ext] 37 | 38 | const items = parser(data) 39 | 40 | return items 41 | } 42 | 43 | export interface Bibliography {} 44 | 45 | export default function bibliography(_options: Bibliography = {}): Transformer { 46 | const styles: Record = { 47 | 'apa': apa, 48 | 'chicago': chicago, 49 | 'mla': mla, 50 | 'vancouver': vancouver 51 | } 52 | 53 | const locales: Record = { 54 | 'de-de': deDE, 55 | 'en-gb': enGB, 56 | 'en-us': enUS, 57 | 'es-es': esES, 58 | 'fr-fr': frFR 59 | } 60 | 61 | return async (tree, file): Promise> => { 62 | if (!file.data.hasOwnProperty('bibliography')) { 63 | return Promise.resolve(tree) 64 | } 65 | 66 | const dir = path.dirname(file.history[file.history.length - 1]) 67 | const bibfile = path.resolve(dir, file.data.bibliography as string) 68 | 69 | const style = file.data.hasOwnProperty('style') 70 | ? (file.data.style as string).toLowerCase() 71 | : 'chicago' 72 | const locale = file.data.hasOwnProperty('locale') 73 | ? (file.data.locale as string).toLowerCase() 74 | : 'en-us' 75 | 76 | if (!styles.hasOwnProperty(style)) { 77 | return Promise.reject(new Error(`Unrecognized style: ${style}`)) 78 | } else if (!locales.hasOwnProperty(locale)) { 79 | return Promise.reject(new Error(`Unrecognized locale: ${locale}`)) 80 | } 81 | 82 | const opts = { 83 | style: styles[style], 84 | locale: locales[locale] 85 | } 86 | 87 | const data = await readFile(bibfile, 'utf8') 88 | const items = format(data, path.extname(bibfile)) 89 | return citations(tree, items, opts) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/types/citeproc.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | // declare module 'style-chicago' 3 | 4 | declare module "style-chicago" { 5 | type RecordType = Record 6 | 7 | const style: RecordType; 8 | export default style; 9 | } 10 | 11 | CSL.Engine = function (sys, style, lang, forceLang) {} 12 | 13 | CSL.setupXml = function(xmlObject) {} 14 | localexml = CSL.setupXml(this.sys.retrieveLocale("en-US")); 15 | 16 | */ 17 | 18 | declare module "citeproc" { 19 | interface Sys { 20 | retrieveLocale: (locale: string) => any; 21 | retrieveItem: (id: string) => any 22 | } 23 | 24 | type EntryIds = string[] 25 | 26 | interface Bibliography { 27 | entry_ids: EntryIds[]; 28 | } 29 | 30 | // Temporary 31 | type Style = Record; 32 | 33 | class Engine { 34 | constructor(sys: Sys, style: Style); 35 | 36 | updateItems(items: string[]): void; 37 | 38 | makeCitationCluster(items: any[]): string; 39 | 40 | makeBibliography(): [ Bibliography, string[] ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/types/locales.d.ts: -------------------------------------------------------------------------------- 1 | declare module "locale-en-us" { 2 | const locale: Record; 3 | export default locale; 4 | } 5 | 6 | declare module "locale-de-de" { 7 | const locale: Record; 8 | export default locale; 9 | } 10 | 11 | declare module "locale-en-gb" { 12 | const locale: Record; 13 | export default locale; 14 | } 15 | 16 | declare module "locale-es-es" { 17 | const locale: Record; 18 | export default locale; 19 | } 20 | 21 | declare module "locale-fr-fr" { 22 | const locale: Record; 23 | export default locale; 24 | } 25 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/types/styles.d.ts: -------------------------------------------------------------------------------- 1 | declare module "style-apa" { 2 | const style: Record; 3 | export default style; 4 | } 5 | 6 | declare module "style-chicago" { 7 | const style: Record; 8 | export default style; 9 | } 10 | 11 | declare module "style-mla" { 12 | const style: Record; 13 | export default style; 14 | } 15 | 16 | declare module "style-vancouver" { 17 | const style: Record; 18 | export default style; 19 | } 20 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/utils/date.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Derived from https://github.com/citation-js/date/blob/master/src/input.js 3 | */ 4 | const ISO8601 = /^(\d{4}|[-+]\d{6,})-(\d{2})-(\d{2})/ 5 | const RFC2822 = /^(?:[a-z]{3},\s*)?(\d{1,2}) ([a-z]{3}) (\d{4,})/i 6 | const AMERICAN_DAY = /^(\d{1,2})\/(\d{1,2})\/(\d{2}(?:\d{2})?)/ 7 | const REGULAR_DAY = /^(\d{1,2})[ .\-/](\d{1,2}|[a-z]{3,10})[ .\-/](-?\d+)/i 8 | const REVERSE_DAY = /^(-?\d+)[ .\-/](\d{1,2}|[a-z]{3,10})[ .\-/](\d{1,2})/i 9 | const MONTH = /^([a-z]{3,10}|-?\d+)[^\w-]+([a-z]{3,10}|-?\d+)$/i 10 | const YEAR = /^-?\d+$/ 11 | 12 | function getMonth(month: string) { 13 | const MONTHS_TABLE: Record = { 14 | jan: 1, 15 | feb: 2, 16 | mar: 3, 17 | apr: 4, 18 | may: 5, 19 | jun: 6, 20 | jul: 7, 21 | aug: 8, 22 | sep: 9, 23 | oct: 10, 24 | nov: 11, 25 | dec: 12 26 | } 27 | const abbr: string = month.toLowerCase().slice(0, 3) 28 | if (abbr in MONTHS_TABLE) { 29 | return MONTHS_TABLE[abbr]; 30 | } 31 | return 0 32 | } 33 | 34 | /* 35 | const isEpoc = date => { 36 | const epoch = new Date(date) 37 | return typeof date === 'number' && !isNaN(epoch.valueOf()) 38 | } 39 | const isIso8601 = date => typeof date === 'string' && ISO8601.test(date) 40 | const isRfc2822 = date => typeof date === 'string' && RFC2822.test(date) 41 | && getMonth(date.match(RFC2822)[2]) 42 | const isAmericanDay = date => { 43 | if (typeof date === 'string' && AMERICAN_DAY.test(date)) { 44 | const [ , month, day, year ] = date.match(AMERICAN_DAY) 45 | const check = new Date(year, month, day) 46 | return check.getMonth() === parseInt(month) 47 | } 48 | return false 49 | } 50 | */ 51 | 52 | function parseEpoch(date: string | number) { 53 | let epoch = new Date(date) 54 | 55 | if (typeof date === 'number' && !isNaN(epoch.valueOf())) { 56 | return [epoch.getFullYear(), epoch.getMonth() + 1, epoch.getDate()] 57 | } else { 58 | return null 59 | } 60 | } 61 | 62 | function parseIso8601(date: string) { 63 | if (typeof date !== 'string' || !ISO8601.test(date)) { 64 | return null 65 | } 66 | 67 | let [, year, month, day] = date.match(ISO8601) as RegExpMatchArray 68 | 69 | if (!+month) { 70 | return [year] 71 | } else if (!+day) { 72 | return [year, month] 73 | } else { 74 | return [year, month, day] 75 | } 76 | } 77 | 78 | function parseRfc2822(date: string) { 79 | if (typeof date !== 'string' || !RFC2822.test(date)) { 80 | return null 81 | } 82 | 83 | let [, day, monthStr, year] = date.match(RFC2822) as RegExpMatchArray 84 | 85 | const month = getMonth(monthStr) 86 | if (!month) { 87 | return null 88 | } 89 | 90 | return [year, month, day] 91 | } 92 | 93 | function parseAmericanDay(date: string) { 94 | if (typeof date !== 'string' || !AMERICAN_DAY.test(date)) { 95 | return null 96 | } 97 | 98 | let [, month, day, year]: any = date.match(AMERICAN_DAY)! 99 | 100 | let check = new Date(year, month, day) 101 | if (check.getMonth() === parseInt(month)) { 102 | return [year, month, day] 103 | } else { 104 | return null 105 | } 106 | } 107 | 108 | function parseDay(date: string) { 109 | let year 110 | let month 111 | let day 112 | 113 | if (typeof date !== 'string') { 114 | return null 115 | } else if (REGULAR_DAY.test(date)) { 116 | [, day, month, year] = date.match(REGULAR_DAY) 117 | } else if (REVERSE_DAY.test(date)) { 118 | [, year, month, day] = date.match(REVERSE_DAY) 119 | } else { 120 | return null 121 | } 122 | 123 | if (getMonth(month)) { 124 | month = getMonth(month) 125 | } else if (isNaN(month)) { 126 | return null 127 | } 128 | 129 | return [year, month, day] 130 | } 131 | 132 | function parseMonth(date: string) { 133 | if (typeof date === 'string' && MONTH.test(date)) { 134 | let values = date.match(MONTH)!.slice(1, 3) 135 | 136 | let month 137 | if (getMonth(values[1])) { 138 | month = getMonth(values.pop() as string) 139 | } else if (getMonth(values[0])) { 140 | month = getMonth(values.shift() as string) 141 | } else if (values.some((val: any) => isNaN(val)) || values.every(value => +value < 0)) { 142 | return null 143 | } else if (+values[0] < 0) { 144 | month = values.pop() 145 | } else if (+values[0] > +values[1] && +values[1] > 0) { 146 | month = values.pop() 147 | } else { 148 | month = values.shift() 149 | } 150 | 151 | let year = values.pop() 152 | 153 | return [year, month] 154 | } else { 155 | return null 156 | } 157 | } 158 | 159 | function parseYear(date: string) { 160 | if (typeof date === 'string' && YEAR.test(date)) { 161 | return [date] 162 | } else { 163 | return null 164 | } 165 | } 166 | 167 | export default function parseDate(value: string) { 168 | const date = parseEpoch(value) 169 | || parseIso8601(value) 170 | || parseRfc2822(value) 171 | || parseAmericanDay(value) 172 | || parseDay(value) 173 | || parseMonth(value) 174 | || parseYear(value) 175 | 176 | return date ? { 177 | // 'date-parts': [ date.map(string => parseInt(string)) ] 178 | 'date-parts': [date.map(str => str.length > 2 ? str : parseInt(str))] 179 | } : { 180 | raw: value 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /packages/remark-bibliography/src/utils/name.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Derived from https://github.com/citation-js/name/blob/master/src/input.js 3 | */ 4 | const punctutationMatcher = (str: string) => str.replace(/$|( )|(?!^)(?=[A-Z])/g, '\\.?$1') 5 | const getListMatcher = (list: string[]) => `(?:${list.join('|')})\\b` 6 | const getSplittingRegex = (matcher: string, flags: string) => new RegExp(`(?:^| )(${matcher}$)`, flags) 7 | 8 | const titles = [ 9 | 'mr', 'mrs', 'ms', 'miss', 'dr', 'herr', 'monsieur', 'hr', 'frau', 10 | 'a v m', 'admiraal', 'admiral', 'air cdre', 'air commodore', 'air marshal', 11 | 'air vice marshal', 'alderman', 'alhaji', 'ambassador', 'baron', 'barones', 12 | 'brig', 'brig gen', 'brig general', 'brigadier', 'brigadier general', 13 | 'brother', 'canon', 'capt', 'captain', 'cardinal', 'cdr', 'chief', 'cik', 'cmdr', 14 | 'coach', 'col', 'col dr', 'colonel', 'commandant', 'commander', 'commissioner', 15 | 'commodore', 'comte', 'comtessa', 'congressman', 'conseiller', 'consul', 16 | 'conte', 'contessa', 'corporal', 'councillor', 'count', 'countess', 17 | 'crown prince', 'crown princess', 'dame', 'datin', 'dato', 'datuk', 18 | 'datuk seri', 'deacon', 'deaconess', 'dean', 'dhr', 'dipl ing', 'doctor', 19 | 'dott', 'dott sa', 'dr', 'dr ing', 'dra', 'drs', 'embajador', 'embajadora', 'en', 20 | 'encik', 'eng', 'eur ing', 'exma sra', 'exmo sr', 'f o', 'father', 21 | 'first lieutient', 'first officer', 'flt lieut', 'flying officer', 'fr', 22 | 'frau', 'fraulein', 'fru', 'gen', 'generaal', 'general', 'governor', 'graaf', 23 | 'gravin', 'group captain', 'grp capt', 'h e dr', 'h h', 'h m', 'h r h', 'hajah', 24 | 'haji', 'hajim', 'her highness', 'her majesty', 'herr', 'high chief', 25 | 'his highness', 'his holiness', 'his majesty', 'hon', 'hr', 'hra', 'ing', 'ir', 26 | 'jonkheer', 'judge', 'justice', 'khun ying', 'kolonel', 'lady', 'lcda', 'lic', 27 | 'lieut', 'lieut cdr', 'lieut col', 'lieut gen', 'lord', 'm', 'm l', 'm r', 28 | 'madame', 'mademoiselle', 'maj gen', 'major', 'master', 'mevrouw', 'miss', 29 | 'mlle', 'mme', 'monsieur', 'monsignor', 'mr', 'mrs', 'ms', 'mstr', 'nti', 'pastor', 30 | 'president', 'prince', 'princess', 'princesse', 'prinses', 'prof', 'prof dr', 31 | 'prof sir', 'professor', 'puan', 'puan sri', 'rabbi', 'rear admiral', 'rev', 32 | 'rev canon', 'rev dr', 'rev mother', 'reverend', 'rva', 'senator', 'sergeant', 33 | 'sheikh', 'sheikha', 'sig', 'sig na', 'sig ra', 'sir', 'sister', 'sqn ldr', 'sr', 34 | 'sr d', 'sra', 'srta', 'sultan', 'tan sri', 'tan sri dato', 'tengku', 'teuku', 35 | 'than puying', 'the hon dr', 'the hon justice', 'the hon miss', 'the hon mr', 36 | 'the hon mrs', 'the hon ms', 'the hon sir', 'the very rev', 'toh puan', 'tun', 37 | 'vice admiral', 'viscount', 'viscountess', 'wg cdr' 38 | ] 39 | 40 | const suffixes = [ 41 | 'I', 'II', 'III', 'IV', 'V', 'Senior', 'Junior', 'Jr', 'Sr', 'PhD', 'Ph\\.D', 'APR', 42 | 'RPh', 'PE', 'MD', 'MA', 'DMD', 'CME', 'BVM', 'CFRE', 'CLU', 'CPA', 'CSC', 'CSJ', 43 | 'DC', 'DD', 'DDS', 'DO', 'DVM', 'EdD', 'Esq', 'JD', 'LLD', 'OD', 'OSB', 'PC', 'Ret', 44 | 'RGS', 'RN', 'RNC', 'SHCJ', 'SJ', 'SNJM', 'SSMO', 'USA', 'USAF', 'USAFR', 'USAR', 45 | 'USCG', 'USMC', 'USMCR', 'USN', 'USNR' 46 | ] 47 | 48 | const particles = [ 49 | 'Vere', 'Von', 'Van', 'De', 'Del', 'Della', 'Di', 'Da', 'Pietro', 'Vanden', 'Du', 50 | 'St.', 'St', 'La', 'Lo', 'Ter', 'O', 'O\'', 'Mac', 'Fitz' 51 | ] 52 | 53 | const titleMatcher = getListMatcher(titles.map(punctutationMatcher)) 54 | const suffixMatcher = getListMatcher(suffixes.map(punctutationMatcher)) 55 | const particleMatcher = getListMatcher(particles) 56 | const titleSplitter = new RegExp(`^((?:${titleMatcher} )*)(.*)$`, 'i') 57 | const suffixSplitter = getSplittingRegex(`(?:${suffixMatcher}, )*(?:${suffixMatcher})`, 'i') 58 | 59 | /* Not 100% sure these are correct, but Babel REALLY doesn't like the template literals version. */ 60 | // const particleSplitter = getSplittingRegex(`${/\p{Uppercase}/u.source}.*`) 61 | const particleSplitter = new RegExp(`(?:^| )(/\p{Uppercase}/u.source.*$)`) 62 | // const endSplitter = getSplittingRegex(`(?:${/\p{Lowercase}/u.source}.*|${particleMatcher}.*|\\S*)`) 63 | const endSplitter = new RegExp(`(?:^| )((?:/\p{Lowercase}/u.source.*|${particleMatcher}.*|\\S*)$)`) 64 | 65 | export default function parseName(name: string = '') { 66 | if (typeof name !== 'string') { 67 | name = name + '' 68 | } 69 | 70 | let start: string = '' 71 | let mid: string = '' 72 | let end: string = '' 73 | 74 | if (/[^.], /.test(name)) { 75 | // reversed name 76 | const parts = name.split(', ') 77 | end = parts.shift() as string 78 | const suffixMatch = RegExp(suffixMatcher).exec(parts.join(', ')) 79 | start = parts.splice(suffixMatch && suffixMatch.index !== 0 ? 0 : -1, 1)[0] 80 | mid = parts.join(', ') 81 | } else { 82 | const parts = name.split(suffixSplitter, 2) 83 | const main = (parts.shift() as string).split(endSplitter, 2) 84 | start = main[0] 85 | end = main[1] 86 | mid = parts.pop() as string 87 | } 88 | 89 | const [ , droppingParticle, given ] = start.match(titleSplitter) as RegExpMatchArray 90 | const suffix = mid 91 | const [ family, nonDroppingParticle ] = end.split(particleSplitter, 2).reverse() 92 | 93 | if (!given && family) { 94 | return family.includes(' ') ? { literal: family } : { family } 95 | } else if (family) { 96 | const nameObject: Record = { 97 | 'dropping-particle': droppingParticle, 98 | given, 99 | suffix, 100 | 'non-dropping-particle': nonDroppingParticle, 101 | family 102 | } 103 | 104 | // remove empty parts (easier than if statement for every part) 105 | Object.keys(nameObject).forEach((key) => { 106 | if (!nameObject[key]) { 107 | delete nameObject[key] 108 | } 109 | }) 110 | 111 | return nameObject 112 | } else { 113 | return { 114 | literal: name 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /packages/remark-bibliography/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "declaration": true 6 | }, 7 | "include": [ 8 | "./src", 9 | "./src/types" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/remark-deflist/LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright © Alex Shaw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/remark-deflist/README.md: -------------------------------------------------------------------------------- 1 | # remark-deflist 2 | 3 | [![CI/CD Status](https://github.com/Symbitic/remark-plugins/workflows/main/badge.svg)](https://github.com/Symbitic/remark-plugins/actions) 4 | [![MIT License](https://img.shields.io/github/license/Symbitic/remark-plugins)](https://github.com/Symbitic/remark-plugins/blob/master/LICENSE.md) 5 | [![stars](https://img.shields.io/github/stars/Symbitic/remark-plugins.svg)](https://github.com/Symbitic/remark-plugins) 6 | 7 | [Remark](https://remark.js.org/) plugin for adding support for pandoc-style definition lists to Markdown. 8 | 9 | Adds three new node types to [MDAST](https://github.com/syntax-tree/mdast): `descriptionlist`, `descriptionterm`, and `descriptiondetails`. 10 | When using [rehype](https://github.com/rehypejs/rehype), these will be stringified as `dl`, `dt`, and `dd` respectively. 11 | 12 | Mostly compatible with the [pandoc]/[PHP Markdown Extra] syntax. The only difference is that multi-paragraph descriptions are not currently supported. 13 | 14 | ## Install 15 | 16 | This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): 17 | Node 12+ is needed to use it and it must be `import`ed instead of `require`d. 18 | 19 | [npm](https://docs.npmjs.com/cli/install): 20 | 21 | ```sh 22 | npm install remark-deflist 23 | ``` 24 | 25 | ## Example 26 | 27 | ### Syntax 28 | ```markdown 29 | Term 1 30 | 31 | : Definition 1 32 | ``` 33 | 34 | ### AST 35 | 36 | The example above will yield: 37 | 38 | ```javascript 39 | { 40 | type: 'descriptionlist', 41 | children: [ 42 | { 43 | type: 'descriptionterm', 44 | children: [{ 45 | type: 'text', 46 | value: 'Term 1' 47 | }] 48 | }, 49 | { 50 | type: 'descriptiondetails', 51 | children: [{ 52 | type: 'text', 53 | value: 'Definition 1' 54 | }] 55 | } 56 | ] 57 | } 58 | ``` 59 | 60 | ## Syntax 61 | 62 | ``` 63 | Term with *inline markup* 64 | 65 | : Definition **1** 66 | ``` 67 | 68 | ``` 69 | Lazy Initialization 70 | : Achievement of compactness by not typing an extra line after the definition term. 71 | ``` 72 | 73 | ``` 74 | Continuation 75 | 76 | : Splitting a single paragraph 77 | across multiple lines. 78 | ``` 79 | 80 | ``` 81 | Lazy Continuation 82 | : Ugliness 83 | by not indenting text. 84 | ``` 85 | 86 | ``` 87 | This is an example of multiple definitions for a single term. 88 | 89 | Indent 90 | : (*noun*) A whitespace to align text in a beautiful way. 91 | : (*verb*) To add whitespace to make ugly code beautiful. 92 | ``` 93 | 94 | ## Usage 95 | 96 | ```javascript 97 | import { unified } from 'unified' 98 | import markdown from 'remark-parse' 99 | import html from 'rehype-stringify' 100 | import remark2rehype from 'remark-rehype' 101 | import meta from 'remark-meta' 102 | 103 | unified() 104 | .use(markdown) 105 | .use(meta) 106 | .use(remark2rehype) 107 | .use(html) 108 | ``` 109 | 110 | ## License 111 | 112 | [MIT](LICENSE.md) © Alex Shaw 113 | 114 | [pandoc]: https://pandoc.org/MANUAL.html#definition-lists 115 | 116 | [PHP Markdown Extra]: https://michelf.ca/projects/php-markdown/extra/#def-list 117 | -------------------------------------------------------------------------------- /packages/remark-deflist/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remark-deflist", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "0.3.0", 9 | "license": "MIT", 10 | "dependencies": { 11 | "mdast-util-from-markdown": "^1.0.0", 12 | "mdast-util-to-markdown": "^1.1.1", 13 | "mdast-util-to-string": "^3.1.0", 14 | "unist-util-visit": "^4.0.0" 15 | } 16 | }, 17 | "node_modules/@types/debug": { 18 | "version": "4.1.7", 19 | "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", 20 | "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", 21 | "dependencies": { 22 | "@types/ms": "*" 23 | } 24 | }, 25 | "node_modules/@types/mdast": { 26 | "version": "3.0.7", 27 | "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.7.tgz", 28 | "integrity": "sha512-YwR7OK8aPmaBvMMUi+pZXBNoW2unbVbfok4YRqGMJBe1dpDlzpRkJrYEYmvjxgs5JhuQmKfDexrN98u941Zasg==", 29 | "dependencies": { 30 | "@types/unist": "*" 31 | } 32 | }, 33 | "node_modules/@types/ms": { 34 | "version": "0.7.31", 35 | "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", 36 | "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" 37 | }, 38 | "node_modules/@types/unist": { 39 | "version": "2.0.6", 40 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", 41 | "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" 42 | }, 43 | "node_modules/character-entities": { 44 | "version": "2.0.0", 45 | "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.0.tgz", 46 | "integrity": "sha512-oHqMj3eAuJ77/P5PaIRcqk+C3hdfNwyCD2DAUcD5gyXkegAuF2USC40CEqPscDk4I8FRGMTojGJQkXDsN5QlJA==", 47 | "funding": { 48 | "type": "github", 49 | "url": "https://github.com/sponsors/wooorm" 50 | } 51 | }, 52 | "node_modules/character-entities-legacy": { 53 | "version": "2.0.0", 54 | "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-2.0.0.tgz", 55 | "integrity": "sha512-YwaEtEvWLpFa6Wh3uVLrvirA/ahr9fki/NUd/Bd4OR6EdJ8D22hovYQEOUCBfQfcqnC4IAMGMsHXY1eXgL4ZZA==", 56 | "funding": { 57 | "type": "github", 58 | "url": "https://github.com/sponsors/wooorm" 59 | } 60 | }, 61 | "node_modules/character-reference-invalid": { 62 | "version": "2.0.0", 63 | "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.0.tgz", 64 | "integrity": "sha512-pE3Z15lLRxDzWJy7bBHBopRwfI20sbrMVLQTC7xsPglCHf4Wv1e167OgYAFP78co2XlhojDyAqA+IAJse27//g==", 65 | "funding": { 66 | "type": "github", 67 | "url": "https://github.com/sponsors/wooorm" 68 | } 69 | }, 70 | "node_modules/debug": { 71 | "version": "4.3.2", 72 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", 73 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", 74 | "dependencies": { 75 | "ms": "2.1.2" 76 | }, 77 | "engines": { 78 | "node": ">=6.0" 79 | }, 80 | "peerDependenciesMeta": { 81 | "supports-color": { 82 | "optional": true 83 | } 84 | } 85 | }, 86 | "node_modules/is-alphabetical": { 87 | "version": "2.0.0", 88 | "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.0.tgz", 89 | "integrity": "sha512-5OV8Toyq3oh4eq6sbWTYzlGdnMT/DPI5I0zxUBxjiigQsZycpkKF3kskkao3JyYGuYDHvhgJF+DrjMQp9SX86w==", 90 | "funding": { 91 | "type": "github", 92 | "url": "https://github.com/sponsors/wooorm" 93 | } 94 | }, 95 | "node_modules/is-alphanumerical": { 96 | "version": "2.0.0", 97 | "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.0.tgz", 98 | "integrity": "sha512-t+2GlJ+hO9yagJ+jU3+HSh80VKvz/3cG2cxbGGm4S0hjKuhWQXgPVUVOZz3tqZzMjhmphZ+1TIJTlRZRoe6GCQ==", 99 | "dependencies": { 100 | "is-alphabetical": "^2.0.0", 101 | "is-decimal": "^2.0.0" 102 | }, 103 | "funding": { 104 | "type": "github", 105 | "url": "https://github.com/sponsors/wooorm" 106 | } 107 | }, 108 | "node_modules/is-decimal": { 109 | "version": "2.0.0", 110 | "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.0.tgz", 111 | "integrity": "sha512-QfrfjQV0LjoWQ1K1XSoEZkTAzSa14RKVMa5zg3SdAfzEmQzRM4+tbSFWb78creCeA9rNBzaZal92opi1TwPWZw==", 112 | "funding": { 113 | "type": "github", 114 | "url": "https://github.com/sponsors/wooorm" 115 | } 116 | }, 117 | "node_modules/is-hexadecimal": { 118 | "version": "2.0.0", 119 | "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.0.tgz", 120 | "integrity": "sha512-vGOtYkiaxwIiR0+Ng/zNId+ZZehGfINwTzdrDqc6iubbnQWhnPuYymOzOKUDqa2cSl59yHnEh2h6MvRLQsyNug==", 121 | "funding": { 122 | "type": "github", 123 | "url": "https://github.com/sponsors/wooorm" 124 | } 125 | }, 126 | "node_modules/longest-streak": { 127 | "version": "3.0.0", 128 | "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.0.0.tgz", 129 | "integrity": "sha512-XhUjWR5CFaQ03JOP+iSDS9koy8T5jfoImCZ4XprElw3BXsSk4MpVYOLw/6LTDKZhO13PlAXnB5gS4MHQTpkSOw==", 130 | "funding": { 131 | "type": "github", 132 | "url": "https://github.com/sponsors/wooorm" 133 | } 134 | }, 135 | "node_modules/mdast-util-from-markdown": { 136 | "version": "1.0.0", 137 | "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.0.tgz", 138 | "integrity": "sha512-uj2G60sb7z1PNOeElFwCC9b/Se/lFXuLhVKFOAY2EHz/VvgbupTQRNXPoZl7rGpXYL6BNZgcgaybrlSWbo7n/g==", 139 | "dependencies": { 140 | "@types/mdast": "^3.0.0", 141 | "@types/unist": "^2.0.0", 142 | "mdast-util-to-string": "^3.0.0", 143 | "micromark": "^3.0.0", 144 | "micromark-util-decode-numeric-character-reference": "^1.0.0", 145 | "micromark-util-normalize-identifier": "^1.0.0", 146 | "micromark-util-symbol": "^1.0.0", 147 | "micromark-util-types": "^1.0.0", 148 | "parse-entities": "^3.0.0", 149 | "unist-util-stringify-position": "^3.0.0" 150 | }, 151 | "funding": { 152 | "type": "opencollective", 153 | "url": "https://opencollective.com/unified" 154 | } 155 | }, 156 | "node_modules/mdast-util-to-markdown": { 157 | "version": "1.1.1", 158 | "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.1.1.tgz", 159 | "integrity": "sha512-4puev/CxuxVdlsx5lVmuzgdqfjkkJJLS1Zm/MnejQ8I7BLeeBlbkwp6WOGJypEcN8g56LbVbhNmn84MvvcAvSQ==", 160 | "dependencies": { 161 | "@types/mdast": "^3.0.0", 162 | "@types/unist": "^2.0.0", 163 | "longest-streak": "^3.0.0", 164 | "mdast-util-to-string": "^3.0.0", 165 | "parse-entities": "^3.0.0", 166 | "zwitch": "^2.0.0" 167 | }, 168 | "funding": { 169 | "type": "opencollective", 170 | "url": "https://opencollective.com/unified" 171 | } 172 | }, 173 | "node_modules/mdast-util-to-string": { 174 | "version": "3.1.0", 175 | "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", 176 | "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", 177 | "funding": { 178 | "type": "opencollective", 179 | "url": "https://opencollective.com/unified" 180 | } 181 | }, 182 | "node_modules/micromark": { 183 | "version": "3.0.3", 184 | "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.0.3.tgz", 185 | "integrity": "sha512-fWuHx+JKV4zA8WfCFor2DWP9XmsZkIiyWRGofr7P7IGfpRIlb7/C5wwusGsNyr1D8HI5arghZDG1Ikc0FBwS5Q==", 186 | "funding": [ 187 | { 188 | "type": "GitHub Sponsors", 189 | "url": "https://github.com/sponsors/unifiedjs" 190 | }, 191 | { 192 | "type": "OpenCollective", 193 | "url": "https://opencollective.com/unified" 194 | } 195 | ], 196 | "dependencies": { 197 | "@types/debug": "^4.0.0", 198 | "debug": "^4.0.0", 199 | "micromark-core-commonmark": "^1.0.0", 200 | "micromark-factory-space": "^1.0.0", 201 | "micromark-util-character": "^1.0.0", 202 | "micromark-util-chunked": "^1.0.0", 203 | "micromark-util-combine-extensions": "^1.0.0", 204 | "micromark-util-decode-numeric-character-reference": "^1.0.0", 205 | "micromark-util-encode": "^1.0.0", 206 | "micromark-util-normalize-identifier": "^1.0.0", 207 | "micromark-util-resolve-all": "^1.0.0", 208 | "micromark-util-sanitize-uri": "^1.0.0", 209 | "micromark-util-subtokenize": "^1.0.0", 210 | "micromark-util-symbol": "^1.0.0", 211 | "micromark-util-types": "^1.0.0", 212 | "parse-entities": "^3.0.0" 213 | } 214 | }, 215 | "node_modules/micromark-core-commonmark": { 216 | "version": "1.0.0", 217 | "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.0.tgz", 218 | "integrity": "sha512-y9g7zymcKRBHM/aNBekstvs/Grpf+y4OEBULUTYvGZcusnp+JeOxmilJY4GMpo2/xY7iHQL9fjz5pD9pSAud9A==", 219 | "funding": [ 220 | { 221 | "type": "GitHub Sponsors", 222 | "url": "https://github.com/sponsors/unifiedjs" 223 | }, 224 | { 225 | "type": "OpenCollective", 226 | "url": "https://opencollective.com/unified" 227 | } 228 | ], 229 | "dependencies": { 230 | "micromark-factory-destination": "^1.0.0", 231 | "micromark-factory-label": "^1.0.0", 232 | "micromark-factory-space": "^1.0.0", 233 | "micromark-factory-title": "^1.0.0", 234 | "micromark-factory-whitespace": "^1.0.0", 235 | "micromark-util-character": "^1.0.0", 236 | "micromark-util-chunked": "^1.0.0", 237 | "micromark-util-classify-character": "^1.0.0", 238 | "micromark-util-html-tag-name": "^1.0.0", 239 | "micromark-util-normalize-identifier": "^1.0.0", 240 | "micromark-util-resolve-all": "^1.0.0", 241 | "micromark-util-subtokenize": "^1.0.0", 242 | "micromark-util-symbol": "^1.0.0", 243 | "micromark-util-types": "^1.0.0", 244 | "parse-entities": "^3.0.0" 245 | } 246 | }, 247 | "node_modules/micromark-factory-destination": { 248 | "version": "1.0.0", 249 | "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz", 250 | "integrity": "sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==", 251 | "funding": [ 252 | { 253 | "type": "GitHub Sponsors", 254 | "url": "https://github.com/sponsors/unifiedjs" 255 | }, 256 | { 257 | "type": "OpenCollective", 258 | "url": "https://opencollective.com/unified" 259 | } 260 | ], 261 | "dependencies": { 262 | "micromark-util-character": "^1.0.0", 263 | "micromark-util-symbol": "^1.0.0", 264 | "micromark-util-types": "^1.0.0" 265 | } 266 | }, 267 | "node_modules/micromark-factory-label": { 268 | "version": "1.0.0", 269 | "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.0.0.tgz", 270 | "integrity": "sha512-XWEucVZb+qBCe2jmlOnWr6sWSY6NHx+wtpgYFsm4G+dufOf6tTQRRo0bdO7XSlGPu5fyjpJenth6Ksnc5Mwfww==", 271 | "funding": [ 272 | { 273 | "type": "GitHub Sponsors", 274 | "url": "https://github.com/sponsors/unifiedjs" 275 | }, 276 | { 277 | "type": "OpenCollective", 278 | "url": "https://opencollective.com/unified" 279 | } 280 | ], 281 | "dependencies": { 282 | "micromark-util-character": "^1.0.0", 283 | "micromark-util-symbol": "^1.0.0", 284 | "micromark-util-types": "^1.0.0" 285 | } 286 | }, 287 | "node_modules/micromark-factory-space": { 288 | "version": "1.0.0", 289 | "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz", 290 | "integrity": "sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==", 291 | "funding": [ 292 | { 293 | "type": "GitHub Sponsors", 294 | "url": "https://github.com/sponsors/unifiedjs" 295 | }, 296 | { 297 | "type": "OpenCollective", 298 | "url": "https://opencollective.com/unified" 299 | } 300 | ], 301 | "dependencies": { 302 | "micromark-util-character": "^1.0.0", 303 | "micromark-util-types": "^1.0.0" 304 | } 305 | }, 306 | "node_modules/micromark-factory-title": { 307 | "version": "1.0.0", 308 | "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.0.0.tgz", 309 | "integrity": "sha512-flvC7Gx0dWVWorXuBl09Cr3wB5FTuYec8pMGVySIp2ZlqTcIjN/lFohZcP0EG//krTptm34kozHk7aK/CleCfA==", 310 | "funding": [ 311 | { 312 | "type": "GitHub Sponsors", 313 | "url": "https://github.com/sponsors/unifiedjs" 314 | }, 315 | { 316 | "type": "OpenCollective", 317 | "url": "https://opencollective.com/unified" 318 | } 319 | ], 320 | "dependencies": { 321 | "micromark-factory-space": "^1.0.0", 322 | "micromark-util-character": "^1.0.0", 323 | "micromark-util-symbol": "^1.0.0", 324 | "micromark-util-types": "^1.0.0" 325 | } 326 | }, 327 | "node_modules/micromark-factory-whitespace": { 328 | "version": "1.0.0", 329 | "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz", 330 | "integrity": "sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==", 331 | "funding": [ 332 | { 333 | "type": "GitHub Sponsors", 334 | "url": "https://github.com/sponsors/unifiedjs" 335 | }, 336 | { 337 | "type": "OpenCollective", 338 | "url": "https://opencollective.com/unified" 339 | } 340 | ], 341 | "dependencies": { 342 | "micromark-factory-space": "^1.0.0", 343 | "micromark-util-character": "^1.0.0", 344 | "micromark-util-symbol": "^1.0.0", 345 | "micromark-util-types": "^1.0.0" 346 | } 347 | }, 348 | "node_modules/micromark-util-character": { 349 | "version": "1.1.0", 350 | "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.1.0.tgz", 351 | "integrity": "sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==", 352 | "funding": [ 353 | { 354 | "type": "GitHub Sponsors", 355 | "url": "https://github.com/sponsors/unifiedjs" 356 | }, 357 | { 358 | "type": "OpenCollective", 359 | "url": "https://opencollective.com/unified" 360 | } 361 | ], 362 | "dependencies": { 363 | "micromark-util-symbol": "^1.0.0", 364 | "micromark-util-types": "^1.0.0" 365 | } 366 | }, 367 | "node_modules/micromark-util-chunked": { 368 | "version": "1.0.0", 369 | "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz", 370 | "integrity": "sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==", 371 | "funding": [ 372 | { 373 | "type": "GitHub Sponsors", 374 | "url": "https://github.com/sponsors/unifiedjs" 375 | }, 376 | { 377 | "type": "OpenCollective", 378 | "url": "https://opencollective.com/unified" 379 | } 380 | ], 381 | "dependencies": { 382 | "micromark-util-symbol": "^1.0.0" 383 | } 384 | }, 385 | "node_modules/micromark-util-classify-character": { 386 | "version": "1.0.0", 387 | "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz", 388 | "integrity": "sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==", 389 | "funding": [ 390 | { 391 | "type": "GitHub Sponsors", 392 | "url": "https://github.com/sponsors/unifiedjs" 393 | }, 394 | { 395 | "type": "OpenCollective", 396 | "url": "https://opencollective.com/unified" 397 | } 398 | ], 399 | "dependencies": { 400 | "micromark-util-character": "^1.0.0", 401 | "micromark-util-symbol": "^1.0.0", 402 | "micromark-util-types": "^1.0.0" 403 | } 404 | }, 405 | "node_modules/micromark-util-combine-extensions": { 406 | "version": "1.0.0", 407 | "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz", 408 | "integrity": "sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==", 409 | "funding": [ 410 | { 411 | "type": "GitHub Sponsors", 412 | "url": "https://github.com/sponsors/unifiedjs" 413 | }, 414 | { 415 | "type": "OpenCollective", 416 | "url": "https://opencollective.com/unified" 417 | } 418 | ], 419 | "dependencies": { 420 | "micromark-util-chunked": "^1.0.0", 421 | "micromark-util-types": "^1.0.0" 422 | } 423 | }, 424 | "node_modules/micromark-util-decode-numeric-character-reference": { 425 | "version": "1.0.0", 426 | "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz", 427 | "integrity": "sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==", 428 | "funding": [ 429 | { 430 | "type": "GitHub Sponsors", 431 | "url": "https://github.com/sponsors/unifiedjs" 432 | }, 433 | { 434 | "type": "OpenCollective", 435 | "url": "https://opencollective.com/unified" 436 | } 437 | ], 438 | "dependencies": { 439 | "micromark-util-symbol": "^1.0.0" 440 | } 441 | }, 442 | "node_modules/micromark-util-encode": { 443 | "version": "1.0.0", 444 | "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.0.tgz", 445 | "integrity": "sha512-cJpFVM768h6zkd8qJ1LNRrITfY4gwFt+tziPcIf71Ui8yFzY9wG3snZQqiWVq93PG4Sw6YOtcNiKJfVIs9qfGg==", 446 | "funding": [ 447 | { 448 | "type": "GitHub Sponsors", 449 | "url": "https://github.com/sponsors/unifiedjs" 450 | }, 451 | { 452 | "type": "OpenCollective", 453 | "url": "https://opencollective.com/unified" 454 | } 455 | ] 456 | }, 457 | "node_modules/micromark-util-html-tag-name": { 458 | "version": "1.0.0", 459 | "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.0.0.tgz", 460 | "integrity": "sha512-NenEKIshW2ZI/ERv9HtFNsrn3llSPZtY337LID/24WeLqMzeZhBEE6BQ0vS2ZBjshm5n40chKtJ3qjAbVV8S0g==", 461 | "funding": [ 462 | { 463 | "type": "GitHub Sponsors", 464 | "url": "https://github.com/sponsors/unifiedjs" 465 | }, 466 | { 467 | "type": "OpenCollective", 468 | "url": "https://opencollective.com/unified" 469 | } 470 | ] 471 | }, 472 | "node_modules/micromark-util-normalize-identifier": { 473 | "version": "1.0.0", 474 | "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz", 475 | "integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==", 476 | "funding": [ 477 | { 478 | "type": "GitHub Sponsors", 479 | "url": "https://github.com/sponsors/unifiedjs" 480 | }, 481 | { 482 | "type": "OpenCollective", 483 | "url": "https://opencollective.com/unified" 484 | } 485 | ], 486 | "dependencies": { 487 | "micromark-util-symbol": "^1.0.0" 488 | } 489 | }, 490 | "node_modules/micromark-util-resolve-all": { 491 | "version": "1.0.0", 492 | "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz", 493 | "integrity": "sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==", 494 | "funding": [ 495 | { 496 | "type": "GitHub Sponsors", 497 | "url": "https://github.com/sponsors/unifiedjs" 498 | }, 499 | { 500 | "type": "OpenCollective", 501 | "url": "https://opencollective.com/unified" 502 | } 503 | ], 504 | "dependencies": { 505 | "micromark-util-types": "^1.0.0" 506 | } 507 | }, 508 | "node_modules/micromark-util-sanitize-uri": { 509 | "version": "1.0.0", 510 | "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz", 511 | "integrity": "sha512-cCxvBKlmac4rxCGx6ejlIviRaMKZc0fWm5HdCHEeDWRSkn44l6NdYVRyU+0nT1XC72EQJMZV8IPHF+jTr56lAg==", 512 | "funding": [ 513 | { 514 | "type": "GitHub Sponsors", 515 | "url": "https://github.com/sponsors/unifiedjs" 516 | }, 517 | { 518 | "type": "OpenCollective", 519 | "url": "https://opencollective.com/unified" 520 | } 521 | ], 522 | "dependencies": { 523 | "micromark-util-character": "^1.0.0", 524 | "micromark-util-encode": "^1.0.0", 525 | "micromark-util-symbol": "^1.0.0" 526 | } 527 | }, 528 | "node_modules/micromark-util-subtokenize": { 529 | "version": "1.0.0", 530 | "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.0.tgz", 531 | "integrity": "sha512-EsnG2qscmcN5XhkqQBZni/4oQbLFjz9yk3ZM/P8a3YUjwV6+6On2wehr1ALx0MxK3+XXXLTzuBKHDFeDFYRdgQ==", 532 | "funding": [ 533 | { 534 | "type": "GitHub Sponsors", 535 | "url": "https://github.com/sponsors/unifiedjs" 536 | }, 537 | { 538 | "type": "OpenCollective", 539 | "url": "https://opencollective.com/unified" 540 | } 541 | ], 542 | "dependencies": { 543 | "micromark-util-chunked": "^1.0.0", 544 | "micromark-util-symbol": "^1.0.0", 545 | "micromark-util-types": "^1.0.0" 546 | } 547 | }, 548 | "node_modules/micromark-util-symbol": { 549 | "version": "1.0.0", 550 | "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.0.tgz", 551 | "integrity": "sha512-NZA01jHRNCt4KlOROn8/bGi6vvpEmlXld7EHcRH+aYWUfL3Wc8JLUNNlqUMKa0hhz6GrpUWsHtzPmKof57v0gQ==", 552 | "funding": [ 553 | { 554 | "type": "GitHub Sponsors", 555 | "url": "https://github.com/sponsors/unifiedjs" 556 | }, 557 | { 558 | "type": "OpenCollective", 559 | "url": "https://opencollective.com/unified" 560 | } 561 | ] 562 | }, 563 | "node_modules/micromark-util-types": { 564 | "version": "1.0.0", 565 | "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.0.0.tgz", 566 | "integrity": "sha512-psf1WAaP1B77WpW4mBGDkTr+3RsPuDAgsvlP47GJzbH1jmjH8xjOx7Z6kp84L8oqHmy5pYO3Ev46odosZV+3AA==", 567 | "funding": [ 568 | { 569 | "type": "GitHub Sponsors", 570 | "url": "https://github.com/sponsors/unifiedjs" 571 | }, 572 | { 573 | "type": "OpenCollective", 574 | "url": "https://opencollective.com/unified" 575 | } 576 | ] 577 | }, 578 | "node_modules/ms": { 579 | "version": "2.1.2", 580 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 581 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 582 | }, 583 | "node_modules/parse-entities": { 584 | "version": "3.0.0", 585 | "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-3.0.0.tgz", 586 | "integrity": "sha512-AJlcIFDNPEP33KyJLguv0xJc83BNvjxwpuUIcetyXUsLpVXAUCePJ5kIoYtEN2R1ac0cYaRu/vk9dVFkewHQhQ==", 587 | "dependencies": { 588 | "character-entities": "^2.0.0", 589 | "character-entities-legacy": "^2.0.0", 590 | "character-reference-invalid": "^2.0.0", 591 | "is-alphanumerical": "^2.0.0", 592 | "is-decimal": "^2.0.0", 593 | "is-hexadecimal": "^2.0.0" 594 | }, 595 | "funding": { 596 | "type": "github", 597 | "url": "https://github.com/sponsors/wooorm" 598 | } 599 | }, 600 | "node_modules/unist-util-is": { 601 | "version": "5.1.1", 602 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", 603 | "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", 604 | "funding": { 605 | "type": "opencollective", 606 | "url": "https://opencollective.com/unified" 607 | } 608 | }, 609 | "node_modules/unist-util-stringify-position": { 610 | "version": "3.0.0", 611 | "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", 612 | "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", 613 | "dependencies": { 614 | "@types/unist": "^2.0.0" 615 | }, 616 | "funding": { 617 | "type": "opencollective", 618 | "url": "https://opencollective.com/unified" 619 | } 620 | }, 621 | "node_modules/unist-util-visit": { 622 | "version": "4.0.0", 623 | "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", 624 | "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", 625 | "dependencies": { 626 | "@types/unist": "^2.0.0", 627 | "unist-util-is": "^5.0.0", 628 | "unist-util-visit-parents": "^5.0.0" 629 | }, 630 | "funding": { 631 | "type": "opencollective", 632 | "url": "https://opencollective.com/unified" 633 | } 634 | }, 635 | "node_modules/unist-util-visit-parents": { 636 | "version": "5.0.0", 637 | "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", 638 | "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", 639 | "dependencies": { 640 | "@types/unist": "^2.0.0", 641 | "unist-util-is": "^5.0.0" 642 | }, 643 | "funding": { 644 | "type": "opencollective", 645 | "url": "https://opencollective.com/unified" 646 | } 647 | }, 648 | "node_modules/zwitch": { 649 | "version": "2.0.2", 650 | "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.2.tgz", 651 | "integrity": "sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==", 652 | "funding": { 653 | "type": "github", 654 | "url": "https://github.com/sponsors/wooorm" 655 | } 656 | } 657 | }, 658 | "dependencies": { 659 | "@types/debug": { 660 | "version": "4.1.7", 661 | "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", 662 | "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", 663 | "requires": { 664 | "@types/ms": "*" 665 | } 666 | }, 667 | "@types/mdast": { 668 | "version": "3.0.7", 669 | "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.7.tgz", 670 | "integrity": "sha512-YwR7OK8aPmaBvMMUi+pZXBNoW2unbVbfok4YRqGMJBe1dpDlzpRkJrYEYmvjxgs5JhuQmKfDexrN98u941Zasg==", 671 | "requires": { 672 | "@types/unist": "*" 673 | } 674 | }, 675 | "@types/ms": { 676 | "version": "0.7.31", 677 | "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", 678 | "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" 679 | }, 680 | "@types/unist": { 681 | "version": "2.0.6", 682 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", 683 | "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" 684 | }, 685 | "character-entities": { 686 | "version": "2.0.0", 687 | "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.0.tgz", 688 | "integrity": "sha512-oHqMj3eAuJ77/P5PaIRcqk+C3hdfNwyCD2DAUcD5gyXkegAuF2USC40CEqPscDk4I8FRGMTojGJQkXDsN5QlJA==" 689 | }, 690 | "character-entities-legacy": { 691 | "version": "2.0.0", 692 | "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-2.0.0.tgz", 693 | "integrity": "sha512-YwaEtEvWLpFa6Wh3uVLrvirA/ahr9fki/NUd/Bd4OR6EdJ8D22hovYQEOUCBfQfcqnC4IAMGMsHXY1eXgL4ZZA==" 694 | }, 695 | "character-reference-invalid": { 696 | "version": "2.0.0", 697 | "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.0.tgz", 698 | "integrity": "sha512-pE3Z15lLRxDzWJy7bBHBopRwfI20sbrMVLQTC7xsPglCHf4Wv1e167OgYAFP78co2XlhojDyAqA+IAJse27//g==" 699 | }, 700 | "debug": { 701 | "version": "4.3.2", 702 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", 703 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", 704 | "requires": { 705 | "ms": "2.1.2" 706 | } 707 | }, 708 | "is-alphabetical": { 709 | "version": "2.0.0", 710 | "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.0.tgz", 711 | "integrity": "sha512-5OV8Toyq3oh4eq6sbWTYzlGdnMT/DPI5I0zxUBxjiigQsZycpkKF3kskkao3JyYGuYDHvhgJF+DrjMQp9SX86w==" 712 | }, 713 | "is-alphanumerical": { 714 | "version": "2.0.0", 715 | "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.0.tgz", 716 | "integrity": "sha512-t+2GlJ+hO9yagJ+jU3+HSh80VKvz/3cG2cxbGGm4S0hjKuhWQXgPVUVOZz3tqZzMjhmphZ+1TIJTlRZRoe6GCQ==", 717 | "requires": { 718 | "is-alphabetical": "^2.0.0", 719 | "is-decimal": "^2.0.0" 720 | } 721 | }, 722 | "is-decimal": { 723 | "version": "2.0.0", 724 | "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.0.tgz", 725 | "integrity": "sha512-QfrfjQV0LjoWQ1K1XSoEZkTAzSa14RKVMa5zg3SdAfzEmQzRM4+tbSFWb78creCeA9rNBzaZal92opi1TwPWZw==" 726 | }, 727 | "is-hexadecimal": { 728 | "version": "2.0.0", 729 | "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.0.tgz", 730 | "integrity": "sha512-vGOtYkiaxwIiR0+Ng/zNId+ZZehGfINwTzdrDqc6iubbnQWhnPuYymOzOKUDqa2cSl59yHnEh2h6MvRLQsyNug==" 731 | }, 732 | "longest-streak": { 733 | "version": "3.0.0", 734 | "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.0.0.tgz", 735 | "integrity": "sha512-XhUjWR5CFaQ03JOP+iSDS9koy8T5jfoImCZ4XprElw3BXsSk4MpVYOLw/6LTDKZhO13PlAXnB5gS4MHQTpkSOw==" 736 | }, 737 | "mdast-util-from-markdown": { 738 | "version": "1.0.0", 739 | "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.0.tgz", 740 | "integrity": "sha512-uj2G60sb7z1PNOeElFwCC9b/Se/lFXuLhVKFOAY2EHz/VvgbupTQRNXPoZl7rGpXYL6BNZgcgaybrlSWbo7n/g==", 741 | "requires": { 742 | "@types/mdast": "^3.0.0", 743 | "@types/unist": "^2.0.0", 744 | "mdast-util-to-string": "^3.0.0", 745 | "micromark": "^3.0.0", 746 | "micromark-util-decode-numeric-character-reference": "^1.0.0", 747 | "micromark-util-normalize-identifier": "^1.0.0", 748 | "micromark-util-symbol": "^1.0.0", 749 | "micromark-util-types": "^1.0.0", 750 | "parse-entities": "^3.0.0", 751 | "unist-util-stringify-position": "^3.0.0" 752 | } 753 | }, 754 | "mdast-util-to-markdown": { 755 | "version": "1.1.1", 756 | "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.1.1.tgz", 757 | "integrity": "sha512-4puev/CxuxVdlsx5lVmuzgdqfjkkJJLS1Zm/MnejQ8I7BLeeBlbkwp6WOGJypEcN8g56LbVbhNmn84MvvcAvSQ==", 758 | "requires": { 759 | "@types/mdast": "^3.0.0", 760 | "@types/unist": "^2.0.0", 761 | "longest-streak": "^3.0.0", 762 | "mdast-util-to-string": "^3.0.0", 763 | "parse-entities": "^3.0.0", 764 | "zwitch": "^2.0.0" 765 | } 766 | }, 767 | "mdast-util-to-string": { 768 | "version": "3.1.0", 769 | "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", 770 | "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==" 771 | }, 772 | "micromark": { 773 | "version": "3.0.3", 774 | "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.0.3.tgz", 775 | "integrity": "sha512-fWuHx+JKV4zA8WfCFor2DWP9XmsZkIiyWRGofr7P7IGfpRIlb7/C5wwusGsNyr1D8HI5arghZDG1Ikc0FBwS5Q==", 776 | "requires": { 777 | "@types/debug": "^4.0.0", 778 | "debug": "^4.0.0", 779 | "micromark-core-commonmark": "^1.0.0", 780 | "micromark-factory-space": "^1.0.0", 781 | "micromark-util-character": "^1.0.0", 782 | "micromark-util-chunked": "^1.0.0", 783 | "micromark-util-combine-extensions": "^1.0.0", 784 | "micromark-util-decode-numeric-character-reference": "^1.0.0", 785 | "micromark-util-encode": "^1.0.0", 786 | "micromark-util-normalize-identifier": "^1.0.0", 787 | "micromark-util-resolve-all": "^1.0.0", 788 | "micromark-util-sanitize-uri": "^1.0.0", 789 | "micromark-util-subtokenize": "^1.0.0", 790 | "micromark-util-symbol": "^1.0.0", 791 | "micromark-util-types": "^1.0.0", 792 | "parse-entities": "^3.0.0" 793 | } 794 | }, 795 | "micromark-core-commonmark": { 796 | "version": "1.0.0", 797 | "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.0.tgz", 798 | "integrity": "sha512-y9g7zymcKRBHM/aNBekstvs/Grpf+y4OEBULUTYvGZcusnp+JeOxmilJY4GMpo2/xY7iHQL9fjz5pD9pSAud9A==", 799 | "requires": { 800 | "micromark-factory-destination": "^1.0.0", 801 | "micromark-factory-label": "^1.0.0", 802 | "micromark-factory-space": "^1.0.0", 803 | "micromark-factory-title": "^1.0.0", 804 | "micromark-factory-whitespace": "^1.0.0", 805 | "micromark-util-character": "^1.0.0", 806 | "micromark-util-chunked": "^1.0.0", 807 | "micromark-util-classify-character": "^1.0.0", 808 | "micromark-util-html-tag-name": "^1.0.0", 809 | "micromark-util-normalize-identifier": "^1.0.0", 810 | "micromark-util-resolve-all": "^1.0.0", 811 | "micromark-util-subtokenize": "^1.0.0", 812 | "micromark-util-symbol": "^1.0.0", 813 | "micromark-util-types": "^1.0.0", 814 | "parse-entities": "^3.0.0" 815 | } 816 | }, 817 | "micromark-factory-destination": { 818 | "version": "1.0.0", 819 | "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz", 820 | "integrity": "sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==", 821 | "requires": { 822 | "micromark-util-character": "^1.0.0", 823 | "micromark-util-symbol": "^1.0.0", 824 | "micromark-util-types": "^1.0.0" 825 | } 826 | }, 827 | "micromark-factory-label": { 828 | "version": "1.0.0", 829 | "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.0.0.tgz", 830 | "integrity": "sha512-XWEucVZb+qBCe2jmlOnWr6sWSY6NHx+wtpgYFsm4G+dufOf6tTQRRo0bdO7XSlGPu5fyjpJenth6Ksnc5Mwfww==", 831 | "requires": { 832 | "micromark-util-character": "^1.0.0", 833 | "micromark-util-symbol": "^1.0.0", 834 | "micromark-util-types": "^1.0.0" 835 | } 836 | }, 837 | "micromark-factory-space": { 838 | "version": "1.0.0", 839 | "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz", 840 | "integrity": "sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==", 841 | "requires": { 842 | "micromark-util-character": "^1.0.0", 843 | "micromark-util-types": "^1.0.0" 844 | } 845 | }, 846 | "micromark-factory-title": { 847 | "version": "1.0.0", 848 | "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.0.0.tgz", 849 | "integrity": "sha512-flvC7Gx0dWVWorXuBl09Cr3wB5FTuYec8pMGVySIp2ZlqTcIjN/lFohZcP0EG//krTptm34kozHk7aK/CleCfA==", 850 | "requires": { 851 | "micromark-factory-space": "^1.0.0", 852 | "micromark-util-character": "^1.0.0", 853 | "micromark-util-symbol": "^1.0.0", 854 | "micromark-util-types": "^1.0.0" 855 | } 856 | }, 857 | "micromark-factory-whitespace": { 858 | "version": "1.0.0", 859 | "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz", 860 | "integrity": "sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==", 861 | "requires": { 862 | "micromark-factory-space": "^1.0.0", 863 | "micromark-util-character": "^1.0.0", 864 | "micromark-util-symbol": "^1.0.0", 865 | "micromark-util-types": "^1.0.0" 866 | } 867 | }, 868 | "micromark-util-character": { 869 | "version": "1.1.0", 870 | "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.1.0.tgz", 871 | "integrity": "sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==", 872 | "requires": { 873 | "micromark-util-symbol": "^1.0.0", 874 | "micromark-util-types": "^1.0.0" 875 | } 876 | }, 877 | "micromark-util-chunked": { 878 | "version": "1.0.0", 879 | "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz", 880 | "integrity": "sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==", 881 | "requires": { 882 | "micromark-util-symbol": "^1.0.0" 883 | } 884 | }, 885 | "micromark-util-classify-character": { 886 | "version": "1.0.0", 887 | "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz", 888 | "integrity": "sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==", 889 | "requires": { 890 | "micromark-util-character": "^1.0.0", 891 | "micromark-util-symbol": "^1.0.0", 892 | "micromark-util-types": "^1.0.0" 893 | } 894 | }, 895 | "micromark-util-combine-extensions": { 896 | "version": "1.0.0", 897 | "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz", 898 | "integrity": "sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==", 899 | "requires": { 900 | "micromark-util-chunked": "^1.0.0", 901 | "micromark-util-types": "^1.0.0" 902 | } 903 | }, 904 | "micromark-util-decode-numeric-character-reference": { 905 | "version": "1.0.0", 906 | "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz", 907 | "integrity": "sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==", 908 | "requires": { 909 | "micromark-util-symbol": "^1.0.0" 910 | } 911 | }, 912 | "micromark-util-encode": { 913 | "version": "1.0.0", 914 | "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.0.tgz", 915 | "integrity": "sha512-cJpFVM768h6zkd8qJ1LNRrITfY4gwFt+tziPcIf71Ui8yFzY9wG3snZQqiWVq93PG4Sw6YOtcNiKJfVIs9qfGg==" 916 | }, 917 | "micromark-util-html-tag-name": { 918 | "version": "1.0.0", 919 | "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.0.0.tgz", 920 | "integrity": "sha512-NenEKIshW2ZI/ERv9HtFNsrn3llSPZtY337LID/24WeLqMzeZhBEE6BQ0vS2ZBjshm5n40chKtJ3qjAbVV8S0g==" 921 | }, 922 | "micromark-util-normalize-identifier": { 923 | "version": "1.0.0", 924 | "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz", 925 | "integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==", 926 | "requires": { 927 | "micromark-util-symbol": "^1.0.0" 928 | } 929 | }, 930 | "micromark-util-resolve-all": { 931 | "version": "1.0.0", 932 | "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz", 933 | "integrity": "sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==", 934 | "requires": { 935 | "micromark-util-types": "^1.0.0" 936 | } 937 | }, 938 | "micromark-util-sanitize-uri": { 939 | "version": "1.0.0", 940 | "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz", 941 | "integrity": "sha512-cCxvBKlmac4rxCGx6ejlIviRaMKZc0fWm5HdCHEeDWRSkn44l6NdYVRyU+0nT1XC72EQJMZV8IPHF+jTr56lAg==", 942 | "requires": { 943 | "micromark-util-character": "^1.0.0", 944 | "micromark-util-encode": "^1.0.0", 945 | "micromark-util-symbol": "^1.0.0" 946 | } 947 | }, 948 | "micromark-util-subtokenize": { 949 | "version": "1.0.0", 950 | "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.0.tgz", 951 | "integrity": "sha512-EsnG2qscmcN5XhkqQBZni/4oQbLFjz9yk3ZM/P8a3YUjwV6+6On2wehr1ALx0MxK3+XXXLTzuBKHDFeDFYRdgQ==", 952 | "requires": { 953 | "micromark-util-chunked": "^1.0.0", 954 | "micromark-util-symbol": "^1.0.0", 955 | "micromark-util-types": "^1.0.0" 956 | } 957 | }, 958 | "micromark-util-symbol": { 959 | "version": "1.0.0", 960 | "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.0.tgz", 961 | "integrity": "sha512-NZA01jHRNCt4KlOROn8/bGi6vvpEmlXld7EHcRH+aYWUfL3Wc8JLUNNlqUMKa0hhz6GrpUWsHtzPmKof57v0gQ==" 962 | }, 963 | "micromark-util-types": { 964 | "version": "1.0.0", 965 | "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.0.0.tgz", 966 | "integrity": "sha512-psf1WAaP1B77WpW4mBGDkTr+3RsPuDAgsvlP47GJzbH1jmjH8xjOx7Z6kp84L8oqHmy5pYO3Ev46odosZV+3AA==" 967 | }, 968 | "ms": { 969 | "version": "2.1.2", 970 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 971 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 972 | }, 973 | "parse-entities": { 974 | "version": "3.0.0", 975 | "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-3.0.0.tgz", 976 | "integrity": "sha512-AJlcIFDNPEP33KyJLguv0xJc83BNvjxwpuUIcetyXUsLpVXAUCePJ5kIoYtEN2R1ac0cYaRu/vk9dVFkewHQhQ==", 977 | "requires": { 978 | "character-entities": "^2.0.0", 979 | "character-entities-legacy": "^2.0.0", 980 | "character-reference-invalid": "^2.0.0", 981 | "is-alphanumerical": "^2.0.0", 982 | "is-decimal": "^2.0.0", 983 | "is-hexadecimal": "^2.0.0" 984 | } 985 | }, 986 | "unist-util-is": { 987 | "version": "5.1.1", 988 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", 989 | "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" 990 | }, 991 | "unist-util-stringify-position": { 992 | "version": "3.0.0", 993 | "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", 994 | "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", 995 | "requires": { 996 | "@types/unist": "^2.0.0" 997 | } 998 | }, 999 | "unist-util-visit": { 1000 | "version": "4.0.0", 1001 | "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", 1002 | "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", 1003 | "requires": { 1004 | "@types/unist": "^2.0.0", 1005 | "unist-util-is": "^5.0.0", 1006 | "unist-util-visit-parents": "^5.0.0" 1007 | } 1008 | }, 1009 | "unist-util-visit-parents": { 1010 | "version": "5.0.0", 1011 | "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", 1012 | "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", 1013 | "requires": { 1014 | "@types/unist": "^2.0.0", 1015 | "unist-util-is": "^5.0.0" 1016 | } 1017 | }, 1018 | "zwitch": { 1019 | "version": "2.0.2", 1020 | "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.2.tgz", 1021 | "integrity": "sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==" 1022 | } 1023 | } 1024 | } 1025 | -------------------------------------------------------------------------------- /packages/remark-deflist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remark-deflist", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "description": "Remark plugin for pandoc-style definition lists.", 6 | "author": "Alex Shaw ", 7 | "sideEffects": false, 8 | "type": "module", 9 | "exports": "./lib/index.js", 10 | "types": "lib/index.d.ts", 11 | "files": [ 12 | "lib/" 13 | ], 14 | "keywords": [ 15 | "remark", 16 | "remark-plugin" 17 | ], 18 | "repository": "https://github.com/Symbitic/remark-plugins/tree/master/packages/remark-deflist", 19 | "bugs": "https://github.com/Symbitic/remark-plugins/issues", 20 | "scripts": { 21 | "build": "tsc" 22 | }, 23 | "dependencies": { 24 | "mdast-util-from-markdown": "^1.0.0", 25 | "mdast-util-to-markdown": "^1.1.1", 26 | "mdast-util-to-string": "^3.1.0", 27 | "unist-util-visit": "^4.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/remark-deflist/src/index.spec.ts: -------------------------------------------------------------------------------- 1 | import test, { ExecutionContext } from 'ava'; 2 | import deflist from './index.js'; 3 | import html from 'rehype-stringify' 4 | import markdown from 'remark-parse' 5 | import remark2rehype from 'remark-rehype' 6 | import { unified } from 'unified' 7 | 8 | const strip = ([str]: TemplateStringsArray) => str.replace(/\n {6}/g, '\n').replace(/\n {4}$/, '') 9 | 10 | const parse = (str: string) => 11 | unified() 12 | .use(markdown) 13 | .use(deflist) 14 | .use(remark2rehype) 15 | .use(html) 16 | .process(str) 17 | .then(data => data.toString()) 18 | ; 19 | 20 | const fixtures = [ 21 | [ 22 | 'basic definition list', 23 | strip` 24 | Term 1 25 | 26 | : Definition 1 27 | ` 28 | ], 29 | [ 30 | 'definition list with inline markup', 31 | strip` 32 | Term *1* 33 | 34 | : Definition **1** 35 | ` 36 | ], 37 | [ 38 | 'document with other elements', 39 | strip` 40 | Definition List 41 | 42 | : Definition 1 43 | 44 | This paragraph follows the definition list. 45 | ` 46 | ], 47 | [ 48 | 'definition list with continuation', 49 | strip` 50 | Term 1 51 | 52 | : Definition 53 | with continuation. 54 | ` 55 | ], 56 | [ 57 | 'definition list with lazy continuation', 58 | strip` 59 | Term 1 60 | 61 | : Definition 62 | with lazy continuation. 63 | ` 64 | ], 65 | [ 66 | 'definition list with no space between the term and the descriptions (#7)', 67 | strip` 68 | Term **1** 69 | : Definition **bold** 1 70 | : Definition 2 71 | ` 72 | ], 73 | [ 74 | 'definition list with multiple descriptions (#9)', 75 | strip` 76 | Multiple descriptions 77 | 78 | : Description **1** 79 | : Description 2 80 | ` 81 | ], 82 | [ 83 | 'document with several subsequent definition lists (#10)', 84 | strip` 85 | Definition List 1 86 | 87 | : Description 1 88 | 89 | Definition List 2 90 | 91 | : Description 1 92 | 93 | Definition List 3 94 | 95 | : Description 1 96 | ` 97 | ] 98 | ] 99 | 100 | async function macro(t: ExecutionContext, input: any) { 101 | const result = await parse(input) 102 | t.snapshot(result) 103 | } 104 | 105 | macro.title = (name: string) => `remark-deflist should parse a ${name}`; 106 | 107 | for (const fixture of fixtures) { 108 | const [ name, source ] = fixture 109 | test(name, macro, source); 110 | } 111 | 112 | /* 113 | describe.each(fixtures)('remark-supersub', (name, source) => { 114 | it(`should parse a ${name}`, () => { 115 | return expect(parse(source)).resolves.toMatchSnapshot() 116 | }) 117 | }) 118 | */ 119 | -------------------------------------------------------------------------------- /packages/remark-deflist/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect metadata and add it to the `data` field of a VFile. 3 | */ 4 | import { visit } from 'unist-util-visit' 5 | import { toString } from 'mdast-util-to-string' 6 | import { fromMarkdown } from 'mdast-util-from-markdown' 7 | import { toMarkdown } from 'mdast-util-to-markdown' 8 | import type { Transformer } from 'unified' 9 | import type { Node } from 'unist' 10 | import type { Parent } from 'mdast' 11 | 12 | // Test if deflist is contained in a single paragraph. 13 | const isSingleDeflist = (node: Node) => 14 | // i > 0 && 15 | /^[^:].+\n:\s/.test(toString(node)) && 16 | node.type === 'paragraph' 17 | 18 | // Test if deflist is split between two paragraphs. 19 | const isSplitDeflist = (node: Node, i: number, parent: Parent) => 20 | i > 0 && 21 | /^:\s/.test(toString(node)) && 22 | !/^:\s/.test(toString(parent.children[i - 1])) && 23 | node.type === 'paragraph' && 24 | parent.children[i - 1].type === 'paragraph' 25 | 26 | const isdeflist = (node: Node, i: number, parent: Parent) => isSingleDeflist(node) || isSplitDeflist(node, i, parent) 27 | 28 | export default function deflist(): Transformer { 29 | return (tree) => { 30 | visit(tree, ['paragraph'], (node, i, parent) => { 31 | const isdef = isdeflist(node, i!, parent as Parent) 32 | if (!isdef) { 33 | return 34 | } 35 | 36 | let dd = undefined; 37 | let dt = undefined; 38 | let count = 0; 39 | let start: number = 0; 40 | 41 | if (isSingleDeflist(node)) { 42 | const [ title, ...children ] = toMarkdown(node as any).split(/\n:\s+/) 43 | 44 | const childs = fromMarkdown(title).children as Parent[] 45 | 46 | dt = childs.flatMap(({ children }) => children) 47 | dd = children 48 | .map((str) => fromMarkdown(str) as Parent) 49 | .flatMap(({ children }) => children) 50 | .map(({ children }: any) => ({ 51 | type: 'descriptiondetails', 52 | data: { 53 | hName: 'dd' 54 | }, 55 | children 56 | })) 57 | start = i as number 58 | count = 1 59 | } else { 60 | const childs = parent!.children[i! - 1] as Parent 61 | dt = childs.children 62 | dd = toMarkdown(node as any) 63 | .replace(/^:\s+/, '') 64 | .split(/\n:\s+/) 65 | .map((str) => fromMarkdown(str) as Parent) 66 | .flatMap(({ children }) => children) 67 | .map(({ children }: any) => ({ 68 | type: 'descriptiondetails', 69 | data: { 70 | hName: 'dd' 71 | }, 72 | children 73 | })) 74 | start = i! - 1 75 | count = 2 76 | } 77 | 78 | const child = { 79 | type: 'descriptionlist', 80 | data: { 81 | hName: 'dl' 82 | }, 83 | children: [ 84 | { 85 | type: 'descriptionterm', 86 | data: { 87 | hName: 'dt' 88 | }, 89 | children: dt 90 | }, 91 | ...dd 92 | ] 93 | } 94 | 95 | parent!.children.splice(start, count, child) 96 | }) 97 | 98 | // Merge subsequent definition lists into a single list (#10) 99 | visit(tree, ['descriptionlist'], (node, i, parent) => { 100 | const start = i; 101 | let count = 1; 102 | let children = (node as Parent).children; 103 | 104 | for (let j=i!+1; j", 7 | "sideEffects": false, 8 | "type": "module", 9 | "exports": "./lib/index.js", 10 | "types": "lib/index.d.ts", 11 | "files": [ 12 | "lib/" 13 | ], 14 | "keywords": [ 15 | "remark", 16 | "remark-plugin" 17 | ], 18 | "repository": "https://github.com/Symbitic/remark-plugins/tree/master/packages/remark-meta", 19 | "bugs": "https://github.com/Symbitic/remark-plugins/issues", 20 | "scripts": { 21 | "build": "tsc" 22 | }, 23 | "dependencies": { 24 | "js-yaml": "^4.1.0", 25 | "mdast-util-to-string": "^3.1.0", 26 | "toml": "^3.0.0", 27 | "unist-util-select": "^4.0.0", 28 | "unist-util-visit": "^4.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/remark-meta/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect metadata and add it to the `data` field of a VFile. 3 | */ 4 | import { toString } from 'mdast-util-to-string' 5 | import { visit } from 'unist-util-visit' 6 | import { select } from 'unist-util-select' 7 | import { parse as toml } from 'toml' 8 | import { load as yaml } from 'js-yaml' 9 | import type { Transformer } from 'unified' 10 | import type { Literal } from 'unist' 11 | 12 | export default function metadata(): Transformer { 13 | return (tree, file) => { 14 | const heading = select('heading', tree) 15 | file.data.title = heading ? toString(heading) : '' 16 | 17 | visit(tree, ['yaml'], (node) => { 18 | const { value } = node as Literal 19 | file.data = { 20 | ...file.data, 21 | ...yaml(value) as any 22 | } 23 | }) 24 | 25 | visit(tree, ['toml'], (node) => { 26 | const { value } = node as Literal 27 | file.data = { 28 | ...file.data, 29 | ...toml(value) 30 | } 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/remark-meta/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "declaration": true 6 | }, 7 | "include": [ 8 | "./src" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/remark-redirect/LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright © Alex Shaw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/remark-redirect/README.md: -------------------------------------------------------------------------------- 1 | # remark-redirect 2 | 3 | [![CI/CD Status](https://github.com/Symbitic/remark-plugins/workflows/main/badge.svg)](https://github.com/Symbitic/remark-plugins/actions) 4 | [![MIT License](https://img.shields.io/github/license/Symbitic/remark-plugins)](https://github.com/Symbitic/remark-plugins/blob/master/LICENSE.md) 5 | [![stars](https://img.shields.io/github/stars/Symbitic/remark-plugins.svg)](https://github.com/Symbitic/remark-plugins) 6 | 7 | [Remark](https://remark.js.org/) plugin for redirecting links to markdown files into the equivalent HTML files (e.g. `[Link](link.md)` into `[Link](link.html)`). Also changes to `README.md` into `index.html`. 8 | 9 | ## Install 10 | 11 | This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): 12 | Node 12+ is needed to use it and it must be `import`ed instead of `require`d. 13 | 14 | [npm](https://docs.npmjs.com/cli/install): 15 | 16 | ```sh 17 | npm install remark-redirect 18 | ``` 19 | 20 | ## Usage 21 | 22 | ```javascript 23 | import { unified } from 'unified' 24 | import markdown from 'remark-parse' 25 | import html from 'rehype-stringify' 26 | import remark2rehype from 'remark-rehype' 27 | import redirect from 'remark-redirect' 28 | 29 | unified() 30 | .use(markdown) 31 | .use(redirect) 32 | .use(remark2rehype) 33 | .use(html) 34 | ``` 35 | 36 | ## License 37 | 38 | [MIT](LICENSE.md) © Alex Shaw 39 | -------------------------------------------------------------------------------- /packages/remark-redirect/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remark-redirect", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "0.3.0", 9 | "license": "MIT", 10 | "dependencies": { 11 | "unist-util-visit": "^4.0.0" 12 | } 13 | }, 14 | "node_modules/@types/unist": { 15 | "version": "2.0.6", 16 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", 17 | "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" 18 | }, 19 | "node_modules/unist-util-is": { 20 | "version": "5.1.1", 21 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", 22 | "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", 23 | "funding": { 24 | "type": "opencollective", 25 | "url": "https://opencollective.com/unified" 26 | } 27 | }, 28 | "node_modules/unist-util-visit": { 29 | "version": "4.0.0", 30 | "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", 31 | "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", 32 | "dependencies": { 33 | "@types/unist": "^2.0.0", 34 | "unist-util-is": "^5.0.0", 35 | "unist-util-visit-parents": "^5.0.0" 36 | }, 37 | "funding": { 38 | "type": "opencollective", 39 | "url": "https://opencollective.com/unified" 40 | } 41 | }, 42 | "node_modules/unist-util-visit-parents": { 43 | "version": "5.0.0", 44 | "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", 45 | "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", 46 | "dependencies": { 47 | "@types/unist": "^2.0.0", 48 | "unist-util-is": "^5.0.0" 49 | }, 50 | "funding": { 51 | "type": "opencollective", 52 | "url": "https://opencollective.com/unified" 53 | } 54 | } 55 | }, 56 | "dependencies": { 57 | "@types/unist": { 58 | "version": "2.0.6", 59 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", 60 | "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" 61 | }, 62 | "unist-util-is": { 63 | "version": "5.1.1", 64 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", 65 | "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" 66 | }, 67 | "unist-util-visit": { 68 | "version": "4.0.0", 69 | "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", 70 | "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", 71 | "requires": { 72 | "@types/unist": "^2.0.0", 73 | "unist-util-is": "^5.0.0", 74 | "unist-util-visit-parents": "^5.0.0" 75 | } 76 | }, 77 | "unist-util-visit-parents": { 78 | "version": "5.0.0", 79 | "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", 80 | "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", 81 | "requires": { 82 | "@types/unist": "^2.0.0", 83 | "unist-util-is": "^5.0.0" 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /packages/remark-redirect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remark-redirect", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "description": "Remark plugin for changing links to markdown files to HTML files.", 6 | "author": "Alex Shaw ", 7 | "sideEffects": false, 8 | "type": "module", 9 | "exports": "./lib/index.js", 10 | "types": "lib/index.d.ts", 11 | "files": [ 12 | "lib/" 13 | ], 14 | "keywords": [ 15 | "remark", 16 | "remark-plugin" 17 | ], 18 | "repository": "https://github.com/Symbitic/remark-plugins/tree/master/packages/remark-redirect", 19 | "bugs": "https://github.com/Symbitic/remark-plugins/issues", 20 | "scripts": { 21 | "build": "tsc" 22 | }, 23 | "dependencies": { 24 | "unist-util-visit": "^4.0.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/remark-redirect/src/index.spec.ts: -------------------------------------------------------------------------------- 1 | import test, { ExecutionContext } from 'ava'; 2 | import redirect from './index.js'; 3 | import html from 'rehype-stringify' 4 | import markdown from 'remark-parse' 5 | import remark2rehype from 'remark-rehype' 6 | import { unified } from 'unified' 7 | 8 | const strip = ([str]: TemplateStringsArray) => str.replace(/\n {6}/g, '\n').replace(/\n {4}$/, '') 9 | 10 | const parse = (str: string) => 11 | unified() 12 | .use(markdown) 13 | .use(redirect) 14 | .use(remark2rehype) 15 | .use(html) 16 | .process(str) 17 | .then(data => data.toString()) 18 | ; 19 | 20 | const fixtures = [ 21 | [ 22 | 'basic link', 23 | strip` 24 | [README](README.md) 25 | ` 26 | ] 27 | ] 28 | 29 | async function macro(t: ExecutionContext, input: any) { 30 | const result = await parse(input) 31 | t.snapshot(result) 32 | } 33 | 34 | macro.title = (name: string) => `remark-redirect should parse a ${name}`; 35 | 36 | for (const fixture of fixtures) { 37 | const [ name, source ] = fixture 38 | test(name, macro, source); 39 | } 40 | 41 | /* 42 | describe.each(fixtures)('remark-redirect', (name, source) => { 43 | it(`should parse a ${name}`, () => { 44 | return expect(parse(source)).resolves.toMatchSnapshot() 45 | }) 46 | }) 47 | */ 48 | -------------------------------------------------------------------------------- /packages/remark-redirect/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Rename a URL. 3 | * Used to change links from `README.md` to `index.html`. 4 | */ 5 | import { visit } from 'unist-util-visit'; 6 | import { Transformer } from 'unified'; 7 | import { Node } from 'unist'; 8 | import { Definition, Link } from 'mdast'; 9 | 10 | type LinkNode = Definition | Link 11 | 12 | export default function rename(): Transformer { 13 | return (tree) => { 14 | visit(tree, ['link', 'definition'], (node: Node) => { 15 | const { url } = node as LinkNode 16 | (node as LinkNode).url = url 17 | .replace(/README\.md/, 'index.html') 18 | .replace(/\.md/, '.html') 19 | }) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/remark-redirect/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "declaration": true 6 | }, 7 | "include": [ 8 | "./src" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/remark-supersub/LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright © Alex Shaw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/remark-supersub/README.md: -------------------------------------------------------------------------------- 1 | # remark-supersub 2 | 3 | [![CI/CD Status](https://github.com/Symbitic/remark-plugins/workflows/main/badge.svg)](https://github.com/Symbitic/remark-plugins/actions) 4 | [![MIT License](https://img.shields.io/github/license/Symbitic/remark-plugins)](https://github.com/Symbitic/remark-plugins/blob/master/LICENSE.md) 5 | [![stars](https://img.shields.io/github/stars/Symbitic/remark-plugins.svg)](https://github.com/Symbitic/remark-plugins) 6 | 7 | [Remark](https://remark.js.org/) plugin for adding support for pandoc-style superscript and subscript syntax to Markdown. 8 | 9 | Adds two new node types to [MDAST](https://github.com/syntax-tree/mdast): `superscript` and `subscript`. 10 | When using [rehype](https://github.com/rehypejs/rehype), these will be stringified as `sup` and `sub` respectively. 11 | 12 | ## Install 13 | 14 | This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): 15 | Node 12+ is needed to use it and it must be `import`ed instead of `require`d. 16 | 17 | [npm](https://docs.npmjs.com/cli/install): 18 | 19 | ```sh 20 | npm install remark-supersub 21 | ``` 22 | 23 | ## Syntax 24 | 25 | ```markdown 26 | 21^st^ Century 27 | 28 | H~2~O 29 | ``` 30 | 31 | ## AST 32 | 33 | The example above will yield: 34 | 35 | ```javascript 36 | { 37 | type: 'paragraph', 38 | children: [ 39 | { 40 | type: 'text', 41 | value: '21' 42 | }, 43 | { 44 | type: 'superscript', 45 | children: [{ 46 | type: 'text', 47 | value: 'st' 48 | }] 49 | }, 50 | { 51 | type: 'text', 52 | value: ' Century' 53 | } 54 | ] 55 | } 56 | ... 57 | { 58 | type: 'paragraph', 59 | children: [ 60 | { 61 | type: 'text', 62 | value: 'H' 63 | }, 64 | { 65 | type: 'subscript', 66 | children: [{ 67 | type: 'text', 68 | value: '2' 69 | }] 70 | }, 71 | { 72 | type: 'text', 73 | value: 'O' 74 | } 75 | ] 76 | } 77 | ``` 78 | 79 | ## Usage 80 | 81 | ```javascript 82 | import { unified } from 'unified' 83 | import markdown from 'remark-parse' 84 | import html from 'rehype-stringify' 85 | import remark2rehype from 'remark-rehype' 86 | import supersub from 'remark-supersub' 87 | 88 | unified() 89 | .use(markdown) 90 | .use(supersub) 91 | .use(remark2rehype) 92 | .use(html) 93 | ``` 94 | 95 | ## License 96 | 97 | [MIT](LICENSE.md) © Alex Shaw 98 | -------------------------------------------------------------------------------- /packages/remark-supersub/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remark-supersub", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "0.3.0", 9 | "license": "MIT", 10 | "dependencies": { 11 | "unist-util-visit": "^4.0.0" 12 | } 13 | }, 14 | "node_modules/@types/unist": { 15 | "version": "2.0.6", 16 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", 17 | "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" 18 | }, 19 | "node_modules/unist-util-is": { 20 | "version": "5.1.1", 21 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", 22 | "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", 23 | "funding": { 24 | "type": "opencollective", 25 | "url": "https://opencollective.com/unified" 26 | } 27 | }, 28 | "node_modules/unist-util-visit": { 29 | "version": "4.0.0", 30 | "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", 31 | "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", 32 | "dependencies": { 33 | "@types/unist": "^2.0.0", 34 | "unist-util-is": "^5.0.0", 35 | "unist-util-visit-parents": "^5.0.0" 36 | }, 37 | "funding": { 38 | "type": "opencollective", 39 | "url": "https://opencollective.com/unified" 40 | } 41 | }, 42 | "node_modules/unist-util-visit-parents": { 43 | "version": "5.0.0", 44 | "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", 45 | "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", 46 | "dependencies": { 47 | "@types/unist": "^2.0.0", 48 | "unist-util-is": "^5.0.0" 49 | }, 50 | "funding": { 51 | "type": "opencollective", 52 | "url": "https://opencollective.com/unified" 53 | } 54 | } 55 | }, 56 | "dependencies": { 57 | "@types/unist": { 58 | "version": "2.0.6", 59 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", 60 | "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" 61 | }, 62 | "unist-util-is": { 63 | "version": "5.1.1", 64 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", 65 | "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" 66 | }, 67 | "unist-util-visit": { 68 | "version": "4.0.0", 69 | "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", 70 | "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", 71 | "requires": { 72 | "@types/unist": "^2.0.0", 73 | "unist-util-is": "^5.0.0", 74 | "unist-util-visit-parents": "^5.0.0" 75 | } 76 | }, 77 | "unist-util-visit-parents": { 78 | "version": "5.0.0", 79 | "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", 80 | "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", 81 | "requires": { 82 | "@types/unist": "^2.0.0", 83 | "unist-util-is": "^5.0.0" 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /packages/remark-supersub/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remark-supersub", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "description": "Remark plugin for adding subscript/superscript syntax.", 6 | "author": "Alex Shaw ", 7 | "sideEffects": false, 8 | "type": "module", 9 | "exports": "./lib/index.js", 10 | "types": "lib/index.d.ts", 11 | "files": [ 12 | "lib/" 13 | ], 14 | "keywords": [ 15 | "remark", 16 | "remark-plugin" 17 | ], 18 | "repository": "https://github.com/Symbitic/remark-plugins/tree/master/packages/remark-supersub", 19 | "bugs": "https://github.com/Symbitic/remark-plugins/issues", 20 | "scripts": { 21 | "build": "tsc" 22 | }, 23 | "dependencies": { 24 | "unist-util-visit": "^4.0.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/remark-supersub/src/index.spec.ts: -------------------------------------------------------------------------------- 1 | import test, { ExecutionContext } from 'ava'; 2 | import supersub from './index.js'; 3 | import html from 'rehype-stringify' 4 | import markdown from 'remark-parse' 5 | import remark2rehype from 'remark-rehype' 6 | import { unified } from 'unified' 7 | 8 | const strip = ([str]: TemplateStringsArray) => str.replace(/\n {6}/g, '\n').replace(/\n {4}$/, '') 9 | 10 | const parse = (str: string) => 11 | unified() 12 | .use(markdown) 13 | .use(supersub) 14 | .use(remark2rehype) 15 | .use(html) 16 | .process(str) 17 | .then(data => data.toString()) 18 | ; 19 | 20 | const fixtures = [ 21 | [ 22 | 'basic supersub list', 23 | strip` 24 | 21^st^ Century 25 | 26 | H~2~O 27 | ` 28 | ] 29 | ] 30 | 31 | async function macro(t: ExecutionContext, input: any) { 32 | const result = await parse(input) 33 | t.snapshot(result) 34 | } 35 | 36 | macro.title = (name: string) => `remark-supersub should parse a ${name}`; 37 | 38 | for (const fixture of fixtures) { 39 | const [ name, source ] = fixture 40 | test(name, macro, source); 41 | } 42 | 43 | /* 44 | describe.each(fixtures)('remark-supersub', (name, source) => { 45 | it(`should parse a ${name}`, () => { 46 | return expect(parse(source)).resolves.toMatchSnapshot() 47 | }) 48 | }) 49 | */ 50 | -------------------------------------------------------------------------------- /packages/remark-supersub/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Subscript and Superscript plugin for Remark. 3 | */ 4 | import { visit } from 'unist-util-visit'; 5 | import { Transformer } from 'unified'; 6 | import { Data, Literal, Node } from 'unist'; 7 | 8 | export default function supersub(): Transformer { 9 | // Superscript 10 | return (tree) => { 11 | visit(tree, ['text'], (node, i, parent) => { 12 | if (node.type !== 'text') { 13 | return 14 | } 15 | 16 | const { value } = node as Literal 17 | 18 | const values = value.split(/\^/) 19 | if (values.length === 1 || values.length % 2 === 0) { 20 | return 21 | } 22 | 23 | const children: Node[] = values.map((str, i) => 24 | i % 2 === 0 25 | ? { 26 | type: 'text', 27 | value: str 28 | } 29 | : { 30 | type: 'superscript', 31 | data: { 32 | hName: 'sup' 33 | }, 34 | children: [ 35 | { 36 | type: 'text', 37 | value: str 38 | } 39 | ] 40 | } 41 | ) 42 | parent!.children.splice(i!, 1, ...children) 43 | }) 44 | 45 | // Subscript 46 | visit(tree, ['text'], (node, i, parent) => { 47 | if (node.type !== 'text') { 48 | return 49 | } 50 | 51 | const { value } = node as Literal 52 | 53 | // eslint-disable-next-line no-useless-escape 54 | const values = value.split(/\~/) 55 | if (values.length === 1 || values.length % 2 === 0) { 56 | return 57 | } 58 | 59 | const children: Node[] = values.map((str, i) => 60 | i % 2 === 0 61 | ? { 62 | type: 'text', 63 | value: str 64 | } 65 | : { 66 | type: 'subscript', 67 | data: { 68 | hName: 'sub' 69 | }, 70 | children: [ 71 | { 72 | type: 'text', 73 | value: str 74 | } 75 | ] 76 | } 77 | ) 78 | parent!.children.splice(i!, 1, ...children) 79 | }) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /packages/remark-supersub/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "declaration": true 6 | }, 7 | "include": [ 8 | "./src" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": [ 5 | "ES2020" 6 | ], 7 | "module": "ES2020", 8 | "moduleResolution": "node", 9 | "strict": true, 10 | "esModuleInterop": true 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | "**/*.spec.ts" 15 | ] 16 | } 17 | --------------------------------------------------------------------------------