Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduce nested admonitions #42

Closed
wants to merge 14 commits into from
31 changes: 31 additions & 0 deletions .github/workflows/node.js.yml
@@ -0,0 +1,31 @@
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Node.js CI

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -3,4 +3,5 @@ node_modules
# files generated during testing
test/*.html
# editor configuration files
.vscode
.vscode
.DS_Store
13 changes: 0 additions & 13 deletions .travis.yml
Expand Up @@ -8,19 +8,6 @@ jobs:
script: npm test
- stage: lint
script: npm run lint
- stage: release
if: type = push AND tag IS present
install: true
script: skip
deploy:
provider: npm
email: elviswolcott@gmail.com
api_key:
secure: lNF+2FSZU0EsH9jerhWYbZT9dKiO1Kfz2NPuA/mSk5UkVTOQC+8A9ufkyF9kkwcDgBXvxsUcI0OM9C0wQatE2DIqGNOo9YzkUfF7zcxC63Nb878alp6tcVDflRIP/a5X3la5loq7uxEPD/8JJICt54Y6OJBW8GlZ8+ZvtlZzba8ZIW3G6JEBh1mXH1ZGBCbRuVw7kLaFe7E1VEgYHLIcAm6bVB8DvK4Kqtjx4karv8y8+u2NMV+qj9QkrqHpqTfcwNqbQXmKJIcdX42tC4f8ImweeE4Jvv0s6bg76FTuOR1O4yTp+8gUplZqdP6JWJj3OS3RaooYrrUqN4d7ZJ5z8u3yvzu8LrVfQmruza+TkixNLKzQfGwAxPtt/Rc/VWyG3aJNcz8AkAyufnLX/OOT6XR2oBSZtB9Dhk7OcZeKu9ZpLg9J8Z73weWJipCYsVefnxEVg01fzqrfeKBC1jBeuOEe3IEcMkczpxDAp4o5wpyc7KaHdcWTFzasOIWjb/XNgQ6JRylIDD+Zg9HiQjzKodE3hDELMypRHVBD2a9sdxO2pNIpBSvf7LAJAz5okxl1+y2S9Hn6+aNEL0aMMP0pxBi4A28vVc4oSVHy4Uz1mKaJSj1z6BWxZ0N06CKAoDe8GjWi3ycimRvU86nGIUOWJ/eBVNRuqNdFmRW4+zVs6WU=
on:
tags: true
repo: elviswolcott/remark-admonitions
branch: master
stages:
- test
- lint
Expand Down
43 changes: 40 additions & 3 deletions README.md
@@ -1,7 +1,44 @@
[![Travis (.com)](https://img.shields.io/travis/com/elviswolcott/remark-admonitions?logo=travis)](https://travis-ci.com/elviswolcott/remark-admonitions)
[![npm](https://img.shields.io/npm/v/remark-admonitions?label=remark-admonitions&logo=npm)](https://www.npmjs.com/package/remark-admonitions)
[![Node.js CI](https://github.com/lebalz/remark-admonitions/actions/workflows/node.js.yml/badge.svg)](https://github.com/lebalz/remark-admonitions/actions/workflows/node.js.yml)
[![npm](https://img.shields.io/npm/v/@lebalz/remark-admonitions?label=@lebalz/remark-admonitions&logo=npm)](https://www.npmjs.com/package/@lebalz/remark-admonitions)

# remark-admonitions

Since [remark-admonitions](https://github.com/elviswolcott/remark-admonitions) seems to be unmaintained, this package adds support of nested admonitions (adds [this PR](https://github.com/elviswolcott/remark-admonitions/issues/41)).

This package adds support for nested admonitions (or other remark plugins which have a `:::` markup).

```bash
npm install @lebalz/remark-admonitions
```

or

```bash
yarn add @lebalz/remark-admonitions
```

To use in docusaurus, edit your config as follows:

```js
const admonitions = require('@lebalz/remark-admonitions');

module.exports = {
presets: [
//...,
admonitions: false,
remarkPlugins: [
//...,
[admonitions, { /* options */]
]
]
}
```


Credits to [@elviswolcott](https://github.com/elviswolcott) who built the original `remark-admonitions` plugin.

---

> A [remark](https://github.com/remarkjs/remark) plugin for admonitions designed with Docusaurus v2 in mind.

> `remark-admonitions` is now included out-of-the-box with `@docusaurus/preset-classic`!
Expand All @@ -13,7 +50,7 @@
`remark-admonitions` is available on NPM.

```bash
npm install remark-admonitions
npm install @lebalz/remark-admonitions
```

## unified + remark
Expand Down
36 changes: 28 additions & 8 deletions lib/index.js
Expand Up @@ -2,6 +2,8 @@
const unified = require("unified");
const html = require("rehype-parse");
const visit = require("unist-util-visit");
const GithubSlugger = require("github-slugger");
const slugger = new GithubSlugger();

const NEWLINE = "\n";

Expand Down Expand Up @@ -143,6 +145,10 @@ module.exports = function attacher(options) {
.map(escapeRegExp)
.join("|");
const tag = escapeRegExp(config.tag);
// tag followed by some non-whitespace characters
const isOpeningTag = new RegExp(`^${tag}\\S+`);
// closing tag: tag, optionally followed by whitespace characters
const isClosingTag = new RegExp(`^${tag}\\s*$`);
const regex = new RegExp(`${tag}(${keywords})(?: *(.*))?\n`);
const escapeTag = new RegExp(escapeRegExp(`\\${config.tag}`), "g");

Expand All @@ -161,15 +167,27 @@ module.exports = function attacher(options) {

// consume lines until a closing tag
let idx = 0;
let level = 0;
while ((idx = value.indexOf(NEWLINE)) !== -1) {
// grab this line and eat it
const next = value.indexOf(NEWLINE, idx + 1);
const line =
next !== -1 ? value.slice(idx + 1, next) : value.slice(idx + 1);
food.push(line);
value = value.slice(idx + 1);
// the closing tag is NOT part of the content
if (line.startsWith(config.tag)) break;

// keep track of nested opening tags
if (isOpeningTag.test(line)) level += 1;

// test for a closing tag
if (isClosingTag.test(line)) {
// the closing tag at level 0 is NOT part of the content
if (level === 0) break;

// a nested block was closed
level -= 1;
}

content.push(line);
}

Expand Down Expand Up @@ -200,18 +218,19 @@ module.exports = function attacher(options) {
? []
: [element("span", "admonition-icon", [iconNodes])];

const header = element("h5", "", iconContainerNodes.concat(titleNodes));
if (title) {
header.data.hProperties.id = slugger.slug(title);
header.type = "heading";
}

// build the nodes for the full markup
const admonition = element(
"div",
["admonition", `admonition-${keyword}`].concat(
settings.ifmClass ? ["alert", `alert--${settings.ifmClass}`] : []
),
[
element("div", "admonition-heading", [
element("h5", "", iconContainerNodes.concat(titleNodes))
]),
contentNodes
]
[element("div", "admonition-heading", [header]), contentNodes]
);

return add(admonition);
Expand Down Expand Up @@ -244,6 +263,7 @@ module.exports = function attacher(options) {
// TODO: add compiler rules for converting back to markdown

return function transformer(tree) {
slugger.reset();
// escape everything except admonitionHTML nodes
visit(
tree,
Expand Down