Fix footnote ordering and some other bugs
This commit is contained in:
parent
b1f9bfc9e9
commit
d5bf4317b2
7 changed files with 105 additions and 28 deletions
|
@ -10,7 +10,7 @@ import (
|
|||
type Document struct {
|
||||
tokens []token
|
||||
Nodes []Node
|
||||
Footnotes Footnotes
|
||||
Footnotes *Footnotes
|
||||
StatusKeywords []string
|
||||
MaxEmphasisNewLines int
|
||||
BufferSettings map[string]string
|
||||
|
@ -52,10 +52,10 @@ var nilToken = token{"nil", -1, "", nil}
|
|||
|
||||
func NewDocument() *Document {
|
||||
return &Document{
|
||||
Footnotes: Footnotes{
|
||||
Footnotes: &Footnotes{
|
||||
ExcludeHeading: true,
|
||||
Title: "Footnotes",
|
||||
Definitions: map[string]FootnoteDefinition{},
|
||||
Definitions: map[string]*FootnoteDefinition{},
|
||||
},
|
||||
MaxEmphasisNewLines: 1,
|
||||
BufferSettings: map[string]string{},
|
||||
|
@ -132,7 +132,7 @@ func (d *Document) parseOne(i int, stop stopFn) (consumed int, node Node) {
|
|||
|
||||
func (d *Document) parseMany(i int, stop stopFn) (int, []Node) {
|
||||
start, nodes := i, []Node{}
|
||||
for i < len(d.tokens) {
|
||||
for i < len(d.tokens) && !stop(d, i) {
|
||||
consumed, node := d.parseOne(i, stop)
|
||||
i += consumed
|
||||
nodes = append(nodes, node)
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
type Footnotes struct {
|
||||
ExcludeHeading bool
|
||||
Title string
|
||||
Definitions map[string]FootnoteDefinition
|
||||
Order []string
|
||||
Definitions map[string]*FootnoteDefinition
|
||||
addOrder []string
|
||||
}
|
||||
|
||||
type FootnoteDefinition struct {
|
||||
|
@ -34,6 +34,29 @@ func (d *Document) parseFootnoteDefinition(i int, parentStop stopFn) (int, Node)
|
|||
d.tokens[i].kind == "headline" || d.tokens[i].kind == "footnoteDefinition"
|
||||
}
|
||||
consumed, nodes := d.parseMany(i, stop)
|
||||
d.Footnotes.Definitions[name] = FootnoteDefinition{name, nodes, false}
|
||||
d.Footnotes.add(name, &FootnoteDefinition{name, nodes, false})
|
||||
return consumed, nil
|
||||
}
|
||||
|
||||
func (fs *Footnotes) add(name string, definition *FootnoteDefinition) {
|
||||
if definition != nil {
|
||||
fs.Definitions[name] = definition
|
||||
}
|
||||
fs.addOrder = append(fs.addOrder, name)
|
||||
}
|
||||
|
||||
func (fs *Footnotes) Ordered() []FootnoteDefinition {
|
||||
m := map[string]bool{}
|
||||
definitions, inlineDefinitions := []FootnoteDefinition{}, []FootnoteDefinition{}
|
||||
for _, name := range fs.addOrder {
|
||||
if isDuplicate := m[name]; !isDuplicate {
|
||||
m[name] = true
|
||||
if definition := *fs.Definitions[name]; definition.Inline {
|
||||
inlineDefinitions = append(inlineDefinitions, definition)
|
||||
} else {
|
||||
definitions = append(definitions, definition)
|
||||
}
|
||||
}
|
||||
}
|
||||
return append(definitions, inlineDefinitions...)
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ var listTags = map[string][]string{
|
|||
func NewHTMLWriter() *HTMLWriter {
|
||||
return &HTMLWriter{
|
||||
HighlightCodeBlock: func(source, lang string) string {
|
||||
return fmt.Sprintf("<pre>%s<pre>", html.EscapeString(source))
|
||||
return fmt.Sprintf("<pre>%s</pre>", html.EscapeString(source))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -154,8 +154,8 @@ func (w *HTMLWriter) writeFootnotes(d *Document) {
|
|||
w.WriteString(`<div id="footnotes">` + "\n")
|
||||
w.WriteString(`<h1 class="footnotes-title">` + fs.Title + `</h1>` + "\n")
|
||||
w.WriteString(`<div class="footnote-definitions">` + "\n")
|
||||
for _, name := range fs.Order {
|
||||
w.writeNodes(fs.Definitions[name])
|
||||
for _, definition := range d.Footnotes.Ordered() {
|
||||
w.writeNodes(definition)
|
||||
}
|
||||
w.WriteString("</div>\n</div>\n")
|
||||
}
|
||||
|
|
|
@ -114,19 +114,11 @@ func (d *Document) parseRegularLinkOrFootnoteReference(input string, start int)
|
|||
func (d *Document) parseFootnoteReference(input string, start int) (int, Node) {
|
||||
if m := footnoteRegexp.FindStringSubmatch(input[start:]); m != nil {
|
||||
name, definition := m[1], m[3]
|
||||
seen, link := false, FootnoteLink{name, nil}
|
||||
for _, otherName := range d.Footnotes.Order {
|
||||
if name == otherName {
|
||||
seen = true
|
||||
}
|
||||
}
|
||||
if !seen {
|
||||
d.Footnotes.Order = append(d.Footnotes.Order, name)
|
||||
}
|
||||
link := FootnoteLink{name, nil}
|
||||
if definition != "" {
|
||||
link.Definition = &FootnoteDefinition{name, d.parseInline(definition), true}
|
||||
d.Footnotes.Definitions[name] = *link.Definition
|
||||
}
|
||||
d.Footnotes.add(name, link.Definition)
|
||||
return len(m[0]), link
|
||||
}
|
||||
return 0, nil
|
||||
|
|
|
@ -145,9 +145,9 @@ func (w *OrgWriter) writeFootnotes(d *Document) {
|
|||
return
|
||||
}
|
||||
w.WriteString("* " + fs.Title + "\n")
|
||||
for _, name := range fs.Order {
|
||||
if fnDefinition := fs.Definitions[name]; !fnDefinition.Inline {
|
||||
w.writeNodes(fnDefinition)
|
||||
for _, definition := range fs.Ordered() {
|
||||
if !definition.Inline {
|
||||
w.writeNodes(definition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
52
org/testdata/example.html
vendored
52
org/testdata/example.html
vendored
|
@ -24,7 +24,7 @@
|
|||
<ol>
|
||||
<li><p>and another subitem</p>
|
||||
<code class="src src-sh">
|
||||
<pre>echo with a block<pre>
|
||||
<pre>echo with a block</pre>
|
||||
</code>
|
||||
</li>
|
||||
<li><p>and another one with a table</p>
|
||||
|
@ -66,12 +66,12 @@
|
|||
</ul>
|
||||
<h2>blocks</h2>
|
||||
<code class="src src-bash">
|
||||
<pre>echo a bash source block<pre>
|
||||
<pre>echo a bash source block</pre>
|
||||
</code>
|
||||
<code class="src src-text">
|
||||
<pre>a source block without a language
|
||||
and a second line
|
||||
and a third one<pre>
|
||||
and a third one</pre>
|
||||
</code>
|
||||
<pre class="example">
|
||||
an example blockwith multiple lines
|
||||
|
@ -90,7 +90,51 @@ Mongodb is very webscale
|
|||
<div class="footnote-definitions">
|
||||
<div class="footnote-definition">
|
||||
<sup id="footnote-1">1</sup>
|
||||
<p>Foobar</p>
|
||||
<p><a href="https://www.example.com">https://www.example.com</a></p>
|
||||
<ul>
|
||||
<li>footnotes can contain <strong>markup</strong></li>
|
||||
<li><p>and other elements</p>
|
||||
<ul>
|
||||
<li><p>like blocks</p>
|
||||
<code class="src src-text">
|
||||
<pre>other non-plain</pre>
|
||||
</code>
|
||||
</li>
|
||||
<li><p>and tables</p>
|
||||
<table><tbody>
|
||||
<tr>
|
||||
<td>1</td><td>a</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>2</td><td>b</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>3</td><td>c</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footnote-definition">
|
||||
<sup id="footnote-3">3</sup>
|
||||
<p><a href="http://example.com/unused-footnote">example.com/unused-footnote</a> </p>
|
||||
</div>
|
||||
<div class="footnote-definition">
|
||||
<sup id="footnote-4">4</sup>
|
||||
<p>another unused footnote </p>
|
||||
</div>
|
||||
<div class="footnote-definition">
|
||||
<sup id="footnote-5">5</sup>
|
||||
<p>another unused footnote </p>
|
||||
</div>
|
||||
<div class="footnote-definition">
|
||||
<sup id="footnote-6">6</sup>
|
||||
<p>another unused footnote</p>
|
||||
</div>
|
||||
<div class="footnote-definition">
|
||||
<sup id="footnote-2">2</sup>
|
||||
|
|
20
org/testdata/example.org
vendored
20
org/testdata/example.org
vendored
|
@ -76,4 +76,22 @@ Mongodb is very webscale
|
|||
- inline footnotes are also supported via [fn:2:the inline footnote definition].
|
||||
|
||||
* Footnotes
|
||||
[fn:1] Foobar
|
||||
[fn:1] https://www.example.com
|
||||
- footnotes can contain *markup*
|
||||
- and other elements
|
||||
- like blocks
|
||||
#+BEGIN_SRC
|
||||
other non-plain
|
||||
#+END_SRC
|
||||
- and tables
|
||||
| 1 | a |
|
||||
| 2 | b |
|
||||
| 3 | c |
|
||||
|
||||
[fn:3] [[http://example.com/unused-footnote][example.com/unused-footnote]]
|
||||
|
||||
[fn:4] another unused footnote
|
||||
|
||||
[fn:5] another unused footnote
|
||||
|
||||
[fn:6] another unused footnote
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue