Move Wiki Pages to MD

This commit is contained in:
2026-04-30 20:43:53 +02:00
parent 78133efdf4
commit 18eab086cc
4 changed files with 106 additions and 102 deletions
+45 -77
View File
@@ -5,7 +5,6 @@ import (
"embed"
"encoding/json"
"fmt"
"html"
"io/fs"
"os"
"path/filepath"
@@ -25,7 +24,7 @@ const (
legacyWikiRootDirName = ".wiki"
wikiPagesDirName = "pages"
wikiStateFileName = "state.json"
wikiGeneratorVersion = "nodebb-html-v1"
wikiGeneratorVersion = "nodebb-markdown-v1"
wikiGeneratedStatus = "generated"
wikiSkippedStatus = "skipped"
)
@@ -126,7 +125,7 @@ func buildWiki(p *project.Project, nativeResult BuildResult, force bool, progres
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return err
}
content = renderNodeBBManagedHTML(pageID, content)
content = renderNodeBBManagedMarkdown(pageID, content)
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
return err
}
@@ -1240,24 +1239,24 @@ func wikiStatusNoun(category string) string {
func generateStatusPages(outputDir string, pageStatuses map[string]string, pageTitles map[string]string) error {
summaries := buildWikiNamespaceSummaries(pageStatuses)
if err := writeWikiFile(filepath.Join(outputDir, "meta", "wikistatus.html"), renderWikiStatusReportPage(summaries)); err != nil {
if err := writeWikiFile(filepath.Join(outputDir, "meta", "wikistatus.md"), renderWikiStatusReportPage(summaries)); err != nil {
return err
}
for _, namespace := range wikiManagedNamespaces {
summary := summaries[namespace]
if err := writeWikiFile(filepath.Join(outputDir, "meta", "wikistatus", namespace+".html"), renderWikiNamespaceFragment(namespace, summary)); err != nil {
if err := writeWikiFile(filepath.Join(outputDir, "meta", "wikistatus", namespace+".md"), renderWikiNamespaceFragment(namespace, summary)); err != nil {
return err
}
for _, status := range []string{wikiStatusNew, wikiStatusModified, wikiStatusVanilla} {
pageIDs := filterWikiPageIDs(pageStatuses, namespace, status)
if err := writeWikiFile(filepath.Join(outputDir, "meta", "wikistatus", namespace, status+".html"), renderWikiStatusListingPage(namespaceTitle(namespace)+" "+wikiStatusLabels[status]+" Pages", pageIDs, pageTitles)); err != nil {
if err := writeWikiFile(filepath.Join(outputDir, "meta", "wikistatus", namespace, status+".md"), renderWikiStatusListingPage(namespaceTitle(namespace)+" "+wikiStatusLabels[status]+" Pages", pageIDs, pageTitles)); err != nil {
return err
}
}
}
for _, status := range []string{wikiStatusNew, wikiStatusModified, wikiStatusVanilla} {
pageIDs := filterWikiPageIDs(pageStatuses, "", status)
if err := writeWikiFile(filepath.Join(outputDir, "meta", "wikistatus", status+".html"), renderWikiStatusListingPage(wikiStatusLabels[status]+" Pages", pageIDs, pageTitles)); err != nil {
if err := writeWikiFile(filepath.Join(outputDir, "meta", "wikistatus", status+".md"), renderWikiStatusListingPage(wikiStatusLabels[status]+" Pages", pageIDs, pageTitles)); err != nil {
return err
}
}
@@ -1268,7 +1267,7 @@ func writeWikiFile(path, content string) error {
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return err
}
content = renderNodeBBManagedHTML(wikiRelPathToPageID(path), content)
content = renderNodeBBManagedMarkdown(wikiRelPathToPageID(path), content)
return os.WriteFile(path, []byte(ensureTrailingNewline(content)), 0o644)
}
@@ -1397,11 +1396,12 @@ func wikiPageIDForKey(key string) string {
}
func wikiPageIDToRelPath(pageID string) string {
return filepath.FromSlash(strings.ReplaceAll(pageID, ":", "/") + ".html")
return filepath.FromSlash(strings.ReplaceAll(pageID, ":", "/") + ".md")
}
func wikiRelPathToPageID(path string) string {
path = filepath.ToSlash(path)
path = strings.TrimSuffix(path, ".md")
path = strings.TrimSuffix(path, ".html")
if index := strings.LastIndex(path, "/pages/"); index >= 0 {
path = path[index+len("/pages/"):]
@@ -1583,18 +1583,18 @@ func toDokuWiki(text string) string {
return strings.Join(out, "\n")
}
func renderNodeBBManagedHTML(pageID, dokuText string) string {
func renderNodeBBManagedMarkdown(pageID, dokuText string) string {
generated, notes := splitDokuWikiNotes(dokuText)
body := dokuWikiToNodeBBHTML(generated)
body := dokuWikiToNodeBBMarkdown(generated)
parts := []string{
"<!-- sow-topdata-wiki:page=" + html.EscapeString(pageID) + " -->",
"<!-- sow-topdata-wiki:managed:start -->",
"[//]: # (sow-topdata-wiki:page=" + pageID + ")",
"[//]: # (sow-topdata-wiki:managed:start)",
body,
"<!-- sow-topdata-wiki:managed:end -->",
"[//]: # (sow-topdata-wiki:managed:end)",
}
notesHTML := dokuWikiToNodeBBHTML("===== Notes =====\n" + notes)
if strings.TrimSpace(notesHTML) != "" {
parts = append(parts, notesHTML)
notesMarkdown := dokuWikiToNodeBBMarkdown("===== Notes =====\n" + notes)
if strings.TrimSpace(notesMarkdown) != "" {
parts = append(parts, notesMarkdown)
}
return ensureTrailingNewline(strings.Join(parts, "\n"))
}
@@ -1608,72 +1608,59 @@ func splitDokuWikiNotes(text string) (string, string) {
return before, after
}
func dokuWikiToNodeBBHTML(text string) string {
func dokuWikiToNodeBBMarkdown(text string) string {
text = strings.ReplaceAll(strings.TrimSpace(text), "\r\n", "\n")
if text == "" {
return ""
}
var out []string
var paragraph []string
inList := false
inNotice := false
flushParagraph := func() {
if len(paragraph) == 0 {
return
}
out = append(out, "<p>"+strings.Join(paragraph, "<br>")+"</p>")
paragraph = nil
}
closeList := func() {
if inList {
out = append(out, "</ul>")
inList = false
}
}
closeNotice := func() {
if inNotice {
out = append(out, "</aside>")
inNotice = false
if len(out) > 0 && strings.TrimSpace(out[len(out)-1]) != "" {
out = append(out, "")
}
}
}
appendBlank := func() {
if len(out) == 0 || strings.TrimSpace(out[len(out)-1]) == "" {
return
}
out = append(out, "")
}
for _, line := range strings.Split(text, "\n") {
trimmed := strings.TrimSpace(line)
if trimmed == "" {
flushParagraph()
closeList()
appendBlank()
continue
}
if strings.HasPrefix(trimmed, "<WRAP") {
flushParagraph()
closeList()
out = append(out, `<aside class="sow-generated-note">`)
appendBlank()
inNotice = true
continue
}
if trimmed == "</WRAP>" {
flushParagraph()
closeList()
closeNotice()
continue
}
if heading, level, ok := parseDokuHeading(trimmed); ok {
flushParagraph()
closeList()
closeNotice()
out = append(out, fmt.Sprintf("<h%d>%s</h%d>", level, renderInlineNodeBBHTML(heading), level))
appendBlank()
out = append(out, strings.Repeat("#", level)+" "+renderInlineNodeBBMarkdown(heading))
out = append(out, "")
continue
}
if strings.HasPrefix(trimmed, " * ") || strings.HasPrefix(trimmed, "* ") || strings.HasPrefix(trimmed, "- ") {
flushParagraph()
if !inList {
out = append(out, "<ul>")
inList = true
}
item := strings.TrimSpace(strings.TrimPrefix(strings.TrimPrefix(strings.TrimPrefix(trimmed, " * "), "* "), "- "))
out = append(out, "<li>"+renderInlineNodeBBHTML(item)+"</li>")
prefix := "- "
if inNotice {
prefix = "> - "
}
out = append(out, prefix+renderInlineNodeBBMarkdown(item))
continue
}
@@ -1681,14 +1668,16 @@ func dokuWikiToNodeBBHTML(text string) string {
for _, part := range parts {
part = strings.TrimSpace(part)
if part != "" {
paragraph = append(paragraph, renderInlineNodeBBHTML(part))
prefix := ""
if inNotice {
prefix = "> "
}
out = append(out, prefix+renderInlineNodeBBMarkdown(part))
}
}
}
flushParagraph()
closeList()
closeNotice()
return strings.Join(out, "\n")
return strings.TrimSpace(strings.Join(out, "\n"))
}
func parseDokuHeading(line string) (string, int, bool) {
@@ -1714,29 +1703,8 @@ func parseDokuHeading(line string) (string, int, bool) {
return title, level, true
}
func renderInlineNodeBBHTML(text string) string {
escaped := html.EscapeString(text)
var out strings.Builder
boldOpen := false
for {
index := strings.Index(escaped, "**")
if index < 0 {
out.WriteString(escaped)
break
}
out.WriteString(escaped[:index])
if boldOpen {
out.WriteString("</strong>")
} else {
out.WriteString("<strong>")
}
boldOpen = !boldOpen
escaped = escaped[index+2:]
}
if boldOpen {
out.WriteString("</strong>")
}
return renderWikiLinks(out.String())
func renderInlineNodeBBMarkdown(text string) string {
return renderWikiLinks(text)
}
func renderWikiLinks(text string) string {