Skip to content

Commit b8ba4e3

Browse files
committed
✨ NEW: Add definition-list plugin
1 parent ab066b7 commit b8ba4e3

File tree

11 files changed

+995
-1
lines changed

11 files changed

+995
-1
lines changed

docs/plugins.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ Other plugins are then available *via* the `markdown_it.extensions` package:
4242
:::::
4343
```
4444

45+
- [deflist](https://github.com/markdown-it/markdown-it-deflist) syntax is based on [pandoc definition lists](http://johnmacfarlane.net/pandoc/README.html#definition-lists).
46+
47+
```md
48+
Term 1
49+
50+
: Definition 1 long form
51+
52+
second paragraph
53+
54+
Term 2 with *inline markup*
55+
~ Definition 2a compact style
56+
~ Definition 2b
57+
```
58+
4559
- [texmath](https://github.com/goessner/markdown-it-texmath) parses TeX math equations set inside opening and closing delimiters:
4660

4761
```md
@@ -63,7 +77,6 @@ There are also many other plugins which could easily be ported (and hopefully wi
6377

6478
- [subscript](https://github.com/markdown-it/markdown-it-sub)
6579
- [superscript](https://github.com/markdown-it/markdown-it-sup)
66-
- [definition list](https://github.com/markdown-it/markdown-it-deflist)
6780
- [abbreviation](https://github.com/markdown-it/markdown-it-abbr)
6881
- [emoji](https://github.com/markdown-it/markdown-it-emoji)
6982
- [insert](https://github.com/markdown-it/markdown-it-ins)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Copyright (c) 2014-2015 Vitaly Puzrin, Alex Kocharin.
2+
3+
Permission is hereby granted, free of charge, to any person
4+
obtaining a copy of this software and associated documentation
5+
files (the "Software"), to deal in the Software without
6+
restriction, including without limitation the rights to use,
7+
copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the
9+
Software is furnished to do so, subject to the following
10+
conditions:
11+
12+
The above copyright notice and this permission notice shall be
13+
included in all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
OTHER DEALINGS IN THE SOFTWARE.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# markdown-it-deflist
2+
3+
[![Build Status](https://img.shields.io/travis/markdown-it/markdown-it-deflist/master.svg?style=flat)](https://travis-ci.org/markdown-it/markdown-it-deflist)
4+
[![NPM version](https://img.shields.io/npm/v/markdown-it-deflist.svg?style=flat)](https://www.npmjs.org/package/markdown-it-deflist)
5+
[![Coverage Status](https://img.shields.io/coveralls/markdown-it/markdown-it-deflist/master.svg?style=flat)](https://coveralls.io/r/markdown-it/markdown-it-deflist?branch=master)
6+
7+
> Definition list (`<dl>`) tag plugin for [markdown-it](https://github.com/markdown-it/markdown-it) markdown parser.
8+
9+
__v2.+ requires `markdown-it` v5.+, see changelog.__
10+
11+
Syntax is based on [pandoc definition lists](http://johnmacfarlane.net/pandoc/README.html#definition-lists).
12+
13+
14+
## Install
15+
16+
node.js, browser:
17+
18+
```bash
19+
npm install markdown-it-deflist --save
20+
bower install markdown-it-deflist --save
21+
```
22+
23+
## Use
24+
25+
```js
26+
var md = require('markdown-it')()
27+
.use(require('markdown-it-deflist'));
28+
29+
md.render(/*...*/);
30+
```
31+
32+
_Differences in browser._ If you load script directly into the page, without
33+
package system, module will add itself globally as `window.markdownitDeflist`.
34+
35+
36+
## License
37+
38+
[MIT](https://github.com/markdown-it/markdown-it-deflist/blob/master/LICENSE)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .index import deflist_plugin # noqa F401
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
"""Process definition lists."""
2+
from markdown_it import MarkdownIt
3+
from markdown_it.common.utils import charCodeAt
4+
from markdown_it.rules_block import StateBlock
5+
6+
7+
def deflist_plugin(md: MarkdownIt):
8+
isSpace = md.utils.isSpace
9+
10+
def skipMarker(state: StateBlock, line: int):
11+
"""Search `[:~][\n ]`, returns next pos after marker on success or -1 on fail."""
12+
start = state.bMarks[line] + state.tShift[line]
13+
maximum = state.eMarks[line]
14+
15+
if start >= maximum:
16+
return -1
17+
18+
# Check bullet
19+
marker = charCodeAt(state.src, start)
20+
start += 1
21+
if marker != 0x7E and marker != 0x3A: # ~ :
22+
return -1
23+
24+
pos = state.skipSpaces(start)
25+
26+
# require space after ":"
27+
if start == pos:
28+
return -1
29+
30+
# no empty definitions, e.g. " : "
31+
if pos >= maximum:
32+
return -1
33+
34+
return start
35+
36+
def markTightParagraphs(state: StateBlock, idx: int):
37+
38+
level = state.level + 2
39+
40+
i = idx + 2
41+
l2 = len(state.tokens) - 2
42+
while i < l2:
43+
if (
44+
state.tokens[i].level == level
45+
and state.tokens[i].type == "paragraph_open"
46+
):
47+
state.tokens[i + 2].hidden = True
48+
state.tokens[i].hidden = True
49+
i += 2
50+
i += 1
51+
52+
def deflist(state: StateBlock, startLine: int, endLine: int, silent: bool):
53+
54+
if silent:
55+
# quirk: validation mode validates a dd block only, not a whole deflist
56+
if state.ddIndent < 0:
57+
return False
58+
return skipMarker(state, startLine) >= 0
59+
60+
nextLine = startLine + 1
61+
if nextLine >= endLine:
62+
return False
63+
64+
if state.isEmpty(nextLine):
65+
nextLine += 1
66+
if nextLine >= endLine:
67+
return False
68+
69+
if state.sCount[nextLine] < state.blkIndent:
70+
return False
71+
contentStart = skipMarker(state, nextLine)
72+
if contentStart < 0:
73+
return False
74+
75+
# Start list
76+
listTokIdx = len(state.tokens)
77+
tight = True
78+
79+
token = state.push("dl_open", "dl", 1)
80+
token.map = listLines = [startLine, 0]
81+
82+
# Iterate list items
83+
dtLine = startLine
84+
ddLine = nextLine
85+
86+
# One definition list can contain multiple DTs,
87+
# and one DT can be followed by multiple DDs.
88+
#
89+
# Thus, there is two loops here, and label is
90+
# needed to break out of the second one
91+
#
92+
break_outer = False
93+
94+
while True:
95+
prevEmptyEnd = False
96+
97+
token = state.push("dt_open", "dt", 1)
98+
token.map = [dtLine, dtLine]
99+
100+
token = state.push("inline", "", 0)
101+
token.map = [dtLine, dtLine]
102+
token.content = state.getLines(
103+
dtLine, dtLine + 1, state.blkIndent, False
104+
).strip()
105+
token.children = []
106+
107+
token = state.push("dt_close", "dt", -1)
108+
109+
while True:
110+
token = state.push("dd_open", "dd", 1)
111+
token.map = itemLines = [nextLine, 0]
112+
113+
pos = contentStart
114+
maximum = state.eMarks[ddLine]
115+
offset = (
116+
state.sCount[ddLine]
117+
+ contentStart
118+
- (state.bMarks[ddLine] + state.tShift[ddLine])
119+
)
120+
121+
while pos < maximum:
122+
ch = charCodeAt(state.src, pos)
123+
124+
if isSpace(ch):
125+
if ch == 0x09:
126+
offset += 4 - offset % 4
127+
else:
128+
offset += 1
129+
else:
130+
break
131+
132+
pos += 1
133+
134+
contentStart = pos
135+
136+
oldTight = state.tight
137+
oldDDIndent = state.ddIndent
138+
oldIndent = state.blkIndent
139+
oldTShift = state.tShift[ddLine]
140+
oldSCount = state.sCount[ddLine]
141+
oldParentType = state.parentType
142+
state.blkIndent = state.ddIndent = state.sCount[ddLine] + 2
143+
state.tShift[ddLine] = contentStart - state.bMarks[ddLine]
144+
state.sCount[ddLine] = offset
145+
state.tight = True
146+
state.parentType = "deflist"
147+
148+
state.md.block.tokenize(state, ddLine, endLine, True)
149+
150+
# If any of list item is tight, mark list as tight
151+
if not state.tight or prevEmptyEnd:
152+
tight = False
153+
154+
# Item become loose if finish with empty line,
155+
# but we should filter last element, because it means list finish
156+
prevEmptyEnd = (state.line - ddLine) > 1 and state.isEmpty(
157+
state.line - 1
158+
)
159+
160+
state.tShift[ddLine] = oldTShift
161+
state.sCount[ddLine] = oldSCount
162+
state.tight = oldTight
163+
state.parentType = oldParentType
164+
state.blkIndent = oldIndent
165+
state.ddIndent = oldDDIndent
166+
167+
token = state.push("dd_close", "dd", -1)
168+
169+
itemLines[1] = nextLine = state.line
170+
171+
if nextLine >= endLine:
172+
break_outer = True
173+
break
174+
175+
if state.sCount[nextLine] < state.blkIndent:
176+
break_outer = True
177+
break
178+
179+
contentStart = skipMarker(state, nextLine)
180+
if contentStart < 0:
181+
break
182+
183+
ddLine = nextLine
184+
185+
# go to the next loop iteration:
186+
# insert DD tag and repeat checking
187+
188+
if break_outer:
189+
break_outer = False
190+
break
191+
192+
if nextLine >= endLine:
193+
break
194+
dtLine = nextLine
195+
196+
if state.isEmpty(dtLine):
197+
break
198+
if state.sCount[dtLine] < state.blkIndent:
199+
break
200+
201+
ddLine = dtLine + 1
202+
if ddLine >= endLine:
203+
break
204+
if state.isEmpty(ddLine):
205+
ddLine += 1
206+
if ddLine >= endLine:
207+
break
208+
209+
if state.sCount[ddLine] < state.blkIndent:
210+
break
211+
contentStart = skipMarker(state, ddLine)
212+
if contentStart < 0:
213+
break
214+
215+
# go to the next loop iteration:
216+
# insert DT and DD tags and repeat checking
217+
218+
# Finalise list
219+
token = state.push("dl_close", "dl", -1)
220+
221+
listLines[1] = nextLine
222+
223+
state.line = nextLine
224+
225+
# mark paragraphs tight if needed
226+
if tight:
227+
markTightParagraphs(state, listTokIdx)
228+
229+
return True
230+
231+
md.block.ruler.before(
232+
"paragraph", "deflist", deflist, {"alt": ["paragraph", "reference"]}
233+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
- package: markdown-it-deflist
2+
commit: 20db400948520308291da029a23b0751cb30f3a0
3+
date: July 12, 2017
4+
version: 2.0.3
5+
changes:

tests/test_deflist/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)