Skip to content

Commit cf87d3b

Browse files
authored
man pages: add author section (#122)
This renders the authors (from the title block), if specified, into a Authors section. Signed-off-by: Miek Gieben <miek@miek.nl>
1 parent b47672c commit cf87d3b

File tree

8 files changed

+132
-21
lines changed

8 files changed

+132
-21
lines changed

Syntax.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,15 @@ Title Block:
208208
* `area`, what is it, e.g. "User Commands".
209209
* `workgroup`, who wrote this e.g. "Mmark Markdown".
210210
* `date`, date of the man page, optional, defaults to "today".
211+
* `author`, to add an Authors section at the end.
211212

212213
Images:
213214
: See [Images in Mmark](/syntax/images) for details, `ascii-art` images from a sub-figure are
214215
included.
215216

216217
References and citations:
217-
: Supported, a "Bibliography" section is added.
218+
: Supported, a "Bibliography" section is added. Note that unlike XML2RFC, references for IDs and
219+
RFCs *are not* automatically added.
218220

219221
Code Block:
220222
: Tabs are converted into four spaces.

lang/lang.go

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,36 @@ func New(language string) Lang {
1212
// The keys must be in all lower case for normalized lookup.
1313
l.m = map[string]Term{
1414
"en": {
15-
Footnotes: "Footnotes",
15+
And: "and",
16+
Authors: "Authors",
1617
Bibliography: "Bibliography",
18+
Footnotes: "Footnotes",
1719
Index: "Index",
20+
WrittenBy: "Written by",
1821
},
1922
"nl": {
20-
Footnotes: "Voetnoten",
2123
Bibliography: "Bibliografie",
24+
Footnotes: "Voetnoten",
2225
Index: "Index",
2326
},
2427
"de": {
25-
Footnotes: "Fußnoten",
2628
Bibliography: "Literaturverzeichnis",
29+
Footnotes: "Fußnoten",
2730
Index: "Index",
2831
},
2932
"ja": {
30-
Footnotes: "脚注",
3133
Bibliography: "参考文献",
34+
Footnotes: "脚注",
3235
Index: "索引",
3336
},
3437
"zh-cn": {
35-
Footnotes: "注释",
3638
Bibliography: "参考文献",
39+
Footnotes: "注释",
3740
Index: "索引",
3841
},
3942
"zh-tw": {
40-
Footnotes: "註釋",
4143
Bibliography: "參考文獻",
44+
Footnotes: "註釋",
4245
Index: "索引",
4346
},
4447
}
@@ -55,9 +58,12 @@ type Lang struct {
5558

5659
// Term contains the specific terms for translation.
5760
type Term struct {
58-
Footnotes string
61+
And string
62+
Authors string
5963
Bibliography string
64+
Footnotes string
6065
Index string
66+
WrittenBy string
6167
}
6268

6369
func (l Lang) Footnotes() string {
@@ -83,3 +89,27 @@ func (l Lang) Index() string {
8389
}
8490
return t.Index
8591
}
92+
93+
func (l Lang) Authors() string {
94+
t, ok := l.m[l.language]
95+
if !ok {
96+
return l.m["en"].Authors
97+
}
98+
return t.Authors
99+
}
100+
101+
func (l Lang) And() string {
102+
t, ok := l.m[l.language]
103+
if !ok {
104+
return l.m["en"].And
105+
}
106+
return t.And
107+
}
108+
109+
func (l Lang) WrittenBy() string {
110+
t, ok := l.m[l.language]
111+
if !ok {
112+
return l.m["en"].WrittenBy
113+
}
114+
return t.WrittenBy
115+
}

mast/authors.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package mast
2+
3+
import (
4+
"github.com/gomarkdown/markdown/ast"
5+
)
6+
7+
// Authors represents markdown authors section node.
8+
type Authors struct {
9+
ast.Container
10+
}

mmark.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -106,19 +106,6 @@ func main() {
106106
}
107107

108108
doc := markdown.Parse(d, p)
109-
if *flagBib {
110-
mparser.AddBibliography(doc)
111-
}
112-
if *flagIndex {
113-
mparser.AddIndex(doc)
114-
}
115-
116-
if *flagAst {
117-
ast.Print(os.Stdout, doc)
118-
fmt.Print("\n")
119-
return
120-
}
121-
122109
if *flagMan {
123110
title := false
124111
// If there isn't a title block the resulting manual page does not start
@@ -136,8 +123,24 @@ func main() {
136123
c := doc.GetChildren()
137124
newc := append([]ast.Node{t}, c...)
138125
doc.SetChildren(newc) // t must be the first element.
126+
} else {
127+
ast.AppendChild(doc, &mast.Authors{})
139128
}
129+
140130
}
131+
if *flagBib {
132+
mparser.AddBibliography(doc)
133+
}
134+
if *flagIndex {
135+
mparser.AddIndex(doc)
136+
}
137+
138+
if *flagAst {
139+
ast.Print(os.Stdout, doc)
140+
fmt.Print("\n")
141+
return
142+
}
143+
141144
var renderer markdown.Renderer
142145

143146
switch {

render/man/authors.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package man
2+
3+
import (
4+
"io"
5+
"strings"
6+
7+
"github.com/gomarkdown/markdown/ast"
8+
"github.com/mmarkdown/mmark/mast"
9+
)
10+
11+
// authors creates a 'Authors' section that can be included. Only the 'fullname' is used.
12+
// If not authors are specified, it will return nil.
13+
func (r *Renderer) authors(w io.Writer, _ *mast.Authors, entering bool) {
14+
if !entering {
15+
return
16+
}
17+
if r.Title == nil {
18+
return
19+
}
20+
author := r.Title.TitleData.Author
21+
if len(author) == 0 {
22+
return
23+
}
24+
25+
// create a node and call render on it.
26+
node := &ast.Heading{Level: 1}
27+
authors := r.opts.Language.Authors()
28+
ast.AppendChild(node, &ast.Text{ast.Leaf{Literal: []byte(authors)}})
29+
la := len(author)
30+
31+
// Needs to use the translation stuff
32+
para := &ast.Paragraph{}
33+
text := r.opts.Language.WrittenBy() + " "
34+
// combine them with commas, add the last one with 'and'
35+
switch la {
36+
case 1:
37+
text += author[0].Fullname
38+
case 2:
39+
text += author[0].Fullname + " " + r.opts.Language.And() + " " + author[1].Fullname
40+
default:
41+
names := make([]string, len(author))
42+
for i, a := range author {
43+
names[i] = a.Fullname
44+
}
45+
text += strings.Join(names[:len(names)-2], ", ")
46+
text += " " + r.opts.Language.And() + " " + names[len(names)-1]
47+
}
48+
text += "."
49+
50+
ast.AppendChild(para, &ast.Text{ast.Leaf{Literal: []byte(text)}})
51+
ast.AppendChild(node, para)
52+
53+
ast.WalkFunc(node, func(node ast.Node, entering bool) ast.WalkStatus {
54+
return r.RenderNode(w, node, entering)
55+
})
56+
57+
return
58+
}

render/man/renderer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type RendererOptions struct {
4747
type Renderer struct {
4848
opts RendererOptions
4949

50+
Title *mast.Title
5051
listLevel int
5152
allListLevel int
5253
}
@@ -415,6 +416,9 @@ func (r *Renderer) RenderNode(w io.Writer, node ast.Node, entering bool) ast.Wal
415416
// do nothing
416417
case *mast.Title:
417418
r.title(w, node, entering)
419+
r.Title = node // save for later.
420+
case *mast.Authors:
421+
r.authors(w, node, entering)
418422
case *mast.Bibliography:
419423
if entering {
420424
r.outs(w, "\n.SH \"")

render/markdown/renderer.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,8 @@ func (r *Renderer) RenderNode(w io.Writer, node ast.Node, entering bool) ast.Wal
648648
r.outs(w, node.Trigger)
649649
r.outs(w, "\n")
650650
r.newline(w)
651+
case *mast.Authors:
652+
// ignore
651653
case *mast.Bibliography:
652654
case *mast.BibliographyItem:
653655
case *mast.DocumentIndex, *mast.IndexLetter, *mast.IndexItem, *mast.IndexSubItem, *mast.IndexLink:

render/xml/renderer.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,8 @@ func (r *Renderer) RenderNode(w io.Writer, node ast.Node, entering bool) ast.Wal
716716
case *mast.Title:
717717
r.titleBlock(w, node)
718718
r.title = true
719+
case *mast.Authors:
720+
// ignore
719721
case *mast.Bibliography:
720722
r.bibliography(w, node, entering)
721723
case *mast.BibliographyItem:

0 commit comments

Comments
 (0)