update urfave/cli v1.22.1, go-md2man v2.0.0, blackfriday v2.0.1
This updates urfave/cli and its dependencies to v1.22.1: - diff for urfave/cli: https://github.com/urfave/cli/compare/v1.22.0...v1.22.1 - diff for go-md2man: https://github.com/cpuguy83/go-md2man/compare/v1.0.10...v2.0.0 - diff for blackfriday: https://github.com/russross/blackfriday/compare/v1.5.2...v2.0.1 Also adds github.com/shurcooL/sanitized_anchor_name as a new dependency, which is used by russross/blackfriday, but will be removed again in a future update (dependency is already removed on the v2 branch through russross/blackfriday@919b1f5b9b Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
21
vendor/github.com/cpuguy83/go-md2man/README.md
generated
vendored
21
vendor/github.com/cpuguy83/go-md2man/README.md
generated
vendored
@@ -1,21 +0,0 @@
|
||||
go-md2man
|
||||
=========
|
||||
|
||||
** Work in Progress **
|
||||
This still needs a lot of help to be complete, or even usable!
|
||||
|
||||
Uses blackfriday to process markdown into man pages.
|
||||
|
||||
### Usage
|
||||
|
||||
./md2man -in /path/to/markdownfile.md -out /manfile/output/path
|
||||
|
||||
### How to contribute
|
||||
|
||||
We use [dep](https://github.com/golang/dep/) for vendoring Go packages.
|
||||
See dep documentation for how to update.
|
||||
|
||||
### TODO
|
||||
|
||||
- Needs oh so much testing love
|
||||
- Look into blackfriday's 2.0 API
|
||||
5
vendor/github.com/cpuguy83/go-md2man/go.mod
generated
vendored
5
vendor/github.com/cpuguy83/go-md2man/go.mod
generated
vendored
@@ -1,5 +0,0 @@
|
||||
module github.com/cpuguy83/go-md2man
|
||||
|
||||
go 1.12
|
||||
|
||||
require github.com/russross/blackfriday v1.5.2
|
||||
20
vendor/github.com/cpuguy83/go-md2man/md2man/md2man.go
generated
vendored
20
vendor/github.com/cpuguy83/go-md2man/md2man/md2man.go
generated
vendored
@@ -1,20 +0,0 @@
|
||||
package md2man
|
||||
|
||||
import (
|
||||
"github.com/russross/blackfriday"
|
||||
)
|
||||
|
||||
// Render converts a markdown document into a roff formatted document.
|
||||
func Render(doc []byte) []byte {
|
||||
renderer := RoffRenderer(0)
|
||||
extensions := 0
|
||||
extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS
|
||||
extensions |= blackfriday.EXTENSION_TABLES
|
||||
extensions |= blackfriday.EXTENSION_FENCED_CODE
|
||||
extensions |= blackfriday.EXTENSION_AUTOLINK
|
||||
extensions |= blackfriday.EXTENSION_SPACE_HEADERS
|
||||
extensions |= blackfriday.EXTENSION_FOOTNOTES
|
||||
extensions |= blackfriday.EXTENSION_TITLEBLOCK
|
||||
|
||||
return blackfriday.Markdown(doc, renderer, extensions)
|
||||
}
|
||||
285
vendor/github.com/cpuguy83/go-md2man/md2man/roff.go
generated
vendored
285
vendor/github.com/cpuguy83/go-md2man/md2man/roff.go
generated
vendored
@@ -1,285 +0,0 @@
|
||||
package md2man
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html"
|
||||
"strings"
|
||||
|
||||
"github.com/russross/blackfriday"
|
||||
)
|
||||
|
||||
type roffRenderer struct {
|
||||
ListCounters []int
|
||||
}
|
||||
|
||||
// RoffRenderer creates a new blackfriday Renderer for generating roff documents
|
||||
// from markdown
|
||||
func RoffRenderer(flags int) blackfriday.Renderer {
|
||||
return &roffRenderer{}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) GetFlags() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (r *roffRenderer) TitleBlock(out *bytes.Buffer, text []byte) {
|
||||
out.WriteString(".TH ")
|
||||
|
||||
splitText := bytes.Split(text, []byte("\n"))
|
||||
for i, line := range splitText {
|
||||
line = bytes.TrimPrefix(line, []byte("% "))
|
||||
if i == 0 {
|
||||
line = bytes.Replace(line, []byte("("), []byte("\" \""), 1)
|
||||
line = bytes.Replace(line, []byte(")"), []byte("\" \""), 1)
|
||||
}
|
||||
line = append([]byte("\""), line...)
|
||||
line = append(line, []byte("\" ")...)
|
||||
out.Write(line)
|
||||
}
|
||||
out.WriteString("\n")
|
||||
|
||||
// disable hyphenation
|
||||
out.WriteString(".nh\n")
|
||||
// disable justification (adjust text to left margin only)
|
||||
out.WriteString(".ad l\n")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) {
|
||||
out.WriteString("\n.PP\n.RS\n\n.nf\n")
|
||||
escapeSpecialChars(out, text)
|
||||
out.WriteString("\n.fi\n.RE\n")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) BlockQuote(out *bytes.Buffer, text []byte) {
|
||||
out.WriteString("\n.PP\n.RS\n")
|
||||
out.Write(text)
|
||||
out.WriteString("\n.RE\n")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) BlockHtml(out *bytes.Buffer, text []byte) { // nolint: golint
|
||||
out.Write(text)
|
||||
}
|
||||
|
||||
func (r *roffRenderer) Header(out *bytes.Buffer, text func() bool, level int, id string) {
|
||||
marker := out.Len()
|
||||
|
||||
switch {
|
||||
case marker == 0:
|
||||
// This is the doc header
|
||||
out.WriteString(".TH ")
|
||||
case level == 1:
|
||||
out.WriteString("\n\n.SH ")
|
||||
case level == 2:
|
||||
out.WriteString("\n.SH ")
|
||||
default:
|
||||
out.WriteString("\n.SS ")
|
||||
}
|
||||
|
||||
if !text() {
|
||||
out.Truncate(marker)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) HRule(out *bytes.Buffer) {
|
||||
out.WriteString("\n.ti 0\n\\l'\\n(.lu'\n")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) List(out *bytes.Buffer, text func() bool, flags int) {
|
||||
marker := out.Len()
|
||||
r.ListCounters = append(r.ListCounters, 1)
|
||||
out.WriteString("\n.RS\n")
|
||||
if !text() {
|
||||
out.Truncate(marker)
|
||||
return
|
||||
}
|
||||
r.ListCounters = r.ListCounters[:len(r.ListCounters)-1]
|
||||
out.WriteString("\n.RE\n")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
|
||||
if flags&blackfriday.LIST_TYPE_ORDERED != 0 {
|
||||
out.WriteString(fmt.Sprintf(".IP \"%3d.\" 5\n", r.ListCounters[len(r.ListCounters)-1]))
|
||||
r.ListCounters[len(r.ListCounters)-1]++
|
||||
} else {
|
||||
out.WriteString(".IP \\(bu 2\n")
|
||||
}
|
||||
out.Write(text)
|
||||
out.WriteString("\n")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) Paragraph(out *bytes.Buffer, text func() bool) {
|
||||
marker := out.Len()
|
||||
out.WriteString("\n.PP\n")
|
||||
if !text() {
|
||||
out.Truncate(marker)
|
||||
return
|
||||
}
|
||||
if marker != 0 {
|
||||
out.WriteString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {
|
||||
out.WriteString("\n.TS\nallbox;\n")
|
||||
|
||||
maxDelims := 0
|
||||
lines := strings.Split(strings.TrimRight(string(header), "\n")+"\n"+strings.TrimRight(string(body), "\n"), "\n")
|
||||
for _, w := range lines {
|
||||
curDelims := strings.Count(w, "\t")
|
||||
if curDelims > maxDelims {
|
||||
maxDelims = curDelims
|
||||
}
|
||||
}
|
||||
out.Write([]byte(strings.Repeat("l ", maxDelims+1) + "\n"))
|
||||
out.Write([]byte(strings.Repeat("l ", maxDelims+1) + ".\n"))
|
||||
out.Write(header)
|
||||
if len(header) > 0 {
|
||||
out.Write([]byte("\n"))
|
||||
}
|
||||
|
||||
out.Write(body)
|
||||
out.WriteString("\n.TE\n")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) TableRow(out *bytes.Buffer, text []byte) {
|
||||
if out.Len() > 0 {
|
||||
out.WriteString("\n")
|
||||
}
|
||||
out.Write(text)
|
||||
}
|
||||
|
||||
func (r *roffRenderer) TableHeaderCell(out *bytes.Buffer, text []byte, align int) {
|
||||
if out.Len() > 0 {
|
||||
out.WriteString("\t")
|
||||
}
|
||||
if len(text) == 0 {
|
||||
text = []byte{' '}
|
||||
}
|
||||
out.Write([]byte("\\fB\\fC" + string(text) + "\\fR"))
|
||||
}
|
||||
|
||||
func (r *roffRenderer) TableCell(out *bytes.Buffer, text []byte, align int) {
|
||||
if out.Len() > 0 {
|
||||
out.WriteString("\t")
|
||||
}
|
||||
if len(text) > 30 {
|
||||
text = append([]byte("T{\n"), text...)
|
||||
text = append(text, []byte("\nT}")...)
|
||||
}
|
||||
if len(text) == 0 {
|
||||
text = []byte{' '}
|
||||
}
|
||||
out.Write(text)
|
||||
}
|
||||
|
||||
func (r *roffRenderer) Footnotes(out *bytes.Buffer, text func() bool) {
|
||||
|
||||
}
|
||||
|
||||
func (r *roffRenderer) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) {
|
||||
|
||||
}
|
||||
|
||||
func (r *roffRenderer) AutoLink(out *bytes.Buffer, link []byte, kind int) {
|
||||
out.WriteString("\n\\[la]")
|
||||
out.Write(link)
|
||||
out.WriteString("\\[ra]")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) CodeSpan(out *bytes.Buffer, text []byte) {
|
||||
out.WriteString("\\fB\\fC")
|
||||
escapeSpecialChars(out, text)
|
||||
out.WriteString("\\fR")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) DoubleEmphasis(out *bytes.Buffer, text []byte) {
|
||||
out.WriteString("\\fB")
|
||||
out.Write(text)
|
||||
out.WriteString("\\fP")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) Emphasis(out *bytes.Buffer, text []byte) {
|
||||
out.WriteString("\\fI")
|
||||
out.Write(text)
|
||||
out.WriteString("\\fP")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
|
||||
}
|
||||
|
||||
func (r *roffRenderer) LineBreak(out *bytes.Buffer) {
|
||||
out.WriteString("\n.br\n")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
|
||||
out.Write(content)
|
||||
r.AutoLink(out, link, 0)
|
||||
}
|
||||
|
||||
func (r *roffRenderer) RawHtmlTag(out *bytes.Buffer, tag []byte) { // nolint: golint
|
||||
out.Write(tag)
|
||||
}
|
||||
|
||||
func (r *roffRenderer) TripleEmphasis(out *bytes.Buffer, text []byte) {
|
||||
out.WriteString("\\s+2")
|
||||
out.Write(text)
|
||||
out.WriteString("\\s-2")
|
||||
}
|
||||
|
||||
func (r *roffRenderer) StrikeThrough(out *bytes.Buffer, text []byte) {
|
||||
}
|
||||
|
||||
func (r *roffRenderer) FootnoteRef(out *bytes.Buffer, ref []byte, id int) {
|
||||
|
||||
}
|
||||
|
||||
func (r *roffRenderer) Entity(out *bytes.Buffer, entity []byte) {
|
||||
out.WriteString(html.UnescapeString(string(entity)))
|
||||
}
|
||||
|
||||
func (r *roffRenderer) NormalText(out *bytes.Buffer, text []byte) {
|
||||
escapeSpecialChars(out, text)
|
||||
}
|
||||
|
||||
func (r *roffRenderer) DocumentHeader(out *bytes.Buffer) {
|
||||
}
|
||||
|
||||
func (r *roffRenderer) DocumentFooter(out *bytes.Buffer) {
|
||||
}
|
||||
|
||||
func needsBackslash(c byte) bool {
|
||||
for _, r := range []byte("-_&\\~") {
|
||||
if c == r {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func escapeSpecialChars(out *bytes.Buffer, text []byte) {
|
||||
for i := 0; i < len(text); i++ {
|
||||
// escape initial apostrophe or period
|
||||
if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') {
|
||||
out.WriteString("\\&")
|
||||
}
|
||||
|
||||
// directly copy normal characters
|
||||
org := i
|
||||
|
||||
for i < len(text) && !needsBackslash(text[i]) {
|
||||
i++
|
||||
}
|
||||
if i > org {
|
||||
out.Write(text[org:i])
|
||||
}
|
||||
|
||||
// escape a character
|
||||
if i >= len(text) {
|
||||
break
|
||||
}
|
||||
out.WriteByte('\\')
|
||||
out.WriteByte(text[i])
|
||||
}
|
||||
}
|
||||
15
vendor/github.com/cpuguy83/go-md2man/v2/README.md
generated
vendored
Normal file
15
vendor/github.com/cpuguy83/go-md2man/v2/README.md
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
go-md2man
|
||||
=========
|
||||
|
||||
Converts markdown into roff (man pages).
|
||||
|
||||
Uses blackfriday to process markdown into man pages.
|
||||
|
||||
### Usage
|
||||
|
||||
./md2man -in /path/to/markdownfile.md -out /manfile/output/path
|
||||
|
||||
### How to contribute
|
||||
|
||||
We use go modules to manage dependencies.
|
||||
As such you must be using at lest go1.11.
|
||||
9
vendor/github.com/cpuguy83/go-md2man/v2/go.mod
generated
vendored
Normal file
9
vendor/github.com/cpuguy83/go-md2man/v2/go.mod
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
module github.com/cpuguy83/go-md2man/v2
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
)
|
||||
14
vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
generated
vendored
Normal file
14
vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
package md2man
|
||||
|
||||
import (
|
||||
"github.com/russross/blackfriday/v2"
|
||||
)
|
||||
|
||||
// Render converts a markdown document into a roff formatted document.
|
||||
func Render(doc []byte) []byte {
|
||||
renderer := NewRoffRenderer()
|
||||
|
||||
return blackfriday.Run(doc,
|
||||
[]blackfriday.Option{blackfriday.WithRenderer(renderer),
|
||||
blackfriday.WithExtensions(renderer.GetExtensions())}...)
|
||||
}
|
||||
345
vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
generated
vendored
Normal file
345
vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
generated
vendored
Normal file
@@ -0,0 +1,345 @@
|
||||
package md2man
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/russross/blackfriday/v2"
|
||||
)
|
||||
|
||||
// roffRenderer implements the blackfriday.Renderer interface for creating
|
||||
// roff format (manpages) from markdown text
|
||||
type roffRenderer struct {
|
||||
extensions blackfriday.Extensions
|
||||
listCounters []int
|
||||
firstHeader bool
|
||||
defineTerm bool
|
||||
listDepth int
|
||||
}
|
||||
|
||||
const (
|
||||
titleHeader = ".TH "
|
||||
topLevelHeader = "\n\n.SH "
|
||||
secondLevelHdr = "\n.SH "
|
||||
otherHeader = "\n.SS "
|
||||
crTag = "\n"
|
||||
emphTag = "\\fI"
|
||||
emphCloseTag = "\\fP"
|
||||
strongTag = "\\fB"
|
||||
strongCloseTag = "\\fP"
|
||||
breakTag = "\n.br\n"
|
||||
paraTag = "\n.PP\n"
|
||||
hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n"
|
||||
linkTag = "\n\\[la]"
|
||||
linkCloseTag = "\\[ra]"
|
||||
codespanTag = "\\fB\\fC"
|
||||
codespanCloseTag = "\\fR"
|
||||
codeTag = "\n.PP\n.RS\n\n.nf\n"
|
||||
codeCloseTag = "\n.fi\n.RE\n"
|
||||
quoteTag = "\n.PP\n.RS\n"
|
||||
quoteCloseTag = "\n.RE\n"
|
||||
listTag = "\n.RS\n"
|
||||
listCloseTag = "\n.RE\n"
|
||||
arglistTag = "\n.TP\n"
|
||||
tableStart = "\n.TS\nallbox;\n"
|
||||
tableEnd = ".TE\n"
|
||||
tableCellStart = "T{\n"
|
||||
tableCellEnd = "\nT}\n"
|
||||
)
|
||||
|
||||
// NewRoffRenderer creates a new blackfriday Renderer for generating roff documents
|
||||
// from markdown
|
||||
func NewRoffRenderer() *roffRenderer { // nolint: golint
|
||||
var extensions blackfriday.Extensions
|
||||
|
||||
extensions |= blackfriday.NoIntraEmphasis
|
||||
extensions |= blackfriday.Tables
|
||||
extensions |= blackfriday.FencedCode
|
||||
extensions |= blackfriday.SpaceHeadings
|
||||
extensions |= blackfriday.Footnotes
|
||||
extensions |= blackfriday.Titleblock
|
||||
extensions |= blackfriday.DefinitionLists
|
||||
return &roffRenderer{
|
||||
extensions: extensions,
|
||||
}
|
||||
}
|
||||
|
||||
// GetExtensions returns the list of extensions used by this renderer implementation
|
||||
func (r *roffRenderer) GetExtensions() blackfriday.Extensions {
|
||||
return r.extensions
|
||||
}
|
||||
|
||||
// RenderHeader handles outputting the header at document start
|
||||
func (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) {
|
||||
// disable hyphenation
|
||||
out(w, ".nh\n")
|
||||
}
|
||||
|
||||
// RenderFooter handles outputting the footer at the document end; the roff
|
||||
// renderer has no footer information
|
||||
func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) {
|
||||
}
|
||||
|
||||
// RenderNode is called for each node in a markdown document; based on the node
|
||||
// type the equivalent roff output is sent to the writer
|
||||
func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
|
||||
|
||||
var walkAction = blackfriday.GoToNext
|
||||
|
||||
switch node.Type {
|
||||
case blackfriday.Text:
|
||||
r.handleText(w, node, entering)
|
||||
case blackfriday.Softbreak:
|
||||
out(w, crTag)
|
||||
case blackfriday.Hardbreak:
|
||||
out(w, breakTag)
|
||||
case blackfriday.Emph:
|
||||
if entering {
|
||||
out(w, emphTag)
|
||||
} else {
|
||||
out(w, emphCloseTag)
|
||||
}
|
||||
case blackfriday.Strong:
|
||||
if entering {
|
||||
out(w, strongTag)
|
||||
} else {
|
||||
out(w, strongCloseTag)
|
||||
}
|
||||
case blackfriday.Link:
|
||||
if !entering {
|
||||
out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag)
|
||||
}
|
||||
case blackfriday.Image:
|
||||
// ignore images
|
||||
walkAction = blackfriday.SkipChildren
|
||||
case blackfriday.Code:
|
||||
out(w, codespanTag)
|
||||
escapeSpecialChars(w, node.Literal)
|
||||
out(w, codespanCloseTag)
|
||||
case blackfriday.Document:
|
||||
break
|
||||
case blackfriday.Paragraph:
|
||||
// roff .PP markers break lists
|
||||
if r.listDepth > 0 {
|
||||
return blackfriday.GoToNext
|
||||
}
|
||||
if entering {
|
||||
out(w, paraTag)
|
||||
} else {
|
||||
out(w, crTag)
|
||||
}
|
||||
case blackfriday.BlockQuote:
|
||||
if entering {
|
||||
out(w, quoteTag)
|
||||
} else {
|
||||
out(w, quoteCloseTag)
|
||||
}
|
||||
case blackfriday.Heading:
|
||||
r.handleHeading(w, node, entering)
|
||||
case blackfriday.HorizontalRule:
|
||||
out(w, hruleTag)
|
||||
case blackfriday.List:
|
||||
r.handleList(w, node, entering)
|
||||
case blackfriday.Item:
|
||||
r.handleItem(w, node, entering)
|
||||
case blackfriday.CodeBlock:
|
||||
out(w, codeTag)
|
||||
escapeSpecialChars(w, node.Literal)
|
||||
out(w, codeCloseTag)
|
||||
case blackfriday.Table:
|
||||
r.handleTable(w, node, entering)
|
||||
case blackfriday.TableCell:
|
||||
r.handleTableCell(w, node, entering)
|
||||
case blackfriday.TableHead:
|
||||
case blackfriday.TableBody:
|
||||
case blackfriday.TableRow:
|
||||
// no action as cell entries do all the nroff formatting
|
||||
return blackfriday.GoToNext
|
||||
default:
|
||||
fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String())
|
||||
}
|
||||
return walkAction
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleText(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
var (
|
||||
start, end string
|
||||
)
|
||||
// handle special roff table cell text encapsulation
|
||||
if node.Parent.Type == blackfriday.TableCell {
|
||||
if len(node.Literal) > 30 {
|
||||
start = tableCellStart
|
||||
end = tableCellEnd
|
||||
} else {
|
||||
// end rows that aren't terminated by "tableCellEnd" with a cr if end of row
|
||||
if node.Parent.Next == nil && !node.Parent.IsHeader {
|
||||
end = crTag
|
||||
}
|
||||
}
|
||||
}
|
||||
out(w, start)
|
||||
escapeSpecialChars(w, node.Literal)
|
||||
out(w, end)
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
if entering {
|
||||
switch node.Level {
|
||||
case 1:
|
||||
if !r.firstHeader {
|
||||
out(w, titleHeader)
|
||||
r.firstHeader = true
|
||||
break
|
||||
}
|
||||
out(w, topLevelHeader)
|
||||
case 2:
|
||||
out(w, secondLevelHdr)
|
||||
default:
|
||||
out(w, otherHeader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleList(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
openTag := listTag
|
||||
closeTag := listCloseTag
|
||||
if node.ListFlags&blackfriday.ListTypeDefinition != 0 {
|
||||
// tags for definition lists handled within Item node
|
||||
openTag = ""
|
||||
closeTag = ""
|
||||
}
|
||||
if entering {
|
||||
r.listDepth++
|
||||
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
|
||||
r.listCounters = append(r.listCounters, 1)
|
||||
}
|
||||
out(w, openTag)
|
||||
} else {
|
||||
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
|
||||
r.listCounters = r.listCounters[:len(r.listCounters)-1]
|
||||
}
|
||||
out(w, closeTag)
|
||||
r.listDepth--
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
if entering {
|
||||
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
|
||||
out(w, fmt.Sprintf(".IP \"%3d.\" 5\n", r.listCounters[len(r.listCounters)-1]))
|
||||
r.listCounters[len(r.listCounters)-1]++
|
||||
} else if node.ListFlags&blackfriday.ListTypeDefinition != 0 {
|
||||
// state machine for handling terms and following definitions
|
||||
// since blackfriday does not distinguish them properly, nor
|
||||
// does it seperate them into separate lists as it should
|
||||
if !r.defineTerm {
|
||||
out(w, arglistTag)
|
||||
r.defineTerm = true
|
||||
} else {
|
||||
r.defineTerm = false
|
||||
}
|
||||
} else {
|
||||
out(w, ".IP \\(bu 2\n")
|
||||
}
|
||||
} else {
|
||||
out(w, "\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
if entering {
|
||||
out(w, tableStart)
|
||||
//call walker to count cells (and rows?) so format section can be produced
|
||||
columns := countColumns(node)
|
||||
out(w, strings.Repeat("l ", columns)+"\n")
|
||||
out(w, strings.Repeat("l ", columns)+".\n")
|
||||
} else {
|
||||
out(w, tableEnd)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
var (
|
||||
start, end string
|
||||
)
|
||||
if node.IsHeader {
|
||||
start = codespanTag
|
||||
end = codespanCloseTag
|
||||
}
|
||||
if entering {
|
||||
if node.Prev != nil && node.Prev.Type == blackfriday.TableCell {
|
||||
out(w, "\t"+start)
|
||||
} else {
|
||||
out(w, start)
|
||||
}
|
||||
} else {
|
||||
// need to carriage return if we are at the end of the header row
|
||||
if node.IsHeader && node.Next == nil {
|
||||
end = end + crTag
|
||||
}
|
||||
out(w, end)
|
||||
}
|
||||
}
|
||||
|
||||
// because roff format requires knowing the column count before outputting any table
|
||||
// data we need to walk a table tree and count the columns
|
||||
func countColumns(node *blackfriday.Node) int {
|
||||
var columns int
|
||||
|
||||
node.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
|
||||
switch node.Type {
|
||||
case blackfriday.TableRow:
|
||||
if !entering {
|
||||
return blackfriday.Terminate
|
||||
}
|
||||
case blackfriday.TableCell:
|
||||
if entering {
|
||||
columns++
|
||||
}
|
||||
default:
|
||||
}
|
||||
return blackfriday.GoToNext
|
||||
})
|
||||
return columns
|
||||
}
|
||||
|
||||
func out(w io.Writer, output string) {
|
||||
io.WriteString(w, output) // nolint: errcheck
|
||||
}
|
||||
|
||||
func needsBackslash(c byte) bool {
|
||||
for _, r := range []byte("-_&\\~") {
|
||||
if c == r {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func escapeSpecialChars(w io.Writer, text []byte) {
|
||||
for i := 0; i < len(text); i++ {
|
||||
// escape initial apostrophe or period
|
||||
if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') {
|
||||
out(w, "\\&")
|
||||
}
|
||||
|
||||
// directly copy normal characters
|
||||
org := i
|
||||
|
||||
for i < len(text) && !needsBackslash(text[i]) {
|
||||
i++
|
||||
}
|
||||
if i > org {
|
||||
w.Write(text[org:i]) // nolint: errcheck
|
||||
}
|
||||
|
||||
// escape a character
|
||||
if i >= len(text) {
|
||||
break
|
||||
}
|
||||
|
||||
w.Write([]byte{'\\', text[i]}) // nolint: errcheck
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user