Skip to content

Commit

Permalink
Merge pull request #124 from corhere/fix-whatis
Browse files Browse the repository at this point in the history
Emit a NAME section properly formatted for whatis parsing
  • Loading branch information
cpuguy83 authored Sep 12, 2024
2 parents 4d7d268 + 426206c commit 6350b8a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
20 changes: 18 additions & 2 deletions md2man/roff.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,23 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering

switch node.Type {
case blackfriday.Text:
escapeSpecialChars(w, node.Literal)
// Special case: format the NAME section as required for proper whatis parsing.
// Refer to the lexgrog(1) and groff_man(7) manual pages for details.
if node.Parent != nil &&
node.Parent.Type == blackfriday.Paragraph &&
node.Parent.Prev != nil &&
node.Parent.Prev.Type == blackfriday.Heading &&
node.Parent.Prev.FirstChild != nil &&
bytes.EqualFold(node.Parent.Prev.FirstChild.Literal, []byte("NAME")) {
before, after, found := bytes.Cut(node.Literal, []byte(" - "))
escapeSpecialChars(w, before)
if found {
out(w, ` \- `)
escapeSpecialChars(w, after)
}
} else {
escapeSpecialChars(w, node.Literal)
}
case blackfriday.Softbreak:
out(w, crTag)
case blackfriday.Hardbreak:
Expand Down Expand Up @@ -138,7 +154,7 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering
if r.listDepth > 0 {
return blackfriday.GoToNext
}
if entering {
if entering && (node.Prev == nil || node.Prev.Type != blackfriday.Heading) {
out(w, paraTag)
} else {
out(w, crTag)
Expand Down
14 changes: 14 additions & 0 deletions md2man/roff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,20 @@ func TestComments(t *testing.T) {
doTestsInlineParam(t, inlineTests, TestParams{})
}

func TestHeadings(t *testing.T) {
tests := []string{
"# title\n\n# NAME\ncommand - description\n\n# SYNOPSIS\nA short description\n\nWhich spans multiple paragraphs\n",
".nh\n.TH title\n\n.SH NAME\ncommand \\- description\n\n\n.SH SYNOPSIS\nA short description\n\n.PP\nWhich spans multiple paragraphs\n",

"# title\n\n# Name\nmy-command, other - description - with - hyphens\n",
".nh\n.TH title\n\n.SH Name\nmy-command, other \\- description - with - hyphens\n",

"# title\n\n# Not NAME\nsome - other - text\n",
".nh\n.TH title\n\n.SH Not NAME\nsome - other - text\n",
}
doTestsInline(t, tests)
}

func execRecoverableTestSuite(t *testing.T, tests []string, params TestParams, suite func(candidate *string)) {
// Catch and report panics. This is useful when running 'go test -v' on
// the integration server. When developing, though, crash dump is often
Expand Down

0 comments on commit 6350b8a

Please sign in to comment.