Vitaly Puzrin
10 years ago
11 changed files with 1 additions and 526 deletions
@ -1,66 +0,0 @@ |
|||
// Process footnote reference list
|
|||
|
|||
'use strict'; |
|||
|
|||
|
|||
module.exports = function footnote(state, startLine, endLine, silent) { |
|||
var oldBMark, oldTShift, oldParentType, pos, label, |
|||
start = state.bMarks[startLine] + state.tShift[startLine], |
|||
max = state.eMarks[startLine]; |
|||
|
|||
// line should be at least 5 chars - "[^x]:"
|
|||
if (start + 4 > max) { return false; } |
|||
|
|||
if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; } |
|||
if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; } |
|||
|
|||
for (pos = start + 2; pos < max; pos++) { |
|||
if (state.src.charCodeAt(pos) === 0x20) { return false; } |
|||
if (state.src.charCodeAt(pos) === 0x5D /* ] */) { |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (pos === start + 2) { return false; } // no empty footnote labels
|
|||
if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A /* : */) { return false; } |
|||
if (silent) { return true; } |
|||
pos++; |
|||
|
|||
if (!state.env.footnotes) { state.env.footnotes = {}; } |
|||
if (!state.env.footnotes.refs) { state.env.footnotes.refs = {}; } |
|||
label = state.src.slice(start + 2, pos - 2); |
|||
state.env.footnotes.refs[':' + label] = -1; |
|||
|
|||
state.tokens.push({ |
|||
type: 'footnote_reference_open', |
|||
label: label, |
|||
level: state.level++ |
|||
}); |
|||
|
|||
oldBMark = state.bMarks[startLine]; |
|||
oldTShift = state.tShift[startLine]; |
|||
oldParentType = state.parentType; |
|||
state.tShift[startLine] = state.skipSpaces(pos) - pos; |
|||
state.bMarks[startLine] = pos; |
|||
state.blkIndent += 4; |
|||
state.parentType = 'footnote'; |
|||
|
|||
if (state.tShift[startLine] < state.blkIndent) { |
|||
state.tShift[startLine] += state.blkIndent; |
|||
state.bMarks[startLine] -= state.blkIndent; |
|||
} |
|||
|
|||
state.md.block.tokenize(state, startLine, endLine, true); |
|||
|
|||
state.parentType = oldParentType; |
|||
state.blkIndent -= 4; |
|||
state.tShift[startLine] = oldTShift; |
|||
state.bMarks[startLine] = oldBMark; |
|||
|
|||
state.tokens.push({ |
|||
type: 'footnote_reference_close', |
|||
level: --state.level |
|||
}); |
|||
|
|||
return true; |
|||
}; |
@ -1,95 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
|
|||
module.exports = function footnote_block(state) { |
|||
var i, l, j, t, lastParagraph, list, tokens, current, currentLabel, |
|||
level = 0, |
|||
insideRef = false, |
|||
refTokens = {}; |
|||
|
|||
if (!state.env.footnotes) { return; } |
|||
|
|||
state.tokens = state.tokens.filter(function(tok) { |
|||
if (tok.type === 'footnote_reference_open') { |
|||
insideRef = true; |
|||
current = []; |
|||
currentLabel = tok.label; |
|||
return false; |
|||
} |
|||
if (tok.type === 'footnote_reference_close') { |
|||
insideRef = false; |
|||
// prepend ':' to avoid conflict with Object.prototype members
|
|||
refTokens[':' + currentLabel] = current; |
|||
return false; |
|||
} |
|||
if (insideRef) { current.push(tok); } |
|||
return !insideRef; |
|||
}); |
|||
|
|||
if (!state.env.footnotes.list) { return; } |
|||
list = state.env.footnotes.list; |
|||
|
|||
state.tokens.push({ |
|||
type: 'footnote_block_open', |
|||
level: level++ |
|||
}); |
|||
for (i = 0, l = list.length; i < l; i++) { |
|||
state.tokens.push({ |
|||
type: 'footnote_open', |
|||
id: i, |
|||
level: level++ |
|||
}); |
|||
|
|||
if (list[i].tokens) { |
|||
tokens = []; |
|||
tokens.push({ |
|||
type: 'paragraph_open', |
|||
tight: false, |
|||
level: level++ |
|||
}); |
|||
tokens.push({ |
|||
type: 'inline', |
|||
content: '', |
|||
level: level, |
|||
children: list[i].tokens |
|||
}); |
|||
tokens.push({ |
|||
type: 'paragraph_close', |
|||
tight: false, |
|||
level: --level |
|||
}); |
|||
} else if (list[i].label) { |
|||
tokens = refTokens[':' + list[i].label]; |
|||
} |
|||
|
|||
state.tokens = state.tokens.concat(tokens); |
|||
if (state.tokens[state.tokens.length - 1].type === 'paragraph_close') { |
|||
lastParagraph = state.tokens.pop(); |
|||
} else { |
|||
lastParagraph = null; |
|||
} |
|||
|
|||
t = list[i].count > 0 ? list[i].count : 1; |
|||
for (j = 0; j < t; j++) { |
|||
state.tokens.push({ |
|||
type: 'footnote_anchor', |
|||
id: i, |
|||
subId: j, |
|||
level: level |
|||
}); |
|||
} |
|||
|
|||
if (lastParagraph) { |
|||
state.tokens.push(lastParagraph); |
|||
} |
|||
|
|||
state.tokens.push({ |
|||
type: 'footnote_close', |
|||
level: --level |
|||
}); |
|||
} |
|||
state.tokens.push({ |
|||
type: 'footnote_block_close', |
|||
level: --level |
|||
}); |
|||
}; |
@ -1,50 +0,0 @@ |
|||
// Process inline footnotes (^[...])
|
|||
|
|||
'use strict'; |
|||
|
|||
var parseLinkLabel = require('../helpers/parse_link_label'); |
|||
|
|||
|
|||
module.exports = function footnote_inline(state, silent) { |
|||
var labelStart, |
|||
labelEnd, |
|||
footnoteId, |
|||
oldLength, |
|||
max = state.posMax, |
|||
start = state.pos; |
|||
|
|||
if (start + 2 >= max) { return false; } |
|||
if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; } |
|||
if (state.src.charCodeAt(start + 1) !== 0x5B/* [ */) { return false; } |
|||
|
|||
labelStart = start + 2; |
|||
labelEnd = parseLinkLabel(state, start + 1); |
|||
|
|||
// parser failed to find ']', so it's not a valid note
|
|||
if (labelEnd < 0) { return false; } |
|||
|
|||
// We found the end of the link, and know for a fact it's a valid link;
|
|||
// so all that's left to do is to call tokenizer.
|
|||
//
|
|||
if (!silent) { |
|||
if (!state.env.footnotes) { state.env.footnotes = {}; } |
|||
if (!state.env.footnotes.list) { state.env.footnotes.list = []; } |
|||
footnoteId = state.env.footnotes.list.length; |
|||
|
|||
state.pos = labelStart; |
|||
state.posMax = labelEnd; |
|||
|
|||
state.push({ |
|||
type: 'footnote_ref', |
|||
id: footnoteId, |
|||
level: state.level |
|||
}); |
|||
oldLength = state.tokens.length; |
|||
state.md.inline.tokenize(state); |
|||
state.env.footnotes.list[footnoteId] = { tokens: state.tokens.splice(oldLength) }; |
|||
} |
|||
|
|||
state.pos = labelEnd + 1; |
|||
state.posMax = max; |
|||
return true; |
|||
}; |
@ -1,61 +0,0 @@ |
|||
// Process footnote references ([^...])
|
|||
|
|||
'use strict'; |
|||
|
|||
|
|||
module.exports = function footnote_ref(state, silent) { |
|||
var label, |
|||
pos, |
|||
footnoteId, |
|||
footnoteSubId, |
|||
max = state.posMax, |
|||
start = state.pos; |
|||
|
|||
// should be at least 4 chars - "[^x]"
|
|||
if (start + 3 > max) { return false; } |
|||
|
|||
if (!state.env.footnotes || !state.env.footnotes.refs) { return false; } |
|||
if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; } |
|||
if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; } |
|||
|
|||
for (pos = start + 2; pos < max; pos++) { |
|||
if (state.src.charCodeAt(pos) === 0x20) { return false; } |
|||
if (state.src.charCodeAt(pos) === 0x0A) { return false; } |
|||
if (state.src.charCodeAt(pos) === 0x5D /* ] */) { |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (pos === start + 2) { return false; } // no empty footnote labels
|
|||
if (pos >= max) { return false; } |
|||
pos++; |
|||
|
|||
label = state.src.slice(start + 2, pos - 1); |
|||
if (typeof state.env.footnotes.refs[':' + label] === 'undefined') { return false; } |
|||
|
|||
if (!silent) { |
|||
if (!state.env.footnotes.list) { state.env.footnotes.list = []; } |
|||
|
|||
if (state.env.footnotes.refs[':' + label] < 0) { |
|||
footnoteId = state.env.footnotes.list.length; |
|||
state.env.footnotes.list[footnoteId] = { label: label, count: 0 }; |
|||
state.env.footnotes.refs[':' + label] = footnoteId; |
|||
} else { |
|||
footnoteId = state.env.footnotes.refs[':' + label]; |
|||
} |
|||
|
|||
footnoteSubId = state.env.footnotes.list[footnoteId].count; |
|||
state.env.footnotes.list[footnoteId].count++; |
|||
|
|||
state.push({ |
|||
type: 'footnote_ref', |
|||
id: footnoteId, |
|||
subId: footnoteSubId, |
|||
level: state.level |
|||
}); |
|||
} |
|||
|
|||
state.pos = pos; |
|||
state.posMax = max; |
|||
return true; |
|||
}; |
@ -1,185 +0,0 @@ |
|||
|
|||
Pandoc example: |
|||
. |
|||
Here is a footnote reference,[^1] and another.[^longnote] |
|||
|
|||
[^1]: Here is the footnote. |
|||
|
|||
[^longnote]: Here's one with multiple blocks. |
|||
|
|||
Subsequent paragraphs are indented to show that they |
|||
belong to the previous footnote. |
|||
|
|||
{ some.code } |
|||
|
|||
The whole paragraph can be indented, or just the first |
|||
line. In this way, multi-paragraph footnotes work like |
|||
multi-paragraph list items. |
|||
|
|||
This paragraph won't be part of the note, because it |
|||
isn't indented. |
|||
. |
|||
<p>Here is a footnote reference,<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> and another.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p> |
|||
<p>This paragraph won’t be part of the note, because it |
|||
isn’t indented.</p> |
|||
<hr class="footnotes-sep"> |
|||
<section class="footnotes"> |
|||
<ol class="footnotes-list"> |
|||
<li id="fn1" class="footnote-item"><p>Here is the footnote. <a href="#fnref1" class="footnote-backref">↩</a></p> |
|||
</li> |
|||
<li id="fn2" class="footnote-item"><p>Here’s one with multiple blocks.</p> |
|||
<p>Subsequent paragraphs are indented to show that they |
|||
belong to the previous footnote.</p> |
|||
<pre><code>{ some.code } |
|||
</code></pre> |
|||
<p>The whole paragraph can be indented, or just the first |
|||
line. In this way, multi-paragraph footnotes work like |
|||
multi-paragraph list items. <a href="#fnref2" class="footnote-backref">↩</a></p> |
|||
</li> |
|||
</ol> |
|||
</section> |
|||
. |
|||
|
|||
|
|||
|
|||
They could terminate each other: |
|||
|
|||
. |
|||
[^1][^2][^3] |
|||
|
|||
[^1]: foo |
|||
[^2]: bar |
|||
[^3]: baz |
|||
. |
|||
<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup><sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup></p> |
|||
<hr class="footnotes-sep"> |
|||
<section class="footnotes"> |
|||
<ol class="footnotes-list"> |
|||
<li id="fn1" class="footnote-item"><p>foo <a href="#fnref1" class="footnote-backref">↩</a></p> |
|||
</li> |
|||
<li id="fn2" class="footnote-item"><p>bar <a href="#fnref2" class="footnote-backref">↩</a></p> |
|||
</li> |
|||
<li id="fn3" class="footnote-item"><p>baz <a href="#fnref3" class="footnote-backref">↩</a></p> |
|||
</li> |
|||
</ol> |
|||
</section> |
|||
. |
|||
|
|||
|
|||
They could be inside blockquotes, and are lazy: |
|||
. |
|||
[^foo] |
|||
|
|||
> [^foo]: bar |
|||
baz |
|||
. |
|||
<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> |
|||
<blockquote> |
|||
</blockquote> |
|||
<hr class="footnotes-sep"> |
|||
<section class="footnotes"> |
|||
<ol class="footnotes-list"> |
|||
<li id="fn1" class="footnote-item"><p>bar |
|||
baz <a href="#fnref1" class="footnote-backref">↩</a></p> |
|||
</li> |
|||
</ol> |
|||
</section> |
|||
. |
|||
|
|||
|
|||
Their labels could not contain spaces or newlines: |
|||
|
|||
. |
|||
[^ foo]: bar baz |
|||
|
|||
[^foo |
|||
]: bar baz |
|||
. |
|||
<p>[^ foo]: bar baz</p> |
|||
<p>[^foo |
|||
]: bar baz</p> |
|||
. |
|||
|
|||
|
|||
We support inline notes too (pandoc example): |
|||
|
|||
. |
|||
Here is an inline note.^[Inlines notes are easier to write, since |
|||
you don't have to pick an identifier and move down to type the |
|||
note.] |
|||
. |
|||
<p>Here is an inline note.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> |
|||
<hr class="footnotes-sep"> |
|||
<section class="footnotes"> |
|||
<ol class="footnotes-list"> |
|||
<li id="fn1" class="footnote-item"><p>Inlines notes are easier to write, since |
|||
you don’t have to pick an identifier and move down to type the |
|||
note. <a href="#fnref1" class="footnote-backref">↩</a></p> |
|||
</li> |
|||
</ol> |
|||
</section> |
|||
. |
|||
|
|||
|
|||
They could have arbitrary markup: |
|||
|
|||
. |
|||
foo^[ *bar* ] |
|||
. |
|||
<p>foo<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> |
|||
<hr class="footnotes-sep"> |
|||
<section class="footnotes"> |
|||
<ol class="footnotes-list"> |
|||
<li id="fn1" class="footnote-item"><p> <em>bar</em> <a href="#fnref1" class="footnote-backref">↩</a></p> |
|||
</li> |
|||
</ol> |
|||
</section> |
|||
. |
|||
|
|||
|
|||
Indents: |
|||
|
|||
. |
|||
[^xxxxx] [^yyyyy] |
|||
|
|||
[^xxxxx]: foo |
|||
--- |
|||
|
|||
[^yyyyy]: foo |
|||
--- |
|||
. |
|||
<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p> |
|||
<hr> |
|||
<hr class="footnotes-sep"> |
|||
<section class="footnotes"> |
|||
<ol class="footnotes-list"> |
|||
<li id="fn1" class="footnote-item"><h2>foo</h2> |
|||
<a href="#fnref1" class="footnote-backref">↩</a></li> |
|||
<li id="fn2" class="footnote-item"><p>foo <a href="#fnref2" class="footnote-backref">↩</a></p> |
|||
</li> |
|||
</ol> |
|||
</section> |
|||
. |
|||
|
|||
|
|||
Indents for the first line: |
|||
|
|||
. |
|||
[^xxxxx] [^yyyyy] |
|||
|
|||
[^xxxxx]: foo |
|||
|
|||
[^yyyyy]: foo |
|||
. |
|||
<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p> |
|||
<hr class="footnotes-sep"> |
|||
<section class="footnotes"> |
|||
<ol class="footnotes-list"> |
|||
<li id="fn1" class="footnote-item"><p>foo <a href="#fnref1" class="footnote-backref">↩</a></p> |
|||
</li> |
|||
<li id="fn2" class="footnote-item"><pre><code>foo |
|||
</code></pre> |
|||
<a href="#fnref2" class="footnote-backref">↩</a></li> |
|||
</ol> |
|||
</section> |
|||
. |
Loading…
Reference in new issue