Restructure directory layout: org subpackage
This commit is contained in:
parent
6c683dfbdb
commit
fc982125c9
17 changed files with 11 additions and 7 deletions
243
org/org.go
Normal file
243
org/org.go
Normal file
|
@ -0,0 +1,243 @@
|
|||
package org
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type stringBuilder = strings.Builder
|
||||
|
||||
type OrgWriter struct {
|
||||
TagsColumn int // see org-tags-column
|
||||
stringBuilder
|
||||
indent string
|
||||
}
|
||||
|
||||
var emphasisOrgBorders = map[string][]string{
|
||||
"_": []string{"_", "_"},
|
||||
"*": []string{"*", "*"},
|
||||
"/": []string{"/", "/"},
|
||||
"+": []string{"+", "+"},
|
||||
"~": []string{"~", "~"},
|
||||
"=": []string{"=", "="},
|
||||
"_{}": []string{"_{", "}"},
|
||||
"^{}": []string{"^{", "}"},
|
||||
}
|
||||
|
||||
func NewOrgWriter() *OrgWriter {
|
||||
return &OrgWriter{
|
||||
TagsColumn: 77,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *OrgWriter) before(d *Document) {}
|
||||
func (w *OrgWriter) after(d *Document) {
|
||||
fs := d.Footnotes
|
||||
if len(fs.Definitions) == 0 {
|
||||
return
|
||||
}
|
||||
w.WriteString("* " + fs.Title + "\n")
|
||||
for _, name := range fs.Order {
|
||||
w.writeNodes(fs.Definitions[name])
|
||||
}
|
||||
}
|
||||
|
||||
func (w *OrgWriter) emptyClone() *OrgWriter {
|
||||
wcopy := *w
|
||||
wcopy.stringBuilder = strings.Builder{}
|
||||
return &wcopy
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeNodes(ns ...Node) {
|
||||
for _, n := range ns {
|
||||
switch n := n.(type) {
|
||||
case Comment:
|
||||
w.writeComment(n)
|
||||
case Keyword:
|
||||
w.writeKeyword(n)
|
||||
case Headline:
|
||||
w.writeHeadline(n)
|
||||
case Block:
|
||||
w.writeBlock(n)
|
||||
|
||||
case FootnoteDefinition:
|
||||
w.writeFootnoteDefinition(n)
|
||||
|
||||
case List:
|
||||
w.writeList(n)
|
||||
case ListItem:
|
||||
w.writeListItem(n)
|
||||
|
||||
case Table:
|
||||
w.writeTable(n)
|
||||
case TableHeader:
|
||||
w.writeTableHeader(n)
|
||||
case TableRow:
|
||||
w.writeTableRow(n)
|
||||
case TableSeparator:
|
||||
w.writeTableSeparator(n)
|
||||
|
||||
case Paragraph:
|
||||
w.writeParagraph(n)
|
||||
case HorizontalRule:
|
||||
w.writeHorizontalRule(n)
|
||||
case Line:
|
||||
w.writeLine(n)
|
||||
|
||||
case Text:
|
||||
w.writeText(n)
|
||||
case Emphasis:
|
||||
w.writeEmphasis(n)
|
||||
case Linebreak:
|
||||
w.writeLinebreak(n)
|
||||
case RegularLink:
|
||||
w.writeRegularLink(n)
|
||||
case FootnoteLink:
|
||||
w.writeFootnoteLink(n)
|
||||
default:
|
||||
if n != nil {
|
||||
panic(fmt.Sprintf("bad node %#v", n))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var eolWhiteSpaceRegexp = regexp.MustCompile("[\t ]*\n")
|
||||
|
||||
func (w *OrgWriter) String() string {
|
||||
s := w.stringBuilder.String()
|
||||
return eolWhiteSpaceRegexp.ReplaceAllString(s, "\n")
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeHeadline(h Headline) {
|
||||
tmp := w.emptyClone()
|
||||
tmp.WriteString(strings.Repeat("*", h.Lvl))
|
||||
if h.Status != "" {
|
||||
tmp.WriteString(" " + h.Status)
|
||||
}
|
||||
if h.Priority != "" {
|
||||
tmp.WriteString(" [#" + h.Priority + "]")
|
||||
}
|
||||
tmp.WriteString(" ")
|
||||
tmp.writeNodes(h.Title...)
|
||||
hString := tmp.String()
|
||||
if len(h.Tags) != 0 {
|
||||
hString += " "
|
||||
tString := ":" + strings.Join(h.Tags, ":") + ":"
|
||||
if n := w.TagsColumn - len(tString) - len(hString); n > 0 {
|
||||
w.WriteString(hString + strings.Repeat(" ", n) + tString)
|
||||
} else {
|
||||
w.WriteString(hString + tString)
|
||||
}
|
||||
} else {
|
||||
w.WriteString(hString)
|
||||
}
|
||||
w.WriteString("\n")
|
||||
if len(h.Children) != 0 {
|
||||
w.WriteString(w.indent)
|
||||
}
|
||||
w.writeNodes(h.Children...)
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeBlock(b Block) {
|
||||
w.WriteString(fmt.Sprintf("%s#+BEGIN_%s %s\n", w.indent, b.Name, strings.Join(b.Parameters, " ")))
|
||||
w.writeNodes(b.Children...)
|
||||
w.WriteString(w.indent + "#+END_" + b.Name + "\n")
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeFootnoteDefinition(f FootnoteDefinition) {
|
||||
w.WriteString(fmt.Sprintf("[fn:%s] ", f.Name))
|
||||
w.writeNodes(f.Children...)
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeParagraph(p Paragraph) {
|
||||
w.writeNodes(p.Children...)
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeKeyword(k Keyword) {
|
||||
w.WriteString(w.indent + fmt.Sprintf("#+%s: %s\n", k.Key, k.Value))
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeComment(c Comment) {
|
||||
w.WriteString(w.indent + "#" + c.Content)
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeList(l List) { w.writeNodes(l.Items...) }
|
||||
|
||||
func (w *OrgWriter) writeListItem(li ListItem) {
|
||||
w.WriteString(w.indent + li.Bullet + " ")
|
||||
liWriter := w.emptyClone()
|
||||
liWriter.indent = w.indent + strings.Repeat(" ", len(li.Bullet)+1)
|
||||
liWriter.writeNodes(li.Children...)
|
||||
w.WriteString(strings.TrimPrefix(liWriter.String(), liWriter.indent))
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeTable(t Table) {
|
||||
// TODO: pretty print tables
|
||||
w.writeNodes(t.Header)
|
||||
w.writeNodes(t.Rows...)
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeTableHeader(th TableHeader) {
|
||||
w.writeTableColumns(th.Columns)
|
||||
w.writeNodes(th.Separator)
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeTableRow(tr TableRow) {
|
||||
w.writeTableColumns(tr.Columns)
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeTableSeparator(ts TableSeparator) {
|
||||
w.WriteString(w.indent + ts.Content + "\n")
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeTableColumns(columns [][]Node) {
|
||||
w.WriteString(w.indent + "| ")
|
||||
for _, columnNodes := range columns {
|
||||
w.writeNodes(columnNodes...)
|
||||
w.WriteString(" | ")
|
||||
}
|
||||
w.WriteString("\n")
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeHorizontalRule(hr HorizontalRule) {
|
||||
w.WriteString(w.indent + "-----\n")
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeLine(l Line) {
|
||||
w.WriteString(w.indent)
|
||||
w.writeNodes(l.Children...)
|
||||
w.WriteString("\n")
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeText(t Text) { w.WriteString(t.Content) }
|
||||
|
||||
func (w *OrgWriter) writeEmphasis(e Emphasis) {
|
||||
borders, ok := emphasisOrgBorders[e.Kind]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("bad emphasis %#v", e))
|
||||
}
|
||||
w.WriteString(borders[0])
|
||||
w.writeNodes(e.Content...)
|
||||
w.WriteString(borders[1])
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeLinebreak(l Linebreak) {
|
||||
w.WriteString(`\\`)
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeFootnoteLink(l FootnoteLink) {
|
||||
w.WriteString("[fn:" + l.Name + "]")
|
||||
}
|
||||
|
||||
func (w *OrgWriter) writeRegularLink(l RegularLink) {
|
||||
descriptionWriter := w.emptyClone()
|
||||
descriptionWriter.writeNodes(l.Description...)
|
||||
description := descriptionWriter.String()
|
||||
if l.URL != description {
|
||||
w.WriteString(fmt.Sprintf("[[%s][%s]]", l.URL, description))
|
||||
} else {
|
||||
w.WriteString(fmt.Sprintf("[[%s]]", l.URL))
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue