settle the Markdown dialect, and namespace an include's footnotes
Tables, footnotes, definition lists, strikethrough and automatic heading ids. Which dialect a site is written against is permanent, so ADR-0058 names the whole set at once — including the four refused, each for a reason rather than a taste: task lists publish nothing, linkify rewrites plain text into markup that ADR-0034 forbids the engine to touch, CJK is the wrong script family for a Bengali site, and the GFM bundle is a package deal for the first two. Footnotes collided with includes, as the queue predicted but worse. An include converts its file on its own bytes (ADR-0038), so goldmark numbered its notes from one again and the page carried two id="fn:1"s — the parent's reference jumped to the fragment's note. shortcodes.FootnotePrefix stamps the file name on the nested document and hands it to goldmark's id-prefix function, so the fragment gets _method-fn:1 and the page keeps fn:1. Two things nothing tested before. The extender list ships from cmd/khosra, which no package can import, so the dialect had never been rendered through the list the binary actually uses — cmd/khosra/wire_test.go now does exactly that, including that the typographer no longer eats a table's delimiter row. And the demo carries the dialect and the footnote namespacing as cases, which caught auto heading ids changing markup in three existing assertions. The reference theme gains five lines: a rule under each table row, an indent for definitions, smaller footnotes. core 2790/2800, ext 1058/2000, 34 gates green.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/yuin/goldmark"
|
||||
"github.com/yuin/goldmark/extension"
|
||||
|
||||
"khosra/internal/content"
|
||||
"khosra/internal/ext/shortcodes"
|
||||
@@ -41,8 +42,16 @@ func exampleSite(t *testing.T) http.Handler {
|
||||
if _, err := shortcodes.Derive(fsys, t.TempDir()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// This list has to match cmd/khosra/wire.go, which a package cannot import because it is a main. Kept in
|
||||
// step by hand, and by the dialect's own test living beside the list it ships (ADR-0058).
|
||||
r, err := render.New(fsys, settings, func(p render.Partial) []goldmark.Extender {
|
||||
return []goldmark.Extender{shortcodes.New(p)}
|
||||
return []goldmark.Extender{
|
||||
extension.Table,
|
||||
extension.NewFootnote(extension.WithFootnoteIDPrefixFunction(shortcodes.FootnotePrefix)),
|
||||
extension.DefinitionList,
|
||||
extension.Strikethrough,
|
||||
shortcodes.New(p),
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -107,8 +116,12 @@ var exampleFeatures = []featureCase{
|
||||
expect: []string{`class="gallery"`, "10-grey.jpg", "srcset=", `src="40-line.svg"`},
|
||||
absent: []string{`src="40-line.svg" srcset`}},
|
||||
{what: "an include is parsed as Markdown, and its fragment has no page of its own", path: "/writing/notes-on-water/", code: 200,
|
||||
expect: []string{"<h2>Method</h2>", "<em>Emphasis and links survive</em>"}},
|
||||
expect: []string{`<h2 id="method">Method</h2>`, "<em>Emphasis and links survive</em>"}},
|
||||
{what: "a fragment is not a bundle", path: "/writing/notes-on-water/_method/", code: 404},
|
||||
{what: "the dialect renders tables, definition lists and strikethrough", path: "/writing/notes-on-water/", code: 200,
|
||||
expect: []string{"<table>", "<th>Gauge</th>", "<dl>", "<dt>Monsoon</dt>", "<del>a struck phrase</del>"}},
|
||||
{what: "a fragment's footnote ids are namespaced, so the page's own keep working", path: "/writing/notes-on-water/", code: 200,
|
||||
expect: []string{`id="fn:1"`, `id="_method-fn:1"`, `href="#_method-fn:1"`}},
|
||||
{what: "a page offers its extras only when it has them", path: "/writing/notes-on-water/", code: 200,
|
||||
expect: []string{`href="/writing/notes-on-water/extras/"`}},
|
||||
{what: "the extras tree is classified", path: "/writing/notes-on-water/extras/", code: 200,
|
||||
|
||||
@@ -91,7 +91,7 @@ func TestSelectingAnEntryRendersWhatItCanAndOffersTheRest(t *testing.T) {
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/writing/story/extras/notes.md", nil))
|
||||
body := rec.Body.String()
|
||||
if !strings.Contains(body, "<h2>Notes</h2>") || !strings.Contains(body, "<em>emphasis</em>") {
|
||||
if !strings.Contains(body, `<h2 id="notes">Notes</h2>`) || !strings.Contains(body, "<em>emphasis</em>") {
|
||||
t.Errorf("markdown should be rendered:\n%s", body)
|
||||
}
|
||||
// The tree is still there: selecting is a link, and the page is a full re-render, so no JavaScript is needed.
|
||||
|
||||
Reference in New Issue
Block a user