Skip to content

Commit 76a2e10

Browse files
committed
refactor(cmd/web): htmldoc 生成 markdown 文档
1 parent 77411b1 commit 76a2e10

File tree

8 files changed

+259
-478
lines changed

8 files changed

+259
-478
lines changed

cmd/web/htmldoc/export.go

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@ import (
2424
)
2525

2626
type data struct {
27-
Title string // 标题,页面标题和文档的 h1
28-
Desc template.HTML
29-
Style template.CSS // stylesheet 样式表
30-
Lang string // 页面语言
31-
Header template.HTML
32-
Footer template.HTML
27+
Title string // 标题
28+
Desc template.HTML
3329

3430
TypeLocale string // 表格中 type 的翻译项
3531
DescLocale string // 表格中 desc 的翻译项
@@ -44,7 +40,7 @@ type object struct {
4440

4541
type item struct {
4642
XML, JSON, YAML, TOML string
47-
Type template.HTML
43+
Type string
4844
Desc template.HTML
4945
}
5046

@@ -61,9 +57,9 @@ var basicTypes = []string{
6157
// output 输出的 html 文档路径;
6258
// lang 输出的文档语言,被应用在 html 的 lang 属性上;
6359
// title 文档的标题;
64-
// desc 文档的描述,可以是 HTML 格式;
60+
// desc 文档的描述,可以是 markdown 格式;
6561
// style 样式表;
66-
func export(dir, objName, output, lang, title, desc, header, footer, style string) error {
62+
func export(dir, objName, output, lang, title, desc string) error {
6763
p, err := locales.NewPrinter(lang)
6864
if err != nil {
6965
return err
@@ -87,17 +83,9 @@ func export(dir, objName, output, lang, title, desc, header, footer, style strin
8783
return web.NewLocaleError("not found source in %s", dir)
8884
}
8985

90-
if style == defaultStyleValue {
91-
style = defaultStyle
92-
}
93-
9486
d := &data{
95-
Title: title,
96-
Desc: template.HTML(desc),
97-
Style: template.CSS(style),
98-
Lang: lang,
99-
Header: template.HTML(header),
100-
Footer: template.HTML(footer),
87+
Title: title,
88+
Desc: template.HTML(desc),
10189

10290
TypeLocale: web.StringPhrase("type").LocaleString(p),
10391
DescLocale: web.StringPhrase("description").LocaleString(p),
@@ -161,6 +149,10 @@ func (d *data) append(o *object) {
161149
}
162150
}
163151

152+
var linkReplacer = strings.NewReplacer(
153+
".", "",
154+
)
155+
164156
func (d *data) parseObject(obj *ast.TypeSpec) []string {
165157
s, ok := obj.Type.(*ast.StructType)
166158
if !ok {
@@ -219,15 +211,16 @@ func (d *data) parseObject(obj *ast.TypeSpec) []string {
219211

220212
if slices.Index(basicTypes, fieldTypeName) < 0 {
221213
waitList = append(waitList, fieldTypeName)
222-
fieldTypeName = `<a href="#` + fieldTypeName + `">` + fieldTypeName + "</a>"
214+
// https://stackoverflow.com/questions/51221730/markdown-link-to-header
215+
fieldTypeName = "[" + fieldTypeName + "](#" + strings.ToLower(linkReplacer.Replace(fieldTypeName)) + ")"
223216
}
224217

225218
o.Items = append(o.Items, &item{
226219
XML: xml,
227220
JSON: json,
228221
YAML: yaml,
229222
TOML: toml,
230-
Type: template.HTML(fieldTypeName),
223+
Type: fieldTypeName,
231224
Desc: comment2HTML(f.Doc, f.Comment),
232225
})
233226
}
@@ -251,13 +244,18 @@ func getName(name, tag string) string {
251244
}
252245

253246
var (
254-
cPrinter comment.Printer
255-
cParser comment.Parser
247+
cPrinter comment.Printer
248+
cParser comment.Parser
249+
brReplacer = strings.NewReplacer(
250+
"\n\n", "<br />",
251+
"\n", "<br />",
252+
)
256253
)
257254

258255
func comment2HTML(doc, c *ast.CommentGroup) template.HTML {
259256
if doc == nil {
260257
doc = c
261258
}
262-
return template.HTML(cPrinter.HTML(cParser.Parse(doc.Text())))
259+
s := string(cPrinter.Markdown(cParser.Parse(doc.Text())))
260+
return template.HTML(brReplacer.Replace(s))
263261
}

cmd/web/htmldoc/export_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2018-2024 caixw
1+
// SPDX-FileCopyrightText: 2018-2025 caixw
22
//
33
// SPDX-License-Identifier: MIT
44

@@ -18,7 +18,7 @@ func TestExport(t *testing.T) {
1818
a := assert.New(t, false)
1919

2020
output := "./testdata/output.out.html"
21-
a.NotError(export("./testdata", "object", output, "zh-CN", "title", "desc", "", "", defaultStyle)).
21+
a.NotError(export("./testdata", "object", output, "zh-CN", "title", "desc", "", "")).
2222
FileExists(output)
2323
}
2424

cmd/web/htmldoc/htmldoc.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2018-2024 caixw
1+
// SPDX-FileCopyrightText: 2018-2025 caixw
22
//
33
// SPDX-License-Identifier: MIT
44

@@ -24,9 +24,6 @@ const (
2424
langUsage = web.StringPhrase("set html page language")
2525
titleUsage = web.StringPhrase("set html page title")
2626
descUsage = web.StringPhrase("set html page description")
27-
styleUsage = web.StringPhrase("set html page stylesheet in html>head>style")
28-
headerUsage = web.StringPhrase("set html page header")
29-
footerUsage = web.StringPhrase("set html page footer")
3027
)
3128

3229
const defaultStyleValue = "default"
@@ -39,12 +36,9 @@ func Init(opt *cmdopt.CmdOpt, p *localeutil.Printer) {
3936
lang := fs.String("lang", "cmn-Hans", langUsage.LocaleString(p))
4037
title := fs.String("title", "config", titleUsage.LocaleString(p))
4138
desc := fs.String("desc", "", descUsage.LocaleString(p))
42-
style := fs.String("style", defaultStyleValue, styleUsage.LocaleString(p))
43-
header := fs.String("header", "", headerUsage.LocaleString(p))
44-
footer := fs.String("footer", "", footerUsage.LocaleString(p))
4539

4640
return func(io.Writer) error {
47-
return export(*dir, *obj, *output, *lang, *title, *desc, *header, *footer, *style)
41+
return export(*dir, *obj, *output, *lang, *title, *desc)
4842
}
4943
})
5044
}

cmd/web/htmldoc/tpl.go

Lines changed: 18 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,26 @@
1-
// SPDX-FileCopyrightText: 2018-2024 caixw
1+
// SPDX-FileCopyrightText: 2018-2025 caixw
22
//
33
// SPDX-License-Identifier: MIT
44

55
package htmldoc
66

7-
const defaultStyle = `
8-
:root {
9-
--color: black;
10-
--bg: white;
11-
}
12-
@media (prefers-color-scheme: dark) {
13-
:root {
14-
--color: white;
15-
--bg: black;
16-
}
17-
}
18-
table {
19-
width: 100%;
20-
border-collapse: collapse;
21-
border: 1px solid var(--color);
22-
text-align: left;
23-
}
24-
th {
25-
text-align: left;
26-
}
27-
tr {
28-
border-bottom: 1px solid var(--color);
29-
}
30-
td {
31-
padding-left: 5px;
32-
padding-right: 3px;
33-
}
7+
const tpl = `# {{.Title}}
348
35-
body {
36-
color: var(--color);
37-
background: var(--bg);
38-
}`
9+
{{if .Desc}}{{.Desc}}{{end -}}
3910
40-
const tpl = `<!DOCTYPE html>
41-
<html lang="{{.Lang}}">
42-
<head>
43-
<title>{{.Title}}</title>
44-
<meta charset="utf-8" />
45-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
46-
{{- if .Style}}
47-
<style>
48-
{{.Style}}
49-
</style>
50-
{{- end}}
51-
</head>
52-
<body>
53-
{{- if .Header}}
54-
{{.Header}}
55-
{{else}}
56-
<h1>{{.Title}}</h1>
57-
{{- if .Desc}}<article>{{.Desc}}</article>{{end -}}
58-
{{end}}
11+
{{- range .Objects}}
12+
{{if .Title}}## {{.Title}}{{end}}
5913
60-
{{- range .Objects}}
61-
{{- if .Title}}<h2 id="{{.Title}}">{{.Title}}</h2>{{end -}}
62-
{{- if .Desc}}<article>{{.Desc}}</article>{{end -}}
63-
{{if .Items}}
64-
<table>
65-
<thead><tr><th>JSON</th><th>YAML</th><th>XML</th><th>TOML</th><th>{{$.TypeLocale}}</th><th>{{$.DescLocale}}</th><tr></thead>
66-
<tbody>
67-
{{range .Items -}}
68-
<tr><td>{{.JSON}}</td><td>{{.YAML}}</td><td>{{.XML}}</td><td>{{.TOML}}</td><td>{{.Type}}</td><td>{{.Desc}}</td></tr>
69-
{{- end}}
70-
</tbody>
71-
</table>
72-
{{end}}
73-
{{- end}}
74-
{{- if .Footer}}{{.Footer}}{{end}}
75-
</body>
76-
</html>`
14+
{{if .Desc}}{{.Desc}}{{end}}
15+
16+
{{if .Items}}
17+
| JSON | YAML | XML | TOML | {{$.TypeLocale}} | {{$.DescLocale}} |
18+
|------|------|-----|------|------------------|------------------|
19+
{{range .Items -}}
20+
| {{.JSON}} | {{.YAML}} | {{.XML}} | {{.TOML}} | {{.Type}} | {{.Desc}} |
21+
{{end}}
22+
23+
{{end}}
24+
25+
{{- end}}
26+
`

0 commit comments

Comments
 (0)