From: Thorben Krüger <thorben.krueger@ovgu.de>
---
block.go | 22 ++-
extra.go | 11 ++
inline.go | 12 +-
option.go | 2 +
render.go | 12 +-
render_test.go | 5 +
test_data/renderParagraphLinkCurlyBelow.gmi | 201 ++++++++++++++++++++
7 files changed, 251 insertions(+), 14 deletions(-)
create mode 100644 test_data/renderParagraphLinkCurlyBelow.gmi
diff --git a/block.go b/block.go
index 44e96ef..ff7f01a 100644
--- a/block.go
@@ -22,7 +22,7 @@ func (r *GemRenderer) renderHeading(w util.BufWriter, source []byte, node ast.No
if linkOnly(source, n) {
// In Auto mode, link only headings prints their first link then exit.
for child := n.FirstChild(); child != nil; child = child.NextSibling() {
- if linkPrint(w, source, child, r.config.LinkReplacers) {
+ if linkPrint(w, source, child, r.config.LinkReplacers, "") {
return ast.WalkSkipChildren, nil
}
}
@@ -56,6 +56,7 @@ func (r *GemRenderer) renderHeading(w util.BufWriter, source []byte, node ast.No
}
}
} else {
+
if r.config.HeadingSpace == HeadingSpaceSingle {
fmt.Fprintf(w, "\n")
} else {
@@ -65,7 +66,7 @@ func (r *GemRenderer) renderHeading(w util.BufWriter, source []byte, node ast.No
// Print all links that were in the heading below the heading.
var hasLink bool
for child := n.FirstChild(); child != nil; child = child.NextSibling() {
- if linkPrint(w, source, child, r.config.LinkReplacers) {
+ if linkPrint(w, source, child, r.config.LinkReplacers, "") {
fmt.Fprint(w, "\n")
hasLink = true
}
@@ -212,7 +213,7 @@ func (r *GemRenderer) renderListItem(w util.BufWriter, source []byte, node ast.N
func (r *GemRenderer) renderParagraphLinkOnly(w util.BufWriter, source []byte, n *ast.Paragraph, entering bool) (ast.WalkStatus, error) {
if !entering {
for child := n.FirstChild(); child != nil; child = child.NextSibling() {
- if linkPrint(w, source, child, r.config.LinkReplacers) {
+ if linkPrint(w, source, child, r.config.LinkReplacers, "") {
fmt.Fprintf(w, "\n")
}
}
@@ -242,6 +243,13 @@ func (r *GemRenderer) renderParagraphLinkOff(w util.BufWriter, source []byte, n
// it is printed as a link or list of links itself.
func (r *GemRenderer) renderParagraphLinkBelow(w util.BufWriter, source []byte, n *ast.Paragraph, entering bool) (ast.WalkStatus, error) {
if !entering {
+ var format string
+ if r.config.ParagraphLink == ParagraphLinkCurlyBelow {
+ format = "{%s}"
+ } else {
+ format = ""
+ }
+
// We can make this check inside !entering, because link only
// paragraphs do not contain text. It's a weird quick of goldmark and
// this is the work-around.
@@ -262,7 +270,7 @@ func (r *GemRenderer) renderParagraphLinkBelow(w util.BufWriter, source []byte,
} else {
fmt.Fprintf(w, "\n")
}
- if linkPrint(w, source, nl, r.config.LinkReplacers) {
+ if linkPrint(w, source, nl, r.config.LinkReplacers, format) {
firstLink = false
}
}
@@ -276,11 +284,9 @@ func (r *GemRenderer) renderParagraph(w util.BufWriter, source []byte, node ast.
n := node.(*ast.Paragraph)
switch r.config.ParagraphLink {
case ParagraphLinkOff:
- status, err := r.renderParagraphLinkOff(w, source, n, entering)
- return status, err
+ return r.renderParagraphLinkOff(w, source, n, entering)
default:
- status, err := r.renderParagraphLinkBelow(w, source, n, entering)
- return status, err
+ return r.renderParagraphLinkBelow(w, source, n, entering)
}
}
diff --git a/extra.go b/extra.go
index ce76aca..ce3d2fa 100644
--- a/extra.go
@@ -38,5 +38,16 @@ func (r *GemRenderer) renderWiki(w util.BufWriter, source []byte, node ast.Node,
if linkOnly(source, node.Parent()) {
return ast.WalkSkipChildren, nil
}
+ curly := r.config.ParagraphLink == ParagraphLinkCurlyBelow
+ if entering {
+ if curly {
+ fmt.Fprint(w, "{")
+ }
+ } else {
+ if curly {
+ fmt.Fprint(w, "}")
+ }
+ }
+
return ast.WalkContinue, nil
}
diff --git a/inline.go b/inline.go
index 950067a..ae66fb2 100644
--- a/inline.go
+++ b/inline.go
@@ -82,10 +82,20 @@ func (r *GemRenderer) renderImage(w util.BufWriter, source []byte, node ast.Node
}
func (r *GemRenderer) renderLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
- // skip if the parent node contains only links
if linkOnly(source, node.Parent()) {
return ast.WalkSkipChildren, nil
}
+ curly := r.config.ParagraphLink == ParagraphLinkCurlyBelow && node.Parent().Kind() != ast.KindHeading
+ if entering {
+ if curly {
+ fmt.Fprint(w, "{")
+ }
+ } else {
+ if curly {
+ fmt.Fprint(w, "}")
+ }
+ }
+
return ast.WalkContinue, nil
}
diff --git a/option.go b/option.go
index 9ff116f..e78f68f 100644
--- a/option.go
+++ b/option.go
@@ -109,6 +109,8 @@ const (
ParagraphLinkOff ParagraphLink = iota
// Print links below paragraph.
ParagraphLinkBelow
+ // Delimit link text with curly braces and print the below the paragraph.
+ ParagraphLinkCurlyBelow
)
// Set Emphasis mode.
diff --git a/render.go b/render.go
index 8b6cb4e..1d284ce 100644
--- a/render.go
+++ b/render.go
@@ -102,9 +102,12 @@ func linkOnly(source []byte, node ast.Node) bool {
// linkPrint is a helper function that prints a link's text to a writer, applies
// any regex replacers. Images are not handled by this function as they operate
-// slightly differently.
+// slightly differently. Format can be used to format the link text.
// Returns false if a link was not printed.
-func linkPrint(w io.Writer, source []byte, node ast.Node, replacers []LinkReplacer) bool {
+func linkPrint(w io.Writer, source []byte, node ast.Node, replacers []LinkReplacer, format string) bool {
+ if format == "" {
+ format = "%s"
+ }
// I know the logic is nearly duplicated in *ast.Link and *wast.Wiki, but I
// don't know of a good way to consolidate this. You _can_ match multiple
// types in a type switch, but instead of n being the correct type it will
@@ -124,8 +127,7 @@ func linkPrint(w io.Writer, source []byte, node ast.Node, replacers []LinkReplac
if err != nil {
return false
}
-
- fmt.Fprintf(w, "=> %s %s", destination, text)
+ fmt.Fprintf(w, "=> %s %s", destination, fmt.Sprintf(format, text))
return true
case *wast.Wiki:
// Apply link replacers.
@@ -141,7 +143,7 @@ func linkPrint(w io.Writer, source []byte, node ast.Node, replacers []LinkReplac
return false
}
- fmt.Fprintf(w, "=> %s %s", destination, text)
+ fmt.Fprintf(w, "=> %s %s", destination, fmt.Sprintf(format, text))
return true
case *ast.AutoLink:
// Apply link replacers.
diff --git a/render_test.go b/render_test.go
index 3632c11..185afc2 100644
--- a/render_test.go
+++ b/render_test.go
@@ -44,6 +44,11 @@ func TestNew(t *testing.T) {
"test_data/render.md", "test_data/renderParagraphLinkOff.gmi",
WithParagraphLink(ParagraphLinkOff),
},
+ {
+ "test_data/render.md", "test_data/renderParagraphLinkCurlyBelow.gmi",
+ WithParagraphLink(ParagraphLinkCurlyBelow),
+ },
+
{
"test_data/render.md", "test_data/renderHeadLinkOff.gmi",
WithHeadingLink(HeadingLinkOff),
diff --git a/test_data/renderParagraphLinkCurlyBelow.gmi b/test_data/renderParagraphLinkCurlyBelow.gmi
new file mode 100644
index 0000000..3566132
--- /dev/null
+++ b/test_data/renderParagraphLinkCurlyBelow.gmi
@@ -0,0 +1,201 @@
+# h1 Heading 8-)
+
+## h2 Heading {#test-hd}
+
+### h3 Heading
+
+### h4 Heading
+
+### h5 Heading
+
+### h6 Heading
+
+# Heading with a link
+
+=> https://twitter.com Complete link heading
+
+=> https://autolinkheading.com
+
+# Multi link heading
+
+# Another multi link head
+
+## Horizontal Rules
+
+
+
+
+
+
+
+## HTML Blocks are disabled
+
+## Emphasis
+
+abcmnoxyz
+
+This is bold text
+
+This is bold text
+
+This is italic text
+
+This is italic text
+
+Strikethrough
+
+## Blockquotes
+
+> Blockquotes can also be nested...
+>
+>> ...by using additional greater-than signs right next to each other...
+>>
+>>> ...or with spaces between arrows. {#bl .class}
+
+## Lists
+
+Unordered
+
+* Create a list by starting a line with +, -, or *
+* Sub-lists are made by indenting 2 spaces:
+ * Marker character change forces new list start:
+ * Ac tristique libero volutpat at
+
+ * Facilisis in pretium nisl aliquet
+
+ * Nulla volutpat aliquam velit
+* Very easy!
+
+Ordered
+
+* Lorem ipsum dolor sit amet
+
+* Consectetur adipiscing elit
+
+* Integer molestie lorem at massa
+
+* You can use sequential numbers...
+
+* ...or keep all the numbers as 1.
+
+Start numbering with offset:
+
+* foo
+* bar
+
+## Code
+
+Inline code
+
+Indented code
+
+```
+// Some comments
+line 1 of code
+line 2 of code
+line 3 of code
+```
+
+Block code "fences"
+
+```markdown
+Sample text here...
+```
+
+Syntax highlighting
+
+```js
+var foo = function (bar) {
+ return bar++;
+};
+
+console.log(foo(5));
+```
+
+## Links
+
+=> http://dev.nodeca.com link text
+
+=> http://nodeca.github.io/pica/demo/ link with title
+
+Autoconverted link https://github.com/nodeca/pica in the middle of a paragraph.
+
+=> https://github.com/nodeca/pica
+
+Fabric has an amazing community of {dedicated} and {brilliant} modders who actively embrace and support open source. Many of the other modding platforms of the past {were "ruled with an iron fist" and generally had all the worst parts you see in other gaming communities.} This is the primary reason I switched to fabric, but it also just so happens to have the fastest and fanciest server mods around.
+
+=> https://www.modrinth.com/user/modmuss50 {dedicated}
+=> https://jellysquid.me/projects/ {brilliant}
+=> https://web.archive.org/web/20201125032822/ {were "ruled with an iron fist" and generally had all the worst parts you see in other gaming communities.}
+
+## Wiki link tests
+
+=> kota.nz kota.nz
+
+=> hello.com world
+
+Paragraph {with} a {few} links {in} it.
+
+=> with {with}
+=> few {few}
+=> in {in}
+
+## Linkparagraphs
+
+=> https://selamjie.medium.com/remove-richard-stallman-appendix-a-a7e41e784f88
+=> https://computer.rip/2021-03-24-RMS.html
+
+=> https://github.com/gnembon/fabric-carpet carpet
+=> https://github.com/gnembon/carpet-extra/ carpet-extra
+=> https://github.com/gnembon/carpet-autoCraftingTable carpet-autoCraftingTable
+
+## Images
+
+=> https://octodex.github.com/images/minion.png Minion
+=> https://octodex.github.com/images/stormtroopocat.jpg Stormtroopocat
+
+=> https://octodex.github.com/images/minion.png 1
+=> https://octodex.github.com/images/stormtroopocat.jpg 2
+=> https://octodex.github.com/images/minion.png 3
+
+Like links, Images also have a footnote style syntax
+
+=> https://octodex.github.com/images/dojocat.jpg Alt text
+
+With a reference later in the document defining the URL location:
+
+## Some good ole paragraphs
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eget mi sit amet dui vestibulum dapibus scelerisque vel justo. Proin convallis suscipit nisl ac posuere. Phasellus commodo, leo vel eleifend euismod, nulla odio commodo turpis, quis rhoncus massa eros vitae lectus. Proin pretium laoreet sodales. Praesent vehicula est ante, vel ullamcorper ante fermentum aliquam. In mauris dui, mattis at mi et, viverra mollis justo. Praesent elit nisl, faucibus vitae leo eu, dictum tristique nulla. Cras vel nibh erat. Ut rutrum scelerisque nisi, non sollicitudin purus vehicula ut. Maecenas tincidunt tellus urna. Sed ac ex in felis tincidunt maximus. Fusce vestibulum ex sed dictum tempus. Nunc a rhoncus augue. Nulla at blandit odio. Aliquam semper volutpat arcu, a porttitor sapien scelerisque ut. Duis molestie nibh sem, quis congue justo laoreet at.
+
+In vitae rutrum ligula, vel bibendum sapien. Sed molestie mi at felis finibus pulvinar. Mauris eleifend viverra risus at mattis. Nulla faucibus massa ac posuere facilisis. Nam varius suscipit congue. Aliquam nisl neque, pharetra vel arcu id, auctor dictum eros. Quisque eu interdum dui. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras nec sollicitudin diam, id commodo ex.
+
+## Hard line breaks
+
+What happens to a dream deferred?
+Does it dry up
+like a raisin in the sun?
+Or fester like a sore—
+And then run?
+Does it stink like rotten meat?
+Or crust and sugar over—
+like a syrupy sweet?
+Maybe it just sags
+like a heavy load.
+Or does it explode?
+
+Although she feeds me bread of bitterness,
+And sinks into my throat her tiger’s tooth,
+Stealing my breath of life, I will confess
+I love this cultured hell that tests my youth.
+Her vigor flows like tides into my blood,
+Giving me strength erect against her hate,
+Her bigness sweeps my being like a flood.
+Yet, as a rebel fronts a king in state,
+I stand within her walls with not a shred
+Of terror, malice, not a word of jeer.
+Darkly I gaze into the days ahead,
+And see her might and granite wonders there,
+Beneath the touch of Time’s unerring hand,
+Like priceless treasures sinking in the sand.
+
--
2.34.2