Implement inline source blocks

https://orgmode.org/manual/Structure-of-Code-Blocks.html
This commit is contained in:
Niklas Fasching 2020-04-16 14:28:40 +02:00
parent 6ed46ba95d
commit 3018ace8d0
8 changed files with 83 additions and 21 deletions

View file

@ -16,7 +16,7 @@ import (
// HTMLWriter exports an org document into a html document.
type HTMLWriter struct {
ExtendingWriter Writer
HighlightCodeBlock func(source, lang string) string
HighlightCodeBlock func(source, lang string, inline bool) string
strings.Builder
document *Document
@ -61,7 +61,10 @@ func NewHTMLWriter() *HTMLWriter {
document: &Document{Configuration: defaultConfig},
log: defaultConfig.Log,
htmlEscape: true,
HighlightCodeBlock: func(source, lang string) string {
HighlightCodeBlock: func(source, lang string, inline bool) string {
if inline {
return fmt.Sprintf("<div class=\"highlight-inline\">\n<pre>\n%s\n</pre>\n</div>", html.EscapeString(source))
}
return fmt.Sprintf("<div class=\"highlight\">\n<pre>\n%s\n</pre>\n</div>", html.EscapeString(source))
},
footnotes: &footnotes{
@ -103,24 +106,14 @@ func (w *HTMLWriter) WriteComment(Comment) {}
func (w *HTMLWriter) WritePropertyDrawer(PropertyDrawer) {}
func (w *HTMLWriter) WriteBlock(b Block) {
content := ""
if isRawTextBlock(b.Name) {
builder, htmlEscape := w.Builder, w.htmlEscape
w.Builder, w.htmlEscape = strings.Builder{}, false
WriteNodes(w, b.Children...)
out := w.String()
w.Builder, w.htmlEscape = builder, htmlEscape
content = strings.TrimRightFunc(out, unicode.IsSpace)
} else {
content = w.WriteNodesAsString(b.Children...)
}
content := w.blockContent(b.Name, b.Children)
switch name := b.Name; {
case name == "SRC":
lang := "text"
if len(b.Parameters) >= 1 {
lang = strings.ToLower(b.Parameters[0])
}
content = w.HighlightCodeBlock(content, lang)
content = w.HighlightCodeBlock(content, lang, false)
w.WriteString(fmt.Sprintf("<div class=\"src src-%s\">\n%s\n</div>\n", lang, content))
case name == "EXAMPLE":
w.WriteString(`<pre class="example">` + "\n" + html.EscapeString(content) + "\n</pre>\n")
@ -139,6 +132,12 @@ func (w *HTMLWriter) WriteBlock(b Block) {
}
}
func (w *HTMLWriter) WriteInlineBlock(b InlineBlock) {
content := w.blockContent(b.Name, b.Children)
lang := strings.ToLower(b.Parameters[0])
w.WriteString(fmt.Sprintf("<div class=\"src src-inline src-%s\">\n%s\n</div>", lang, content))
}
func (w *HTMLWriter) WriteDrawer(d Drawer) {
WriteNodes(w, d.Children...)
}
@ -483,6 +482,19 @@ func (w *HTMLWriter) withHTMLAttributes(input string, kvs ...string) string {
return out.String()
}
func (w *HTMLWriter) blockContent(name string, children []Node) string {
if isRawTextBlock(name) {
builder, htmlEscape := w.Builder, w.htmlEscape
w.Builder, w.htmlEscape = strings.Builder{}, false
WriteNodes(w, children...)
out := w.String()
w.Builder, w.htmlEscape = builder, htmlEscape
return strings.TrimRightFunc(out, unicode.IsSpace)
} else {
return w.WriteNodesAsString(children...)
}
}
func setHTMLAttribute(attributes []h.Attribute, k, v string) []h.Attribute {
for i, a := range attributes {
if strings.ToLower(a.Key) == strings.ToLower(k) {