Improve footnote handling
- Footnotes separator rather than headline to get around i18n - Warn on footnote redefinition - Do not export footnote definitions at point of definition, only in the footnote section. - Do not automatically exclude Footnotes section to get around possibly hiding other content of such a section - and i18n. The user has the choice of explicitly hiding the section via a :noexport: tag. and some other refactoring
This commit is contained in:
parent
beff0c0d8a
commit
eb7db9b968
11 changed files with 114 additions and 60 deletions
|
@ -1,6 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
for org_file in org/testdata/*.org; do
|
for org_file in org/testdata/*.org; do
|
||||||
|
echo $org_file
|
||||||
./go-org $org_file html > org/testdata/$(basename $org_file .org).html
|
./go-org $org_file html > org/testdata/$(basename $org_file .org).html
|
||||||
./go-org $org_file org > org/testdata/$(basename $org_file .org).pretty_org
|
./go-org $org_file org > org/testdata/$(basename $org_file .org).pretty_org
|
||||||
done
|
done
|
||||||
|
|
|
@ -14,7 +14,7 @@ type Document struct {
|
||||||
Path string
|
Path string
|
||||||
tokens []token
|
tokens []token
|
||||||
Nodes []Node
|
Nodes []Node
|
||||||
Footnotes *Footnotes
|
Footnotes Footnotes
|
||||||
StatusKeywords []string
|
StatusKeywords []string
|
||||||
MaxEmphasisNewLines int
|
MaxEmphasisNewLines int
|
||||||
AutoLink bool
|
AutoLink bool
|
||||||
|
@ -72,7 +72,7 @@ func FrontMatterHandler(fm FrontMatter, k, v string) error {
|
||||||
|
|
||||||
func NewDocument() *Document {
|
func NewDocument() *Document {
|
||||||
return &Document{
|
return &Document{
|
||||||
Footnotes: &Footnotes{
|
Footnotes: Footnotes{
|
||||||
Title: "Footnotes",
|
Title: "Footnotes",
|
||||||
Definitions: map[string]*FootnoteDefinition{},
|
Definitions: map[string]*FootnoteDefinition{},
|
||||||
},
|
},
|
||||||
|
@ -222,6 +222,16 @@ func (d *Document) parseMany(i int, stop stopFn) (int, []Node) {
|
||||||
return i - start, nodes
|
return i - start, nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Document) addFootnote(name string, definition *FootnoteDefinition) {
|
||||||
|
if definition != nil {
|
||||||
|
if _, exists := d.Footnotes.Definitions[name]; exists {
|
||||||
|
d.Log.Printf("Footnote [fn:%s] redefined! %#v", name, definition)
|
||||||
|
}
|
||||||
|
d.Footnotes.Definitions[name] = definition
|
||||||
|
}
|
||||||
|
d.Footnotes.addOrder = append(d.Footnotes.addOrder, name)
|
||||||
|
}
|
||||||
|
|
||||||
func tokenize(line string) token {
|
func tokenize(line string) token {
|
||||||
for _, lexFn := range lexFns {
|
for _, lexFn := range lexFns {
|
||||||
if token, ok := lexFn(line); ok {
|
if token, ok := lexFn(line); ok {
|
||||||
|
|
|
@ -35,17 +35,10 @@ func (d *Document) parseFootnoteDefinition(i int, parentStop stopFn) (int, Node)
|
||||||
}
|
}
|
||||||
consumed, nodes := d.parseMany(i, stop)
|
consumed, nodes := d.parseMany(i, stop)
|
||||||
definition := FootnoteDefinition{name, nodes, false}
|
definition := FootnoteDefinition{name, nodes, false}
|
||||||
d.Footnotes.add(name, &definition)
|
d.addFootnote(name, &definition)
|
||||||
return consumed, definition
|
return consumed, definition
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
func (fs *Footnotes) Ordered() []FootnoteDefinition {
|
||||||
m := map[string]bool{}
|
m := map[string]bool{}
|
||||||
definitions, inlineDefinitions := []FootnoteDefinition{}, []FootnoteDefinition{}
|
definitions, inlineDefinitions := []FootnoteDefinition{}, []FootnoteDefinition{}
|
||||||
|
|
29
org/html.go
29
org/html.go
|
@ -13,11 +13,10 @@ import (
|
||||||
|
|
||||||
type HTMLWriter struct {
|
type HTMLWriter struct {
|
||||||
stringBuilder
|
stringBuilder
|
||||||
HighlightCodeBlock func(source, lang string) string
|
HighlightCodeBlock func(source, lang string) string
|
||||||
FootnotesHeadingTitle string
|
htmlEscape bool
|
||||||
htmlEscape bool
|
excludeTags []string
|
||||||
excludeTags []string
|
log *log.Logger
|
||||||
log *log.Logger
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var emphasisTags = map[string][]string{
|
var emphasisTags = map[string][]string{
|
||||||
|
@ -45,8 +44,7 @@ var listItemStatuses = map[string]string{
|
||||||
|
|
||||||
func NewHTMLWriter() *HTMLWriter {
|
func NewHTMLWriter() *HTMLWriter {
|
||||||
return &HTMLWriter{
|
return &HTMLWriter{
|
||||||
htmlEscape: true,
|
htmlEscape: true,
|
||||||
FootnotesHeadingTitle: "Footnotes",
|
|
||||||
HighlightCodeBlock: func(source, lang string) string {
|
HighlightCodeBlock: func(source, lang string) string {
|
||||||
return fmt.Sprintf("%s\n<pre>\n%s\n</pre>\n</div>", `<div class="highlight">`, html.EscapeString(source))
|
return fmt.Sprintf("%s\n<pre>\n%s\n</pre>\n</div>", `<div class="highlight">`, html.EscapeString(source))
|
||||||
},
|
},
|
||||||
|
@ -95,7 +93,7 @@ func (w *HTMLWriter) writeNodes(ns ...Node) {
|
||||||
continue
|
continue
|
||||||
|
|
||||||
case FootnoteDefinition:
|
case FootnoteDefinition:
|
||||||
w.writeFootnoteDefinition(n)
|
continue
|
||||||
|
|
||||||
case List:
|
case List:
|
||||||
w.writeList(n)
|
w.writeList(n)
|
||||||
|
@ -191,24 +189,19 @@ func (w *HTMLWriter) writeFootnoteDefinition(f FootnoteDefinition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *HTMLWriter) writeFootnotes(d *Document) {
|
func (w *HTMLWriter) writeFootnotes(d *Document) {
|
||||||
fs := d.Footnotes
|
if len(d.Footnotes.Definitions) == 0 {
|
||||||
if len(fs.Definitions) == 0 {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteString(`<div class="footnotes">` + "\n")
|
w.WriteString(`<div class="footnotes">` + "\n")
|
||||||
w.WriteString(`<h1 class="footnotes-title">` + fs.Title + `</h1>` + "\n")
|
w.WriteString(`<hr class="footnotes-separatator">` + "\n")
|
||||||
w.WriteString(`<div class="footnote-definitions">` + "\n")
|
w.WriteString(`<div class="footnote-definitions">` + "\n")
|
||||||
for _, definition := range d.Footnotes.Ordered() {
|
for _, definition := range d.Footnotes.Ordered() {
|
||||||
w.writeNodes(definition)
|
w.writeFootnoteDefinition(definition)
|
||||||
}
|
}
|
||||||
w.WriteString("</div>\n</div>\n")
|
w.WriteString("</div>\n</div>\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *HTMLWriter) writeHeadline(h Headline) {
|
func (w *HTMLWriter) writeHeadline(h Headline) {
|
||||||
title := w.nodesAsString(h.Title...)
|
|
||||||
if h.Lvl == 1 && title == w.FootnotesHeadingTitle {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, excludeTag := range w.excludeTags {
|
for _, excludeTag := range w.excludeTags {
|
||||||
for _, tag := range h.Tags {
|
for _, tag := range h.Tags {
|
||||||
if excludeTag == tag {
|
if excludeTag == tag {
|
||||||
|
@ -230,7 +223,7 @@ func (w *HTMLWriter) writeHeadline(h Headline) {
|
||||||
w.WriteString(fmt.Sprintf(`<span class="priority">[%s]</span>`, h.Priority) + "\n")
|
w.WriteString(fmt.Sprintf(`<span class="priority">[%s]</span>`, h.Priority) + "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteString(title)
|
w.writeNodes(h.Title...)
|
||||||
if len(h.Tags) != 0 {
|
if len(h.Tags) != 0 {
|
||||||
tags := make([]string, len(h.Tags))
|
tags := make([]string, len(h.Tags))
|
||||||
for i, tag := range h.Tags {
|
for i, tag := range h.Tags {
|
||||||
|
@ -337,7 +330,7 @@ func (w *HTMLWriter) writeDescriptiveListItem(di DescriptiveListItem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *HTMLWriter) writeParagraph(p Paragraph) {
|
func (w *HTMLWriter) writeParagraph(p Paragraph) {
|
||||||
if isEmptyLineParagraph(p) {
|
if len(p.Children) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteString("<p>")
|
w.WriteString("<p>")
|
||||||
|
|
|
@ -157,7 +157,7 @@ func (d *Document) parseFootnoteReference(input string, start int) (int, Node) {
|
||||||
link := FootnoteLink{name, nil}
|
link := FootnoteLink{name, nil}
|
||||||
if definition != "" {
|
if definition != "" {
|
||||||
link.Definition = &FootnoteDefinition{name, []Node{Paragraph{d.parseInline(definition)}}, true}
|
link.Definition = &FootnoteDefinition{name, []Node{Paragraph{d.parseInline(definition)}}, true}
|
||||||
d.Footnotes.add(name, link.Definition)
|
d.addFootnote(name, link.Definition)
|
||||||
}
|
}
|
||||||
return len(m[0]), link
|
return len(m[0]), link
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -175,10 +176,11 @@ func (w *OrgWriter) writePropertyDrawer(d PropertyDrawer) {
|
||||||
|
|
||||||
func (w *OrgWriter) writeFootnoteDefinition(f FootnoteDefinition) {
|
func (w *OrgWriter) writeFootnoteDefinition(f FootnoteDefinition) {
|
||||||
w.WriteString(fmt.Sprintf("[fn:%s]", f.Name))
|
w.WriteString(fmt.Sprintf("[fn:%s]", f.Name))
|
||||||
if !(len(f.Children) >= 1 && isEmptyLineParagraph(f.Children[0])) {
|
content := w.nodesAsString(f.Children...)
|
||||||
|
if content != "" && !unicode.IsSpace(rune(content[0])) {
|
||||||
w.WriteString(" ")
|
w.WriteString(" ")
|
||||||
}
|
}
|
||||||
w.writeNodes(f.Children...)
|
w.WriteString(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OrgWriter) writeParagraph(p Paragraph) {
|
func (w *OrgWriter) writeParagraph(p Paragraph) {
|
||||||
|
|
59
org/testdata/footnotes.html
vendored
59
org/testdata/footnotes.html
vendored
|
@ -17,11 +17,43 @@ further references to the same footnote should not <sup class="footnote-referenc
|
||||||
inline footnotes are also supported via <sup class="footnote-reference"><a id="footnote-reference-2" href="#footnote-2">2</a></sup>.
|
inline footnotes are also supported via <sup class="footnote-reference"><a id="footnote-reference-2" href="#footnote-2">2</a></sup>.
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>
|
||||||
|
Footnote definitions are not printed where they appear.
|
||||||
|
Rather, they are gathered and exported at the end of the document in the footnote section. <sup class="footnote-reference"><a id="footnote-reference-4" href="#footnote-4">4</a></sup>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<h1>
|
||||||
|
Footnotes
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
Please note that the footnotes section is not automatically excluded from the export like in emacs. <sup class="footnote-reference"><a id="footnote-reference-7" href="#footnote-7">7</a></sup>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
this is not part of <sup class="footnote-reference"><a id="footnote-reference-7" href="#footnote-7">7</a></sup> anymore as there are 2 blank lines in between!
|
||||||
|
</p>
|
||||||
<div class="footnotes">
|
<div class="footnotes">
|
||||||
<h1 class="footnotes-title">Footnotes</h1>
|
<hr class="footnotes-separatator">
|
||||||
<div class="footnote-definitions">
|
<div class="footnote-definitions">
|
||||||
<div class="footnote-definition">
|
<div class="footnote-definition">
|
||||||
|
<sup id="footnote-4"><a href="#footnote-reference-4">4</a></sup>
|
||||||
|
<div class="footnote-body">
|
||||||
|
<p>
|
||||||
|
so this definition will not be at the end of this section in the exported document.
|
||||||
|
Rather, it will be somewhere down below in the footnotes section.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footnote-definition">
|
||||||
|
<sup id="footnote-5"><a href="#footnote-reference-5">5</a></sup>
|
||||||
|
<div class="footnote-body">
|
||||||
|
<p>
|
||||||
|
another unused footnote (this definition overwrites the previous definition of <code class="verbatim">fn:5</code>)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footnote-definition">
|
||||||
<sup id="footnote-1"><a href="#footnote-reference-1">1</a></sup>
|
<sup id="footnote-1"><a href="#footnote-reference-1">1</a></sup>
|
||||||
<div class="footnote-body">
|
<div class="footnote-body">
|
||||||
<p>
|
<p>
|
||||||
|
@ -83,22 +115,6 @@ and tables
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footnote-definition">
|
<div class="footnote-definition">
|
||||||
<sup id="footnote-4"><a href="#footnote-reference-4">4</a></sup>
|
|
||||||
<div class="footnote-body">
|
|
||||||
<p>
|
|
||||||
another unused footnote
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="footnote-definition">
|
|
||||||
<sup id="footnote-5"><a href="#footnote-reference-5">5</a></sup>
|
|
||||||
<div class="footnote-body">
|
|
||||||
<p>
|
|
||||||
another unused footnote
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="footnote-definition">
|
|
||||||
<sup id="footnote-6"><a href="#footnote-reference-6">6</a></sup>
|
<sup id="footnote-6"><a href="#footnote-reference-6">6</a></sup>
|
||||||
<div class="footnote-body">
|
<div class="footnote-body">
|
||||||
<p>
|
<p>
|
||||||
|
@ -108,6 +124,15 @@ This shouldn't happen when the definition line and the line after that are e
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footnote-definition">
|
<div class="footnote-definition">
|
||||||
|
<sup id="footnote-7"><a href="#footnote-reference-7">7</a></sup>
|
||||||
|
<div class="footnote-body">
|
||||||
|
<p>
|
||||||
|
There's multiple reasons for that. Among others, doing so requires i18n (to recognize the section) and silently
|
||||||
|
hides content before and after the footnotes.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footnote-definition">
|
||||||
<sup id="footnote-2"><a href="#footnote-reference-2">2</a></sup>
|
<sup id="footnote-2"><a href="#footnote-reference-2">2</a></sup>
|
||||||
<div class="footnote-body">
|
<div class="footnote-body">
|
||||||
<p>
|
<p>
|
||||||
|
|
22
org/testdata/footnotes.org
vendored
22
org/testdata/footnotes.org
vendored
|
@ -2,8 +2,17 @@
|
||||||
- normal footnote reference [fn:1] [fn:6]
|
- normal footnote reference [fn:1] [fn:6]
|
||||||
- further references to the same footnote should not [fn:1] render duplicates in the footnote list
|
- further references to the same footnote should not [fn:1] render duplicates in the footnote list
|
||||||
- inline footnotes are also supported via [fn:2:the inline footnote definition].
|
- inline footnotes are also supported via [fn:2:the inline footnote definition].
|
||||||
|
- Footnote definitions are not printed where they appear.
|
||||||
|
Rather, they are gathered and exported at the end of the document in the footnote section. [fn:4]
|
||||||
|
|
||||||
|
[fn:4] so this definition will not be at the end of this section in the exported document.
|
||||||
|
Rather, it will be somewhere down below in the footnotes section.
|
||||||
|
|
||||||
|
[fn:5] this definition will also not be exported here - not only that, it will be overwritten by a definition
|
||||||
|
of the same name later on in the document. That will log a warning but carry on nonetheless.
|
||||||
* Footnotes
|
* Footnotes
|
||||||
|
Please note that the footnotes section is not automatically excluded from the export like in emacs. [fn:7]
|
||||||
|
|
||||||
[fn:1] https://www.example.com
|
[fn:1] https://www.example.com
|
||||||
- footnotes can contain *markup*
|
- footnotes can contain *markup*
|
||||||
- and other elements
|
- and other elements
|
||||||
|
@ -18,11 +27,18 @@
|
||||||
|
|
||||||
[fn:3] [[http://example.com/unused-footnote][example.com/unused-footnote]]
|
[fn:3] [[http://example.com/unused-footnote][example.com/unused-footnote]]
|
||||||
|
|
||||||
[fn:4] another unused footnote
|
[fn:5] another unused footnote (this definition overwrites the previous definition of =fn:5=)
|
||||||
|
|
||||||
[fn:5] another unused footnote
|
|
||||||
|
|
||||||
[fn:6]
|
[fn:6]
|
||||||
|
|
||||||
Footnotes break after two consecutive empty lines - just like paragraphs - see https://orgmode.org/worg/dev/org-syntax.html.
|
Footnotes break after two consecutive empty lines - just like paragraphs - see https://orgmode.org/worg/dev/org-syntax.html.
|
||||||
This shouldn't happen when the definition line and the line after that are empty.
|
This shouldn't happen when the definition line and the line after that are empty.
|
||||||
|
|
||||||
|
|
||||||
|
[fn:7]
|
||||||
|
There's multiple reasons for that. Among others, doing so requires i18n (to recognize the section) and silently
|
||||||
|
hides content before and after the footnotes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this is not part of [fn:7] anymore as there are 2 blank lines in between!
|
||||||
|
|
22
org/testdata/footnotes.pretty_org
vendored
22
org/testdata/footnotes.pretty_org
vendored
|
@ -2,8 +2,17 @@
|
||||||
- normal footnote reference [fn:1] [fn:6]
|
- normal footnote reference [fn:1] [fn:6]
|
||||||
- further references to the same footnote should not [fn:1] render duplicates in the footnote list
|
- further references to the same footnote should not [fn:1] render duplicates in the footnote list
|
||||||
- inline footnotes are also supported via [fn:2:the inline footnote definition].
|
- inline footnotes are also supported via [fn:2:the inline footnote definition].
|
||||||
|
- Footnote definitions are not printed where they appear.
|
||||||
|
Rather, they are gathered and exported at the end of the document in the footnote section. [fn:4]
|
||||||
|
|
||||||
|
[fn:4] so this definition will not be at the end of this section in the exported document.
|
||||||
|
Rather, it will be somewhere down below in the footnotes section.
|
||||||
|
|
||||||
|
[fn:5] this definition will also not be exported here - not only that, it will be overwritten by a definition
|
||||||
|
of the same name later on in the document. That will log a warning but carry on nonetheless.
|
||||||
* Footnotes
|
* Footnotes
|
||||||
|
Please note that the footnotes section is not automatically excluded from the export like in emacs. [fn:7]
|
||||||
|
|
||||||
[fn:1] https://www.example.com
|
[fn:1] https://www.example.com
|
||||||
- footnotes can contain *markup*
|
- footnotes can contain *markup*
|
||||||
- and other elements
|
- and other elements
|
||||||
|
@ -18,11 +27,18 @@
|
||||||
|
|
||||||
[fn:3] [[http://example.com/unused-footnote][example.com/unused-footnote]]
|
[fn:3] [[http://example.com/unused-footnote][example.com/unused-footnote]]
|
||||||
|
|
||||||
[fn:4] another unused footnote
|
[fn:5] another unused footnote (this definition overwrites the previous definition of =fn:5=)
|
||||||
|
|
||||||
[fn:5] another unused footnote
|
|
||||||
|
|
||||||
[fn:6]
|
[fn:6]
|
||||||
|
|
||||||
Footnotes break after two consecutive empty lines - just like paragraphs - see https://orgmode.org/worg/dev/org-syntax.html.
|
Footnotes break after two consecutive empty lines - just like paragraphs - see https://orgmode.org/worg/dev/org-syntax.html.
|
||||||
This shouldn't happen when the definition line and the line after that are empty.
|
This shouldn't happen when the definition line and the line after that are empty.
|
||||||
|
|
||||||
|
|
||||||
|
[fn:7]
|
||||||
|
There's multiple reasons for that. Among others, doing so requires i18n (to recognize the section) and silently
|
||||||
|
hides content before and after the footnotes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this is not part of [fn:7] anymore as there are 2 blank lines in between!
|
||||||
|
|
5
org/testdata/misc.html
vendored
5
org/testdata/misc.html
vendored
|
@ -359,8 +359,11 @@ When inserting an image link like <img src="/home/amos/Pictures/Screenshots/img-
|
||||||
(ansi-term))
|
(ansi-term))
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
<h1>
|
||||||
|
Footnotes
|
||||||
|
</h1>
|
||||||
<div class="footnotes">
|
<div class="footnotes">
|
||||||
<h1 class="footnotes-title">Footnotes</h1>
|
<hr class="footnotes-separatator">
|
||||||
<div class="footnote-definitions">
|
<div class="footnote-definitions">
|
||||||
<div class="footnote-definition">
|
<div class="footnote-definition">
|
||||||
<sup id="footnote-1"><a href="#footnote-reference-1">1</a></sup>
|
<sup id="footnote-1"><a href="#footnote-reference-1">1</a></sup>
|
||||||
|
|
|
@ -11,11 +11,6 @@ func isSecondBlankLine(d *Document, i int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func isEmptyLineParagraph(n Node) bool {
|
|
||||||
p, ok := n.(Paragraph)
|
|
||||||
return ok && len(p.Children) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func isImageOrVideoLink(n Node) bool {
|
func isImageOrVideoLink(n Node) bool {
|
||||||
if l, ok := n.(RegularLink); ok && l.Kind() == "video" || l.Kind() == "image" {
|
if l, ok := n.(RegularLink); ok && l.Kind() == "video" || l.Kind() == "image" {
|
||||||
return true
|
return true
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue