This repository has been archived by the owner on Aug 22, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
generator.go
148 lines (139 loc) · 4.6 KB
/
generator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package mycomarkup
import (
"fmt"
"github.com/bouncepaw/mycomarkup/blocks"
"github.com/bouncepaw/mycomarkup/globals"
"github.com/bouncepaw/mycomarkup/mycocontext"
)
const maxRecursionLevel = 3
func generateHTML(ast []blocks.Block, recursionLevel int, counter *blocks.IDCounter) (html string) {
if recursionLevel > maxRecursionLevel {
return "Transclusion depth limit"
}
for _, line := range ast {
switch v := line.(type) {
case blocks.Quote:
html += fmt.Sprintf(
"\n<blockquote%s>%s\n</blockquote>",
idAttribute(v, counter.UnusableCopy()),
generateHTML(v.Contents(), recursionLevel, counter.UnusableCopy()),
)
case blocks.List:
var ret string
for _, item := range v.Items {
ret += fmt.Sprintf(markerToTemplate(item.Marker), generateHTML(item.Contents, recursionLevel, counter.UnusableCopy()))
}
html += fmt.Sprintf(listToTemplate(v), idAttribute(v, counter), ret)
case blocks.Table:
var ret string
if v.Caption != "" {
ret = fmt.Sprintf("<caption>%s</caption>", v.Caption)
}
ret += "<tbody>\n"
for _, tr := range v.Rows {
ret += "<tr>"
for _, tc := range tr.Cells {
ret += fmt.Sprintf(
"\n\t<%[1]s>%[2]s</%[1]s>",
tc.TagName(),
generateHTML(tc.Contents, recursionLevel, counter.UnusableCopy()),
)
}
ret += "</tr>\n"
}
html += fmt.Sprintf(`
<table%s>%s</tbody></table>`, idAttribute(v, counter), ret)
case blocks.Transclusion:
html += transclusionToHTML(v, recursionLevel, counter.UnusableCopy())
case blocks.Formatted, blocks.Paragraph, blocks.Img, blocks.HorizontalLine, blocks.LaunchPad, blocks.Heading, blocks.CodeBlock:
html += BlockToHTML(v, counter)
default:
html += "<v class='error'>Unknown element.</v>"
}
}
return html
}
func transclusionToHTML(xcl blocks.Transclusion, recursionLevel int, counter *blocks.IDCounter) string {
var (
messageBase = `
<section class="transclusion transclusion_%s">
%s
</section>`
messageCLI = fmt.Sprintf(messageBase, "failed",
`<p>Transclusion is not supported in documents generated using Mycomarkup CLI</p>`)
messageNoTarget = fmt.Sprintf(messageBase, "failed",
`<p>Transclusion target not specified</p>`)
messageOldSyntax = fmt.Sprintf(messageBase, "failed",
`<p>This transclusion is using the old syntax. Please update it to the new one</p>`)
_ = fmt.Sprintf(messageBase, "failed",
`<p>An error occured while transcluding</p>`)
messageNotExists = `<section class="transclusion transclusion_failed">
<p class="error">Cannot transclude hypha <a class="wikilink wikilink_new" href="/hypha/%[1]s">%[1]s</a> because it does not exist</p>
</section>`
messageOK = `<section class="transclusion transclusion_ok%[3]s">
<a class="transclusion__link" href="/hypha/%[1]s">%[1]s</a>
<div class="transclusion__content">%[2]s</div>
</section>`
)
// Nonthing will match if there is no error:
switch xcl.TransclusionError.Reason {
case blocks.TransclusionErrorNotExists:
return fmt.Sprintf(messageNotExists, xcl.Target)
case blocks.TransclusionErrorNoTarget:
return messageNoTarget
case blocks.TransclusionInTerminal:
return messageCLI
case blocks.TransclusionErrorOldSyntax:
return messageOldSyntax
}
// Now, to real transclusion:
rawText, binaryHtml, err := globals.HyphaAccess(xcl.Target)
if err != nil {
return fmt.Sprintf(messageNotExists, xcl.Target)
}
xclVisistor, result := transclusionVisitor(xcl)
ctx, _ := mycocontext.ContextFromStringInput(xcl.Target, rawText) // FIXME: it will bite us one day
_ = BlockTree(ctx, xclVisistor) // TODO: inject transclusion visitors here
xclText := generateHTML(result(), recursionLevel+1, counter.UnusableCopy())
if xcl.Selector == blocks.SelectorAttachment || xcl.Selector == blocks.SelectorFull || xcl.Selector == blocks.SelectorOverview {
xclText = binaryHtml + xclText
}
return fmt.Sprintf(
messageOK,
xcl.Target,
xclText,
func() string {
if xcl.Blend {
return " transclusion_blend"
}
return " transclusion_stand-out"
}(),
)
}
func listToTemplate(list blocks.List) string {
switch list.Marker {
case blocks.MarkerOrdered:
return `
<ol%s>%s</ol>`
default:
return `
<ul%s>%s</ul>`
}
}
func markerToTemplate(m blocks.ListMarker) string {
switch m {
case blocks.MarkerUnordered:
return `
<li class="item_unordered">%s</li>`
case blocks.MarkerOrdered:
return `
<li class="item_ordered">%s</li>`
case blocks.MarkerTodoDone:
return `
<li class="item_todo item_todo-done"><input type="checkbox" disabled checked>%s</li>`
case blocks.MarkerTodo:
return `
<li class="item_todo"><input type="checkbox" disabled>%s</li>`
}
panic("unreachable")
}