refactor roff rendering
This commit is contained in:
parent
4c0d034620
commit
a6332946e5
271
runoff.go
271
runoff.go
@ -7,91 +7,46 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func trim(s string) string {
|
|
||||||
return strings.TrimFunc(
|
|
||||||
s,
|
|
||||||
func(r rune) bool { return r != '\u00a0' && unicode.IsSpace(r) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func textToString(t Txt) string {
|
|
||||||
if len(t.cat) == 0 && t.link == "" {
|
|
||||||
return trim(t.text)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(t.cat) == 0 && t.text == "" {
|
|
||||||
return trim(t.link)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(t.cat) == 0 {
|
|
||||||
return fmt.Sprintf("%s (%s)", t.text, t.link)
|
|
||||||
}
|
|
||||||
|
|
||||||
b := bytes.NewBuffer(nil)
|
|
||||||
for i := range t.cat {
|
|
||||||
if i > 0 {
|
|
||||||
b.WriteRune(' ')
|
|
||||||
}
|
|
||||||
|
|
||||||
b.WriteString(textToString(t.cat[i]))
|
|
||||||
}
|
|
||||||
|
|
||||||
return editString(b.String(), singleLine())
|
|
||||||
}
|
|
||||||
|
|
||||||
func manPageDate(d time.Time) string {
|
func manPageDate(d time.Time) string {
|
||||||
return fmt.Sprintf("%v %d", d.Month(), d.Year())
|
return fmt.Sprintf("%v %d", d.Month(), d.Year())
|
||||||
}
|
}
|
||||||
|
|
||||||
func roffString(s string, additionalEscape ...string) string {
|
func roffTextToString(t Txt) string {
|
||||||
s = editString(s, singleLine())
|
var b bytes.Buffer
|
||||||
return editString(s, escapeRoff(additionalEscape...))
|
renderRoffText(&b, t)
|
||||||
}
|
return b.String()
|
||||||
|
|
||||||
func renderRoffString(w writer, s string, additionalEscape ...string) {
|
|
||||||
s = roffString(s, additionalEscape...)
|
|
||||||
w.write(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func roffDefinitionNames(d []DefinitionItem) []string {
|
func roffDefinitionNames(d []DefinitionItem) []string {
|
||||||
var n []string
|
var n []string
|
||||||
for _, di := range d {
|
for _, di := range d {
|
||||||
n = append(n, textToString(di.name))
|
n = append(n, roffTextToString(di.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func roffCellTexts(r []TableRow) ([][]string, error) {
|
func roffCellTexts(r []TableRow) [][]string {
|
||||||
var cellTexts [][]string
|
var cellTexts [][]string
|
||||||
for _, row := range r {
|
for _, row := range r {
|
||||||
var c []string
|
var c []string
|
||||||
for _, cell := range row.cells {
|
for _, cell := range row.cells {
|
||||||
var b bytes.Buffer
|
c = append(c, roffTextToString(cell.text))
|
||||||
w := newRoffWriter(&b, true)
|
|
||||||
renderRoffText(w, cell.text)
|
|
||||||
w.flush()
|
|
||||||
if w.err != nil {
|
|
||||||
return nil, w.err
|
|
||||||
}
|
|
||||||
|
|
||||||
c = append(c, b.String())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cellTexts = append(cellTexts, c)
|
cellTexts = append(cellTexts, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cellTexts, nil
|
return cellTexts
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffText(w writer, text Txt, additionalEscape ...string) {
|
func renderRoffText(w io.Writer, text Txt, additionalEscape ...string) {
|
||||||
if len(text.cat) > 0 {
|
if len(text.cat) > 0 {
|
||||||
for i, tc := range text.cat {
|
for i, tc := range text.cat {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
w.write(" ")
|
write(w, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
renderRoffText(w, tc)
|
renderRoffText(w, tc)
|
||||||
@ -101,34 +56,38 @@ func renderRoffText(w writer, text Txt, additionalEscape ...string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if text.bold {
|
if text.bold {
|
||||||
w.write("\\fB")
|
write(w, "\\fB")
|
||||||
}
|
}
|
||||||
|
|
||||||
if text.italic {
|
if text.italic {
|
||||||
w.write("\\fI")
|
write(w, "\\fI")
|
||||||
}
|
}
|
||||||
|
|
||||||
if text.bold || text.italic {
|
if text.bold || text.italic {
|
||||||
defer w.write("\\fR")
|
defer write(w, "\\fR")
|
||||||
}
|
}
|
||||||
|
|
||||||
if text.link != "" {
|
w, f := writeWith(w, singleLine(), escapeRoff(additionalEscape...))
|
||||||
if text.text != "" {
|
if text.link == "" {
|
||||||
renderRoffString(w, text.text, additionalEscape...)
|
write(w, text.text)
|
||||||
w.write(" (")
|
f()
|
||||||
renderRoffString(w, text.link, additionalEscape...)
|
|
||||||
w.write(")")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
renderRoffString(w, text.link, additionalEscape...)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
renderRoffString(w, text.text, additionalEscape...)
|
if text.text == "" {
|
||||||
|
write(w, text.link)
|
||||||
|
f()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
write(w, text.text)
|
||||||
|
write(w, " (")
|
||||||
|
write(w, text.link)
|
||||||
|
write(w, ")")
|
||||||
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffTitle(w writer, e Entry) {
|
func renderRoffTitle(w io.Writer, e Entry) {
|
||||||
if e.titleLevel != 0 || e.man.section == 0 {
|
if e.titleLevel != 0 || e.man.section == 0 {
|
||||||
e.text.bold = true
|
e.text.bold = true
|
||||||
p := Entry{
|
p := Entry{
|
||||||
@ -142,86 +101,92 @@ func renderRoffTitle(w writer, e Entry) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.write(".TH \"")
|
write(w, ".TH \"")
|
||||||
renderRoffText(w, e.text, "\"", "\\(dq")
|
renderRoffText(w, e.text, "\"", "\\(dq")
|
||||||
w.write("\" ")
|
write(w, "\" ")
|
||||||
renderRoffString(w, fmt.Sprint(e.man.section), "\"", "\\(dq")
|
w, f := writeWith(w, singleLine(), escapeRoff("\"", "\\(dq"))
|
||||||
w.write(" \"")
|
write(w, fmt.Sprint(e.man.section))
|
||||||
|
w, _ = f()
|
||||||
|
write(w, " \"")
|
||||||
if !e.man.date.IsZero() {
|
if !e.man.date.IsZero() {
|
||||||
w.write(manPageDate(e.man.date))
|
write(w, manPageDate(e.man.date))
|
||||||
}
|
}
|
||||||
|
|
||||||
w.write("\" \"")
|
write(w, "\" \"")
|
||||||
renderRoffString(w, e.man.version, "\"", "\\(dq")
|
w, f = writeWith(w, singleLine(), escapeRoff("\"", "\\(dq"))
|
||||||
w.write("\" \"")
|
write(w, e.man.version)
|
||||||
renderRoffString(w, e.man.category, "\"", "\\(dq")
|
w, _ = f()
|
||||||
w.write("\"")
|
write(w, "\" \"")
|
||||||
|
w, f = writeWith(w, singleLine(), escapeRoff("\"", "\\(dq"))
|
||||||
|
write(w, e.man.category)
|
||||||
|
w, _ = f()
|
||||||
|
write(w, "\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffParagraph(w writer, e Entry) {
|
func renderRoffParagraph(w io.Writer, e Entry) {
|
||||||
w.write(".in ", e.indent, "\n.ti ", e.indent+e.indentFirst, "\n")
|
write(w, ".in ", e.indent, "\n.ti ", e.indent+e.indentFirst, "\n")
|
||||||
renderRoffText(w, e.text)
|
renderRoffText(w, e.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffList(w writer, e Entry) {
|
func renderRoffList(w io.Writer, e Entry) {
|
||||||
for i, item := range e.items {
|
for i, item := range e.items {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
w.write("\n.br\n")
|
write(w, "\n.br\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.write(".in ", e.indent+2, "\n.ti ", e.indent+e.indentFirst, "\n")
|
write(w, ".in ", e.indent+2, "\n.ti ", e.indent+e.indentFirst, "\n")
|
||||||
w.write("\\(bu ")
|
write(w, "\\(bu ")
|
||||||
renderRoffText(w, item.text)
|
renderRoffText(w, item.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffNumberedList(w writer, e Entry) {
|
func renderRoffNumberedList(w io.Writer, e Entry) {
|
||||||
maxDigits := numDigits(len(e.items))
|
maxDigits := numDigits(len(e.items))
|
||||||
for i, item := range e.items {
|
for i, item := range e.items {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
w.write("\n.br\n")
|
write(w, "\n.br\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.write(".in ", e.indent+maxDigits+2, "\n.ti ", e.indent+e.indentFirst, "\n")
|
write(w, ".in ", e.indent+maxDigits+2, "\n.ti ", e.indent+e.indentFirst, "\n")
|
||||||
w.write(padRight(fmt.Sprintf("%d.", i+1), maxDigits+2))
|
write(w, padRight(fmt.Sprintf("%d.", i+1), maxDigits+2))
|
||||||
renderRoffText(w, item.text)
|
renderRoffText(w, item.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffDefinitions(w writer, e Entry) {
|
func renderRoffDefinitions(w io.Writer, e Entry) {
|
||||||
names := roffDefinitionNames(e.definitions)
|
names := roffDefinitionNames(e.definitions)
|
||||||
maxNameLength := maxLength(names)
|
maxNameLength := maxLength(names)
|
||||||
for i, definition := range e.definitions {
|
for i, definition := range e.definitions {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
w.write("\n.br\n")
|
write(w, "\n.br\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.write(".in ", e.indent+maxNameLength+4, "\n.ti ", e.indent+e.indentFirst, "\n")
|
write(w, ".in ", e.indent+maxNameLength+4, "\n.ti ", e.indent+e.indentFirst, "\n")
|
||||||
w.write("\\(bu ")
|
write(w, "\\(bu ")
|
||||||
renderRoffText(w, definition.name)
|
renderRoffText(w, definition.name)
|
||||||
w.write(":", timesn("\\~", maxNameLength-len([]rune(names[i]))+1))
|
write(w, ":", timesn("\\~", maxNameLength-len([]rune(names[i]))+1))
|
||||||
renderRoffText(w, definition.value)
|
renderRoffText(w, definition.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffNumberedDefinitions(w writer, e Entry) {
|
func renderRoffNumberedDefinitions(w io.Writer, e Entry) {
|
||||||
maxDigits := numDigits(len(e.definitions))
|
maxDigits := numDigits(len(e.definitions))
|
||||||
names := roffDefinitionNames(e.definitions)
|
names := roffDefinitionNames(e.definitions)
|
||||||
maxNameLength := maxLength(names)
|
maxNameLength := maxLength(names)
|
||||||
for i, definition := range e.definitions {
|
for i, definition := range e.definitions {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
w.write("\n.br\n")
|
write(w, "\n.br\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.write(".in ", e.indent+maxDigits+maxNameLength+4, "\n.ti ", e.indent+e.indentFirst, "\n")
|
write(w, ".in ", e.indent+maxDigits+maxNameLength+4, "\n.ti ", e.indent+e.indentFirst, "\n")
|
||||||
w.write(padRight(fmt.Sprintf("%d.", i+1), maxDigits+2))
|
write(w, padRight(fmt.Sprintf("%d.", i+1), maxDigits+2))
|
||||||
renderRoffText(w, definition.name)
|
renderRoffText(w, definition.name)
|
||||||
w.write(":", timesn("\\~", maxNameLength-len([]rune(names[i]))+1))
|
write(w, ":", timesn("\\~", maxNameLength-len([]rune(names[i]))+1))
|
||||||
renderRoffText(w, definition.value)
|
renderRoffText(w, definition.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffTable(w writer, e Entry) {
|
func renderRoffTable(w io.Writer, e Entry) {
|
||||||
if len(e.rows) == 0 {
|
if len(e.rows) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -231,14 +196,10 @@ func renderRoffTable(w writer, e Entry) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.write(".nf\n")
|
write(w, ".nf\n")
|
||||||
defer w.write("\n.fi")
|
defer write(w, "\n.fi")
|
||||||
|
|
||||||
cellTexts, err := roffCellTexts(e.rows)
|
|
||||||
if err != nil {
|
|
||||||
w.setErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
cellTexts := roffCellTexts(e.rows)
|
||||||
totalSeparatorWidth := (len(cellTexts[0]) - 1) * 3
|
totalSeparatorWidth := (len(cellTexts[0]) - 1) * 3
|
||||||
if e.wrapWidth > 0 {
|
if e.wrapWidth > 0 {
|
||||||
allocatedWidth := e.wrapWidth - e.indent - totalSeparatorWidth
|
allocatedWidth := e.wrapWidth - e.indent - totalSeparatorWidth
|
||||||
@ -257,6 +218,7 @@ func renderRoffTable(w writer, e Entry) {
|
|||||||
totalWidth += columnWidths[i]
|
totalWidth += columnWidths[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w, f := writeWith(w, indent(e.indent, e.indent))
|
||||||
hasHeader := e.rows[0].header
|
hasHeader := e.rows[0].header
|
||||||
for i := range cellTexts {
|
for i := range cellTexts {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
@ -265,9 +227,9 @@ func renderRoffTable(w writer, e Entry) {
|
|||||||
sep = "="
|
sep = "="
|
||||||
}
|
}
|
||||||
|
|
||||||
w.write("\n")
|
write(w, "\n")
|
||||||
w.write(timesn(" ", e.indent), timesn(sep, totalWidth))
|
write(w, timesn(sep, totalWidth))
|
||||||
w.write("\n")
|
write(w, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
lines := make([][]string, len(cellTexts[i]))
|
lines := make([][]string, len(cellTexts[i]))
|
||||||
@ -284,14 +246,12 @@ func renderRoffTable(w writer, e Entry) {
|
|||||||
|
|
||||||
for k := 0; k < maxLines; k++ {
|
for k := 0; k < maxLines; k++ {
|
||||||
if k > 0 {
|
if k > 0 {
|
||||||
w.write("\n")
|
write(w, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
for j := range lines {
|
for j := range lines {
|
||||||
if j == 0 {
|
if j > 0 {
|
||||||
w.write(timesn(" ", e.indent))
|
write(w, " | ")
|
||||||
} else {
|
|
||||||
w.write(" | ")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var l string
|
var l string
|
||||||
@ -299,57 +259,59 @@ func renderRoffTable(w writer, e Entry) {
|
|||||||
l = lines[j][k]
|
l = lines[j][k]
|
||||||
}
|
}
|
||||||
|
|
||||||
w.write(padRight(l, columnWidths[j]))
|
write(w, padRight(l, columnWidths[j]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasHeader && len(cellTexts) == 1 {
|
if hasHeader && len(cellTexts) == 1 {
|
||||||
w.write("\n", timesn("=", totalWidth))
|
write(w, "\n", timesn("=", totalWidth))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffCode(w writer, e Entry) {
|
func renderRoffCode(w io.Writer, e Entry) {
|
||||||
w.write(".nf\n")
|
write(w, ".nf\n")
|
||||||
defer w.write("\n.fi")
|
defer write(w, "\n.fi")
|
||||||
txt := editString(e.text.text, escapeRoff())
|
w, f := writeWith(w, escapeRoff(), indent(e.indent, e.indent))
|
||||||
txt = editString(txt, indent(e.indent, e.indent))
|
write(w, e.text.text)
|
||||||
w.write(txt)
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffMultiple(w writer, s SyntaxItem) {
|
func renderRoffMultiple(w io.Writer, s SyntaxItem) {
|
||||||
s.topLevel = false
|
s.topLevel = false
|
||||||
s.multiple = false
|
s.multiple = false
|
||||||
renderRoffSyntaxItem(w, s)
|
renderRoffSyntaxItem(w, s)
|
||||||
w.write("...")
|
write(w, "...")
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffRequired(w writer, s SyntaxItem) {
|
func renderRoffRequired(w io.Writer, s SyntaxItem) {
|
||||||
s.delimited = true
|
s.delimited = true
|
||||||
s.topLevel = false
|
s.topLevel = false
|
||||||
s.required = false
|
s.required = false
|
||||||
w.write("<")
|
write(w, "<")
|
||||||
renderRoffSyntaxItem(w, s)
|
renderRoffSyntaxItem(w, s)
|
||||||
w.write(">")
|
write(w, ">")
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffOptional(w writer, s SyntaxItem) {
|
func renderRoffOptional(w io.Writer, s SyntaxItem) {
|
||||||
s.delimited = true
|
s.delimited = true
|
||||||
s.topLevel = false
|
s.topLevel = false
|
||||||
s.optional = false
|
s.optional = false
|
||||||
w.write("[")
|
write(w, "[")
|
||||||
renderRoffSyntaxItem(w, s)
|
renderRoffSyntaxItem(w, s)
|
||||||
w.write("]")
|
write(w, "]")
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffSequence(w writer, s SyntaxItem) {
|
func renderRoffSequence(w io.Writer, s SyntaxItem) {
|
||||||
if !s.delimited && !s.topLevel {
|
if !s.delimited && !s.topLevel {
|
||||||
w.write("(")
|
write(w, "(")
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, item := range s.sequence {
|
for i, item := range s.sequence {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
w.write(" ")
|
write(w, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
item.delimited = false
|
item.delimited = false
|
||||||
@ -357,13 +319,13 @@ func renderRoffSequence(w writer, s SyntaxItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !s.delimited && !s.topLevel {
|
if !s.delimited && !s.topLevel {
|
||||||
w.write(")")
|
write(w, ")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffChoice(w writer, s SyntaxItem) {
|
func renderRoffChoice(w io.Writer, s SyntaxItem) {
|
||||||
if !s.delimited && !s.topLevel {
|
if !s.delimited && !s.topLevel {
|
||||||
w.write("(")
|
write(w, "(")
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, item := range s.choice {
|
for i, item := range s.choice {
|
||||||
@ -373,7 +335,7 @@ func renderRoffChoice(w writer, s SyntaxItem) {
|
|||||||
separator = "\n"
|
separator = "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
w.write(separator)
|
write(w, separator)
|
||||||
}
|
}
|
||||||
|
|
||||||
item.delimited = false
|
item.delimited = false
|
||||||
@ -381,15 +343,15 @@ func renderRoffChoice(w writer, s SyntaxItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !s.delimited && !s.topLevel {
|
if !s.delimited && !s.topLevel {
|
||||||
w.write(")")
|
write(w, ")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffSymbol(w writer, s SyntaxItem) {
|
func renderRoffSymbol(w io.Writer, s SyntaxItem) {
|
||||||
w.write(editString(s.symbol, escapeRoff()))
|
write(w, s.symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffSyntaxItem(w writer, s SyntaxItem) {
|
func renderRoffSyntaxItem(w io.Writer, s SyntaxItem) {
|
||||||
switch {
|
switch {
|
||||||
|
|
||||||
// foo...
|
// foo...
|
||||||
@ -418,24 +380,21 @@ func renderRoffSyntaxItem(w writer, s SyntaxItem) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoffSyntax(w writer, e Entry) {
|
func renderRoffSyntax(w io.Writer, e Entry) {
|
||||||
s := e.syntax
|
s := e.syntax
|
||||||
s.topLevel = true
|
s.topLevel = true
|
||||||
w.write(".nf\n")
|
write(w, ".nf\n")
|
||||||
defer w.write("\n.fi")
|
defer write(w, "\n.fi")
|
||||||
w.write(timesn("\u00a0", e.indent))
|
w, f := writeWith(w, escapeRoff(), indent(e.indent, e.indent))
|
||||||
renderRoffSyntaxItem(w, s)
|
renderRoffSyntaxItem(w, s)
|
||||||
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderRoff(out io.Writer, d Document) error {
|
func renderRoff(out io.Writer, d Document) error {
|
||||||
w := newRoffWriter(out, false)
|
w, f := writeWith(out, roffNBSP(), errorHandler)
|
||||||
for i, e := range d.entries {
|
for i, e := range d.entries {
|
||||||
if err := w.error(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
w.write("\n.br\n.sp 1v\n")
|
write(w, "\n.br\n.sp 1v\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch e.typ {
|
switch e.typ {
|
||||||
@ -463,9 +422,9 @@ func renderRoff(out io.Writer, d Document) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(d.entries) > 0 {
|
if len(d.entries) > 0 {
|
||||||
w.write("\n")
|
write(w, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.flush()
|
_, err := f()
|
||||||
return w.err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -127,7 +127,7 @@ Below you can find some test text, with various text items.
|
|||||||
.br
|
.br
|
||||||
.sp 1v
|
.sp 1v
|
||||||
.nf
|
.nf
|
||||||
\~\~\~\~\~\~\~\~textfmt.Doc ( [Entry]... )
|
textfmt.Doc ( [Entry]... )
|
||||||
.fi
|
.fi
|
||||||
.br
|
.br
|
||||||
.sp 1v
|
.sp 1v
|
||||||
@ -329,7 +329,7 @@ Below you can find some test text, with various text items.
|
|||||||
.br
|
.br
|
||||||
.sp 1v
|
.sp 1v
|
||||||
.nf
|
.nf
|
||||||
\~\~\~\~\~\~\~\~textfmt.Doc ( [Entry]... )
|
textfmt.Doc ( [Entry]... )
|
||||||
.fi
|
.fi
|
||||||
.br
|
.br
|
||||||
.sp 1v
|
.sp 1v
|
||||||
@ -2292,7 +2292,7 @@ and silver birch\~\~\~\~ | their canopies creating\~ | and shadow on the
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.String() != ".nf\n\\~\\~\\~\\~foo [options]... <filename> [string|number]...\n.fi\n" {
|
if b.String() != ".nf\n foo [options]... <filename> [string|number]...\n.fi\n" {
|
||||||
t.Fatal(b.String())
|
t.Fatal(b.String())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -149,8 +149,7 @@ func ttyCellTexts(rows []TableRow) [][]string {
|
|||||||
for _, row := range rows {
|
for _, row := range rows {
|
||||||
var c []string
|
var c []string
|
||||||
for _, cell := range row.cells {
|
for _, cell := range row.cells {
|
||||||
txt := ttyTextToString(cell.text)
|
c = append(c, ttyTextToString(cell.text))
|
||||||
c = append(c, txt)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cellTexts = append(cellTexts, c)
|
cellTexts = append(cellTexts, c)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user