add inline block support
fix infinite loop
This commit is contained in:
parent
f6d63781f0
commit
3e2a375aea
5 changed files with 58 additions and 18 deletions
12
README.md
12
README.md
|
@ -8,16 +8,16 @@ to write id, classes, and attributes.
|
||||||
### Where to put `{...}`
|
### Where to put `{...}`
|
||||||
|type|where|example|
|
|type|where|example|
|
||||||
|:-:|:-:|--|
|
|:-:|:-:|--|
|
||||||
|inline tag|**AFTER** tag|em / strong|
|
|inline block|**AFTER** tag|em / strong / code|
|
||||||
|inline block|beginning / end|li / td / th|
|
|inline container|beginning / end|li / td / th|
|
||||||
|block|**BEFORE** block|h1 / ul / table|
|
|block|**BEFORE** block|h1 / ul / table|
|
||||||
|
|
||||||
Note: There is no way to add attributes to `tr` without extension.
|
Note: There is no way to add attributes to `tr` without extension.
|
||||||
See [Extension: Attributes for tr](#tr-extension) for more info.
|
See [Extension: Attributes for tr](#tr-extension) for more info.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
### Attributes for inline tag
|
### Attributes for inline block
|
||||||
Add `{...}` **AFTER** the inline tag.
|
Add `{...}` **AFTER** the inline block.
|
||||||
|
|
||||||
#### em / strong
|
#### em / strong
|
||||||
Example Input:
|
Example Input:
|
||||||
|
@ -29,8 +29,8 @@ Output:
|
||||||
<p><em class="a">x</em> <strong class="b">y</strong> <em class="c"><strong>z</strong></em></p>
|
<p><em class="a">x</em> <strong class="b">y</strong> <em class="c"><strong>z</strong></em></p>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Attributes for inline block
|
### Attributes for inline container
|
||||||
Add `{...}` at the **beginning** or the **end** in the inline block.
|
Add `{...}` at the **beginning** or the **end** in the inline container.
|
||||||
|
|
||||||
#### list item
|
#### list item
|
||||||
Example Input:
|
Example Input:
|
||||||
|
|
17
lib/index.js
17
lib/index.js
|
@ -36,6 +36,7 @@ function pluginAttr(md, opts={}) {
|
||||||
// should meet end of line
|
// should meet end of line
|
||||||
if (!(attrs && index === indexEnd)) return false;
|
if (!(attrs && index === indexEnd)) return false;
|
||||||
// push
|
// push
|
||||||
|
// [block] silent: no need to update state
|
||||||
if (silent) return true;
|
if (silent) return true;
|
||||||
state.line = l0+1;
|
state.line = l0+1;
|
||||||
const token = state.push('block_attr', '', 0);
|
const token = state.push('block_attr', '', 0);
|
||||||
|
@ -53,11 +54,17 @@ function pluginAttr(md, opts={}) {
|
||||||
const {attrs, index} = parseAttrs(src, re) || {};
|
const {attrs, index} = parseAttrs(src, re) || {};
|
||||||
if (!attrs) return false;
|
if (!attrs) return false;
|
||||||
// set attr
|
// set attr
|
||||||
if (silent) return true;
|
/*
|
||||||
const token = state.push('inline_attr', '', 0);
|
[inline] silent:
|
||||||
token.attrs = attrs;
|
false -> push token and update state
|
||||||
token.content = src.substring(pos, index);
|
true -> set state.pos only
|
||||||
token.hidden = true;
|
*/
|
||||||
|
if (!silent) {
|
||||||
|
const token = state.push('inline_attr', '', 0);
|
||||||
|
token.attrs = attrs;
|
||||||
|
token.content = src.substring(pos, index);
|
||||||
|
token.hidden = true;
|
||||||
|
}
|
||||||
state.pos = index;
|
state.pos = index;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
19
lib/rules.js
19
lib/rules.js
|
@ -21,15 +21,22 @@ const inlineAttrsApplyRules = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'after_inline_close',
|
name: 'after_inline_block',
|
||||||
handler(token, i, tokens, iBlock, blockTokens) {
|
handler(token, i, tokens, iBlock, blockTokens) {
|
||||||
|
// find non-empty text token
|
||||||
const iC = rfindIndex(tokens, i-1, t=>t.type!=='text'||t.content);
|
const iC = rfindIndex(tokens, i-1, t=>t.type!=='text'||t.content);
|
||||||
const tokenC = iC>=0 && tokens[iC];
|
const tokenC = iC>=0 && tokens[iC];
|
||||||
if (!(tokenC && tokenC.nesting === -1)) return;
|
if (!tokenC) return;
|
||||||
// find open
|
// check tokenC type
|
||||||
const tokenO = findOpenToken(tokens, iC);
|
if (tokenC.nesting === -1) {
|
||||||
if (!tokenO) return false;
|
// close token -> find open and apply
|
||||||
attrConcat(tokenO, token);
|
const tokenO = findOpenToken(tokens, iC);
|
||||||
|
if (!tokenO) return false;
|
||||||
|
attrConcat(tokenO, token);
|
||||||
|
} else if (tokenC.nesting === 0 && tokenC.type !== 'text') {
|
||||||
|
// block token -> apply directly
|
||||||
|
attrConcat(tokenC, token);
|
||||||
|
} else return false; // not inline block
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@sup39/markdown-it-attr",
|
"name": "@sup39/markdown-it-attr",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"description": "A markdown-it plugin to write id, classes, and attributes",
|
"description": "A markdown-it plugin to write id, classes, and attributes",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"markdown",
|
"markdown",
|
||||||
|
@ -15,6 +15,9 @@
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"test": "mocha"
|
"test": "mocha"
|
||||||
},
|
},
|
||||||
|
"files": [
|
||||||
|
"lib/"
|
||||||
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sup39/markdown-it-raw-table": "^1.0.0",
|
"@sup39/markdown-it-raw-table": "^1.0.0",
|
||||||
"eslint": "^7.17.0",
|
"eslint": "^7.17.0",
|
||||||
|
|
|
@ -89,3 +89,26 @@ line2
|
||||||
line2
|
line2
|
||||||
</code></pre>
|
</code></pre>
|
||||||
.
|
.
|
||||||
|
|
||||||
|
|
||||||
|
ver 1.0.0 bug: should not be trapped in infinite loop
|
||||||
|
.
|
||||||
|
- a: [b}{.c}d
|
||||||
|
.
|
||||||
|
<ul>
|
||||||
|
<li>a: [b}{.c}d</li>
|
||||||
|
</ul>
|
||||||
|
.
|
||||||
|
|
||||||
|
|
||||||
|
`code` block
|
||||||
|
.
|
||||||
|
a `b`{.c} d
|
||||||
|
|
||||||
|
- `e`{.f} g
|
||||||
|
.
|
||||||
|
<p>a <code class="c">b</code> d</p>
|
||||||
|
<ul>
|
||||||
|
<li><code class="f">e</code> g</li>
|
||||||
|
</ul>
|
||||||
|
.
|
||||||
|
|
Reference in a new issue