remark plugin to assign serial numbers.
remark-cli
is required remark-numbers
to run as command.
$ mkdir numbers
$ cd numbers
$ npm init -y
$ npm install remark-cli remark-directive remark-frontmatter remark-gfm @hankei6km/remark-numbers
// .remarkrc.mjs
import remarkDirective from 'remark-directive'
import remarkFrontmatter from 'remark-frontmatter';
import remarkGfm from 'remark-gfm'
import remarkNumbers from '@hankei6km/remark-numbers'
const remarkConfig = {
plugins: [
remarkDirective,
remarkFrontmatter,
remarkGfm,
remarkNumbers
]
}
export default remarkConfig
The basic usage is as follows.
$ npx remark < input.md
input:
# test
## test :num[sec]
section :num[sec]
### test :num[sec]-:num[subsec]
section :num[sec]-:num[subsec]
### test :num[sec]-:num[subsec]
section :num[sec]-:num[subsec]
## test :num[sec]
section :num[sec]
### test :num[sec]-:num[subsec]
section :num[sec]-:num[subsec]
yield:
# test
## test 1
section 1
### test 1-1
section 1-1
### test 1-2
section 1-2
## test 2
section 2
### test 2-1
section 2-1
Following counters are available with default settings
sec
subsec
input:
# test
![Charlie](/images/photo-charlie.jpg)
*Photo :num{#charlie}*
![Don](/images/don.jpg)
*Photo :num{#don}*
Charlie(Photo :num[charlie]) and Don(Photo :num[don])
yield:
# test
![Charlie](/images/photo-charlie.jpg)
*Photo 1*
![Don](/images/don.jpg)
*Photo 2*
Charlie(Photo 1) and Don(Photo 2)
input:
# test
今季の傾向です(Chart :num[chart-overview])
![Overview](/images/chart-overview.png)
*Chart :num{#chart-overview}*
## Fruits
資料(Chart :num[chart-fruits]) によると Orange(Photo :num[photo-orange]) が好調です。
![Fruits](/images/chart-fruits.png)
*Chart :num{#chart-fruits}*
![Apple](/images/apple.jpg)
*Photo :num{#photo-apple}*
![Banana](/images/banana.jpg)
*Photo :num{#photo-banana}*
![Orange](/images/orange.jpg)
*Photo :num{#photo-orange}*
## Drink
資料(Chart :num[chart-drink]) によると Tea(Photo :num[photo-tea]) は Apple(Photo :num[photo-apple]) とのセットメニューが好調です。
![Drink](/images/chart-drink.png)
*Chart :num{#chart-drink}*
![Coffee](/images/coffee.jpg)
*Photo :num{#photo-coffee}*
![Tea](/images/tea.jpg)
*Photo :num{#photo-tea}*
yield:
# test
今季の傾向です(Chart 1)
![Overview](/images/chart-overview.png)
*Chart 1*
## Fruits
資料(Chart 1-1) によると Orange(Photo 1-3) が好調です。
![Fruits](/images/chart-fruits.png)
*Chart 1-1*
![Apple](/images/apple.jpg)
*Photo 1-1*
![Banana](/images/banana.jpg)
*Photo 1-2*
![Orange](/images/orange.jpg)
*Photo 1-3*
## Drink
資料(Chart 2-1) によると Tea(Photo 2-2) は Apple(Photo 1-1) とのセットメニューが好調です。
![Drink](/images/chart-drink.png)
*Chart 2-1*
![Coffee](/images/coffee.jpg)
*Photo 2-1*
![Tea](/images/tea.jpg)
*Photo 2-2*
Following series are available with default settings
fig
photo
chart
graph
diagram
flow
tbl
list
input:
# test
:::num{format assign}
:num[(図 :num)]{series=fig}
:num[(図 :num[sec]-:num)]{series=fig}
:::
![Editors](/images/editors.png)
*:num{#fig-editors}*
Screenshot:num[fig-editors]
## Vim
![Vim](/images/screenshot-vim)
*:num{#fig-vim}*
Screenshot:num[fig-vim]
## VS Code
![VS Code](/images/screenshot-vscode)
*:num{#fig-vscode}*
Screenshot:num[fig-vscode]
yield:
# test
![Editors](/images/editors.png)
*(図 1)*
Screenshot(図 1)
## Vim
![Vim](/images/screenshot-vim)
*(図 1-1)*
Screenshot(図 1-1)
## VS Code
![VS Code](/images/screenshot-vscode)
*(図 2-1)*
Screenshot(図 2-1)
input:
---
title: test
numGroupName: simple
---
# test
:::num{format assign}
:num[(図 :num)]{series=fig}
:num[(図 :num[sec]-:num)]{series=fig}
:::
:::num{reset assign name=simple}
## :num{delete}
:::
:::num{format assign name=simple}
:num[(図 :num)]{series=fig}
:::
![Editors](/images/editors.png)
*:num{#fig-editors}*
Screenshot:num[fig-editors]
## Vim
![Vim](/images/screenshot-vim)
*:num{#fig-vim}*
Screenshot:num[fig-vim]
## VS Code
![VS Code](/images/screenshot-vscode)
*:num{#fig-vscode}*
Screenshot:num[fig-vscode]
yield:
---
title: test
---
# test
![Editors](/images/editors.png)
*(図 1)*
Screenshot(図 1)
## Vim
![Vim](/images/screenshot-vim)
*(図 2)*
Screenshot(図 2)
## VS Code
![VS Code](/images/screenshot-vscode)
*(図 3)*
Screenshot(図 3)
input:
# test
:::num{reset counter}
# :num{#subsubsec}
## :num{#subsubsec}
### :num{#subsubsec}
:::
:::num{increment counter}
#### :num{#subsubsec}
:::
## test :num[sec]
### test :num[sec]-:num[subsec]
#### test :num[sec]-:num[subsec]-:num[subsubsec]
#### test :num[sec]-:num[subsec]-:num[subsubsec]
### test :num[sec]-:num[subsec]
#### test :num[sec]-:num[subsec]-:num[subsubsec]
#### test :num[sec]-:num[subsec]-:num[subsubsec]
#### test :num[sec]-:num[subsec]-:num[subsubsec]
## test :num[sec]
### test :num[sec]-:num[subsec]
#### test :num[sec]-:num[subsec]-:num[subsubsec]
#### test :num[sec]-:num[subsec]-:num[subsubsec]
yield:
# test
## test 1
### test 1-1
#### test 1-1-1
#### test 1-1-2
### test 1-2
#### test 1-2-1
#### test 1-2-2
#### test 1-2-3
## test 2
### test 2-1
#### test 2-1-1
#### test 2-1-2
:num{#counter_name reset}
:num{#counter_name reset=10}
Define(reset) the counter.
The initial value can be set with reset
attribute.
The description will be removed.
:num[counter_name]
:num[counter_name]{up}
Refer to the value of the counter
"up" attribute increments before referencing the value of the counter
Replaced by the value of the variable.
:::num{reset counter}
# :num{#counter_name1}
# :num{#counter_name2}
## :num{#counter_name2}
:::
Set "heading node" to triggers to reset counter.
The description will be removed.
:::num{increment counter}
## :num{#counter_name1}
### :num{#counter_name2}
:::
Set "heading node" to triggers to increment counter.
The description will be removed.
:num{#variable_name}
:num{#series-variable_name}
Define variables. The value is the number of defined times. variables. Series name is specified by -
delimiter
Replaced by the value of the variable.
:num[variable_name]
:num[series-variable]
Refer to the variable.
If series is binded format text, it will be applied.
Replaced by the value of the variable.
:::num{reset assign}
# :num
## :num
:::
Set "heading node" to triggers to reset counter.
Trigger will be removed, when delete
attribute is written.
:::num{reset assign}
## :num{delete}
:::
The description will be removed.
:::num{reset assign name=group-name}
## :num
:::
The group name is assigned to reset setting by {name=groupt-name}
.
The group is switched by front-matter variabe.
---
title: test
numGroupName: group-name
---
# test
The description will be removed.
:::num{format assign}
:num[figure :num]{series=fig}
:num[figure :num[counter_name]-:num]{series=fig}
:::
Set format to series. Format is written in []
as Markdown.
:num[counter_name]
- Refer to the counter:num
- Refer to the value of the variable itself
If the referenced counter is 0
or undefined, the format is not used.
The last matching format will be used, when multiple settings are described,.
The description will be removed.
:::num{format assign name=group-name}
:num[図 :num]{series=fig}
:num[図 :num[counter_name]-:num]{series=fig}
:::
The group name is assigned to reset setting by {name=groupt-name}
.
The group is switched by front-matter variabe.
---
title: test
numGroupName: group-name
---
# test
The description will be removed.
Default template:
:::num{reset counter}
# :num{#sec}
# :num{#subsec}
## :num{#subsec}
:::
:::num{increment counter}
## :num{#sec}
### :num{#subsec}
:::
:::num{reset assign}
# :num
## :num
:::
:::num{format assign}
:num[:num[sec]-:num]{series=fig}
:num[:num[sec]-:num]{series=photo}
:num[:num[sec]-:num]{series=chart}
:num[:num[sec]-:num]{series=graph}
:num[:num[sec]-:num]{series=diagram}
:num[:num[sec]-:num]{series=flow}
:num[:num[sec]-:num]{series=tbl}
:num[:num[sec]-:num]{series=list}
Templates are defined via plugin options
ie. define templates in config file of remark-cli
.
// .remarkrc.mjs
import remarkDirective from 'remark-directive'
import remarkFrontmatter from 'remark-frontmatter'
import remarkGfm from 'remark-gfm'
import remarkNumbers from '@hankei6km/remark-numbers'
const remarkConfig = {
plugins: [
remarkDirective,
remarkFrontmatter,
remarkGfm,
[
remarkNumbers,
{
template: [
`
:::num{format assign}
:num[図 :num]{series=fig}
:num[図 :num[sec]-:num]{series=fig}
:num[写真 :num]{series=photo}
:num[写真 :num[sec]-:num]{series=photo}
:num[グラフ :num]{series=chart}
:num[グラフ :num[sec]-:num]{series=chart}
:num[グラフ :num]{series=graph}
:num[グラフ :num[sec]-:num]{series=graph}
:num[図式 :num]{series=diagram}
:num[図式 :num[sec]-:num]{series=diagram}
:num[フロー :num]{series=flow}
:num[フロー :num[sec]-:num]{series=flow}
:num[表 :num]{series=tbl}
:num[表 :num[sec]-:num]{series=tbl}
:num[リスト :num]{series=list}
:num[リスト :num[sec]-:num]{series=list}
:::
`
],
keepDefaultTemplate: true
}
]
]
}
export default remarkConfig
import { readFileSync } from 'fs'
import { unified } from 'unified'
import remarkParse from 'remark-parse'
import remarkStringify from 'remark-stringify'
import remarkDirective from 'remark-directive'
import remarkNumbers from '@hankei6km/remark-numbers'
const markdown = readFileSync('test.md').toString()
unified()
.use(remarkParse)
.use(remarkDirective)
.use(remarkNumbers)
.use(remarkStringify)
.freeze()
.process(markdown, (err, file) => {
if (err) {
console.error(err)
}
console.log(String(file))
})
Pass templates.
- type:
string[]
Use default template with passed templates.
- type:
boolean
- default:
false
The name of field in Front Matter to switch group.
- type:
string
- default:
numGroupName
remark-numbers
operates under the assumption that it handles trusted sources.
It is recommended to use rehype-sanitize
when handle sources from a third party.
- Variables and counters are processed in AST node order. Therefore, it may not be in the order of description.
MIT License
Copyright (c) 2022 hankei6km