aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2026-01-23 15:33:13 +0700
committerShulhan <ms@kilabit.info>2026-01-24 07:11:24 +0700
commit62c2e03409e8f7bc6f3f20df36603344afaf2b3a (patch)
tree0235899db041244ecabc754ca636d7bbd651d1e0
parent8970c0fef45c87c183a27f8a66d9620fdb6daa1e (diff)
downloadciigo-62c2e03409e8f7bc6f3f20df36603344afaf2b3a.tar.xz
all: embed CSS and index HTML template using memfs
Previously, with direct embed, every time we change the CSS or index template, we need to restart the "ciigo serve" command. Using memfs make us easy to update and see the changes directly, without restarting the server.
-rw-r--r--CHANGELOG.adoc26
-rw-r--r--Makefile4
-rw-r--r--README.md4
-rw-r--r--_static/ciigo.css256
-rw-r--r--_static/index.gohtml49
-rw-r--r--ciigo.go9
-rw-r--r--ciigo_test.go59
-rw-r--r--converter.go67
-rw-r--r--embedded_css.go270
-rw-r--r--filehtml.go43
-rw-r--r--internal/cmd/staticfs/main.go35
-rw-r--r--server.go7
-rw-r--r--staticfs.go103
-rw-r--r--template_index_html.go51
-rw-r--r--testdata/goembed/GoEmbed_test.txt131
-rw-r--r--testdata/goembed/default.go133
-rw-r--r--testdata/goembed/default.go.exp133
-rw-r--r--testdata/goembed/out/.gitignore2
-rw-r--r--testdata/goembed/out/default.go129
-rw-r--r--testdata/watcher_test.txt211
-rw-r--r--watcher_test.go8
21 files changed, 1097 insertions, 633 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index 54e9365..3dc678f 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -1,10 +1,28 @@
-// SPDX-FileCopyrightText: 2020 Shulhan <ms@kilabit.info>
// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2020 Shulhan <ms@kilabit.info>
+
= Changelog for ciigo
-Shulhan <ms@kilabit.info>
-:toc:
:sectanchors:
-:sectlinks:
+:toc:
+
+Legend,
+
+* 🪵: Breaking changes
+* 🌱: New feature
+* 🌼: Enhancement
+* 💧: Chores
+
+[#v0_16_0]
+== ciigo v0.16.0 (2026-xx-xx)
+
+**🌱 all: embed CSS and index HTML template using memfs**
+
+Previously, with direct embed, every time we change the CSS or index
+template, we need to restart the "ciigo serve" command.
+
+Using memfs make us easy to update and see the changes directly, without
+restarting the server.
+
[#v0_15_3]
== ciigo v0.15.3 (2025-12-27)
diff --git a/Makefile b/Makefile
index bc043b3..dac9ae9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-## SPDX-FileCopyrightText: 2019 Shulhan <ms@kilabit.info>
## SPDX-License-Identifier: GPL-3.0-or-later
+## SPDX-FileCopyrightText: 2019 Shulhan <ms@kilabit.info>
VERSION:=$(shell git describe --tags)
ENV_GOBIN:=$(shell go env GOBIN)
@@ -16,7 +16,6 @@ lint:
.PHONY: test
test:
- find ./testdata -name "*.html" -delete
CGO_ENABLED=1 go test -failfast -v -race -p=1 -coverprofile=cover.out ./...
go tool cover -html=cover.out -o cover.html
@@ -31,6 +30,7 @@ run-example:
.PHONY: build
build:
mkdir -p $(DIR_BUILD)
+ go run ./internal/cmd/staticfs/
CGO_ENABLED=0 go build $(LDFLAGS) -o $(DIR_BUILD) ./cmd/...
.PHONY: serve-doc
diff --git a/README.md b/README.md
index 53ee00f..88289c0 100644
--- a/README.md
+++ b/README.md
@@ -24,9 +24,9 @@ Features,
- No themes, built your own template and style.
Except for default
- [HTML](https://git.sr.ht/~shulhan/ciigo/tree/main/item/template_index_html.go)
+ [HTML](https://git.sr.ht/~shulhan/ciigo/tree/main/item/_static/index.gohtml)
template and embedded
- [CSS](https://git.sr.ht/~shulhan/ciigo/tree/main/item/embedded_css.go),
+ [CSS](https://git.sr.ht/~shulhan/ciigo/tree/main/item/_static/ciigo.css),
there is no other selection of theme that you can "pre-installed".
- No layout, you are free to structure your sites, using normal directory
diff --git a/_static/ciigo.css b/_static/ciigo.css
new file mode 100644
index 0000000..27cb0fd
--- /dev/null
+++ b/_static/ciigo.css
@@ -0,0 +1,256 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/* SPDX-FileCopyrightText: 2020 Shulhan <ms@kilabit.info> */
+
+body {
+ margin: 0;
+ font-family: Go, Arial, sans-serif;
+ background-color: #fff;
+ line-height: 1.3;
+ text-align: center;
+ color: #222;
+}
+pre,
+code {
+ font-family: "Go Mono", Menlo, monospace;
+ font-size: 0.875rem;
+}
+pre {
+ line-height: 1.4;
+ overflow-x: auto;
+ background: #efefef;
+ padding: 0.625rem;
+ border-radius: 0.3125rem;
+}
+a {
+ color: #007d9c;
+}
+
+p,
+li {
+ max-width: 50rem;
+ word-wrap: break-word;
+}
+li p {
+ margin: 2px;
+}
+p,
+pre,
+ul,
+ol {
+ margin: 1.25rem;
+}
+
+h1,
+h2,
+h3,
+h4 {
+ margin: 1.25rem 0 1.25rem;
+ padding: 0;
+ color: #007d9c;
+ font-weight: bold;
+}
+h1 {
+ font-size: 1.75rem;
+ line-height: 1;
+}
+h1 .text-muted {
+ color: #777;
+}
+h2 {
+ clear: right;
+ font-size: 1.25rem;
+ background: #e0ebf5;
+ padding: 0.5rem;
+ line-height: 1.25;
+ font-weight: normal;
+ overflow: auto;
+ overflow-wrap: break-word;
+}
+h2 a {
+ font-weight: bold;
+}
+h3 {
+ font-size: 1.25rem;
+ line-height: 1.25;
+ overflow: auto;
+ overflow-wrap: break-word;
+}
+h3,
+h4 {
+ margin: 1.25rem 0.3125rem;
+}
+h4 {
+ font-size: 1rem;
+}
+
+h2 > span,
+h3 > span {
+ float: right;
+ margin: 0 25px 0 0;
+ font-weight: normal;
+ color: #5279c7;
+}
+
+dl {
+ margin: 1.25rem;
+}
+dt {
+ font-weight: bold;
+}
+dd {
+ margin: 0 0 0 1.25rem;
+}
+
+/*---- Admonition block */
+
+.admonitionblock > table {
+ border-collapse: separate;
+ border: 0;
+ background: none;
+ width: 100%;
+}
+.admonitionblock > table td.icon {
+ text-align: center;
+ width: 120px;
+}
+.admonitionblock > table td.icon img {
+ max-width: none;
+}
+.admonitionblock > table td.icon .title {
+ font-weight: bold;
+ font-family: "Go", "Open Sans", "DejaVu Sans", sans-serif;
+ text-transform: uppercase;
+}
+.admonitionblock > table td.content {
+ padding-left: 1.125em;
+ padding-right: 1.25em;
+ border-left: 1px solid #dddddf;
+ word-wrap: anywhere;
+}
+.admonitionblock > table td.content > :last-child > :last-child {
+ margin-bottom: 0;
+}
+.admonitionblock.note td.icon {
+ background-color: whitesmoke;
+}
+.admonitionblock.tip td.icon {
+ background-color: azure;
+}
+.admonitionblock.important td.icon {
+ background-color: honeydew;
+}
+.admonitionblock.caution td.icon {
+ background-color: lavenderbush;
+}
+.admonitionblock.warning td.icon {
+ background-color: mistyrose;
+}
+
+/* Topbar */
+
+.topbar {
+ background: #e0ebf5;
+ height: 4rem;
+ overflow: hidden;
+}
+
+.topbar .top-heading,
+.topbar .menu {
+ padding: 1.313rem 0;
+ font-size: 1.25rem;
+ font-weight: normal;
+}
+.topbar .top-heading {
+ float: left;
+}
+.topbar .top-heading a {
+ color: #222;
+ text-decoration: none;
+}
+
+.top-heading .header-logo {
+ height: 2rem;
+ width: 5.125rem;
+}
+
+.topbar .menu {
+ float: right;
+}
+.topbar .menu a {
+ margin: 0.625rem 0.125rem;
+ padding: 0.625rem;
+ color: white;
+ background: #007d9c;
+ border: 0.0625rem solid #007d9c;
+ border-radius: 5px;
+}
+.topbar .menu form {
+ display: inline-block;
+}
+
+/* Page */
+
+.page {
+ width: 100%;
+}
+
+.page > .container,
+.topbar > .container,
+.footer > .container {
+ margin-left: auto;
+ margin-right: auto;
+ padding: 0 1.25rem;
+ max-width: 59.38rem;
+}
+
+.page > .container {
+ text-align: left;
+}
+
+.container .meta {
+ font-style: italic;
+ margin: 1.25rem;
+}
+
+.footer {
+ text-align: center;
+ color: #666;
+ font-size: 0.875rem;
+ margin: 2.5rem 0;
+}
+
+.ulist li .paragraph {
+ margin-bottom: 1em;
+}
+
+.ulist li .paragraph {
+ margin-bottom: 1em;
+}
+
+/* TOC */
+
+#toc a {
+ text-decoration: none;
+}
+#toctitle {
+ display: none;
+}
+#toc li {
+ list-style: none;
+}
+#toc ul .sectlevel1 {
+ padding: 0px;
+}
+#toc ul .sectlevel1,
+#toc ul .sectlevel2,
+#toc ul .sectlevel3,
+#toc ul .sectlevel4,
+#toc ul .sectlevel5 {
+ margin: 4px;
+}
+
+@media screen and (max-width: 992px) {
+ #toc {
+ all: unset;
+ }
+}
diff --git a/_static/index.gohtml b/_static/index.gohtml
new file mode 100644
index 0000000..decb66c
--- /dev/null
+++ b/_static/index.gohtml
@@ -0,0 +1,49 @@
+<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
+<!-- SPDX-FileCopyrightText: 2020 Shulhan <ms@kilabit.info> -->
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="theme-color" content="#375EAB">
+{{- range $k, $v := .Metadata}}
+ <meta name="{{$k}}" content="{{$v}}">
+{{- end}}
+ <title>{{.Title}}</title>
+{{- if ne .EmbeddedCSS ""}}
+ <style>
+ {{.EmbeddedCSS}}
+ </style>
+{{- end}}
+{{- range .Styles}}
+ <link rel="stylesheet" href="{{.}}">
+{{- end}}
+ </head>
+ <body>
+ <div class="topbar">
+ <div class="container">
+ <div class="top-heading">
+ <a href="/">{{.Title}}</a>
+ </div>
+ <div class="menu">
+ <form class="item" action="/_internal/search">
+ <input type="text" name="q" placeholder="Search" />
+ </form>
+ </div>
+ </div>
+ </div>
+ <div class="page">
+ <div class="container">
+{{.Body}}
+ </div>
+ </div>
+ <div class="footer">
+ Powered by <a
+ href="https://git.sr.ht/~shulhan/ciigo"
+ >
+ ciigo
+ </a>
+ </div>
+ </body>
+</html>
+<!-- vim: set filetype=angular: -->
diff --git a/ciigo.go b/ciigo.go
index 0977673..dfecf12 100644
--- a/ciigo.go
+++ b/ciigo.go
@@ -1,5 +1,5 @@
-// SPDX-FileCopyrightText: 2019 M. Shulhan <ms@kilabit.info>
// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2019 M. Shulhan <ms@kilabit.info>
// Package ciigo is a program to write static web server with embedded files
// using the asciidoc markup languages.
@@ -28,7 +28,7 @@ const (
)
// Version define the latest tagged release of this module.
-var Version = `0.15.4`
+var Version = `0.16.0`
// defExcludes define default files to be excludes on GoEmbed.
var defExcludes = []string{
@@ -37,6 +37,11 @@ var defExcludes = []string{
`^\..*`,
}
+// staticfs contains memory file system for "_static/" directory.
+// The value is initialized by running "go run ./internal/cmd/staticfs", that
+// generate "staticfs.go" file.
+var staticfs *memfs.MemFS
+
// Ciigo provides customizable and reusable instance of ciigo for embedding,
// converting, and/or serving HTTP server.
// This type is introduced so one can add HTTP handler or endpoint along
diff --git a/ciigo_test.go b/ciigo_test.go
index 3b3f5de..94d64cb 100644
--- a/ciigo_test.go
+++ b/ciigo_test.go
@@ -1,12 +1,11 @@
-// SPDX-FileCopyrightText: 2022 M. Shulhan <ms@kilabit.info>
// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2022 M. Shulhan <ms@kilabit.info>
package ciigo
import (
- "html/template"
+ "log"
"os"
- "path/filepath"
"regexp"
"sort"
"testing"
@@ -16,10 +15,13 @@ import (
)
func TestMain(m *testing.M) {
- var templateCSS = template.CSS(`body{}`)
-
- _embeddedCSS = &templateCSS
-
+ if staticfs != nil {
+ css, err := staticfs.Get(`/ciigo.css`)
+ if err != nil {
+ log.Fatal(err)
+ }
+ css.Content = []byte(`body{}`)
+ }
os.Exit(m.Run())
}
@@ -85,18 +87,6 @@ func TestGoEmbed(t *testing.T) {
opts EmbedOptions
}
- var (
- outDir = `testdata/goembed/out`
-
- tdata *test.Data
- err error
- )
-
- tdata, err = test.LoadData(`testdata/goembed/GoEmbed_test.txt`)
- if err != nil {
- t.Fatal(err)
- }
-
var listCase = []testCase{{
opts: EmbedOptions{
ConvertOptions: ConvertOptions{
@@ -106,33 +96,26 @@ func TestGoEmbed(t *testing.T) {
PackageName: `mypackage`,
VarName: `memfsIn`,
WithoutModTime: true,
+ GoFileName: `testdata/goembed/default.go`,
+ CommentHeader: `// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2026 Shulhan <ms@kilabit.info>
+`,
},
},
- tag: `default`,
}}
-
- var (
- tcase testCase
- fname string
- fpath string
- got []byte
- )
- for _, tcase = range listCase {
- // Set the output file name based on tag.
- fname = tcase.tag + `.go`
- fpath = filepath.Join(outDir, fname)
- tcase.opts.EmbedOptions.GoFileName = filepath.Join(outDir, fname)
-
- err = GoEmbed(tcase.opts)
+ for _, tcase := range listCase {
+ err := GoEmbed(tcase.opts)
if err != nil {
t.Fatal(err)
}
-
- got, err = os.ReadFile(fpath)
+ got, err := os.ReadFile(tcase.opts.EmbedOptions.GoFileName)
if err != nil {
t.Fatal(err)
}
-
- test.Assert(t, tcase.tag, string(tdata.Output[fname]), string(got))
+ exp, err := os.ReadFile(tcase.opts.EmbedOptions.GoFileName + `.exp`)
+ if err != nil {
+ t.Fatal(err)
+ }
+ test.Assert(t, tcase.tag, string(exp), string(got))
}
}
diff --git a/converter.go b/converter.go
index 57695e7..ea63510 100644
--- a/converter.go
+++ b/converter.go
@@ -1,5 +1,5 @@
-// SPDX-FileCopyrightText: 2019 Shulhan <ms@kilabit.info>
// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2019 Shulhan <ms@kilabit.info>
package ciigo
@@ -12,6 +12,7 @@ import (
"time"
"git.sr.ht/~shulhan/asciidoctor-go"
+ "git.sr.ht/~shulhan/pakakeh.go/lib/memfs"
"github.com/yuin/goldmark"
meta "github.com/yuin/goldmark-meta"
"github.com/yuin/goldmark/parser"
@@ -31,18 +32,20 @@ type Converter struct {
// NewConverter create and initialize Converter with HTML template.
// If htmlTemplate is empty, it will use the internal, predefined template.
func NewConverter(htmlTemplate string) (converter *Converter, err error) {
- var (
- logp = `NewConverter`
-
- tmplContent string
- )
+ var logp = `NewConverter`
converter = &Converter{}
converter.tmpl = template.New(``)
+ var bhtml []byte
if len(htmlTemplate) == 0 {
- tmplContent = templateIndexHTML
+ var node *memfs.Node
+ node, err = staticfs.Get(`/index.gohtml`)
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+ bhtml = node.Content
} else {
converter.htmlTemplate = filepath.Clean(htmlTemplate)
@@ -55,15 +58,12 @@ func NewConverter(htmlTemplate string) (converter *Converter, err error) {
converter.htmlTemplateModtime = fi.ModTime()
- var bhtml []byte
-
bhtml, err = os.ReadFile(converter.htmlTemplate)
if err != nil {
return nil, fmt.Errorf(`%s: %w`, logp, err)
}
-
- tmplContent = string(bhtml)
}
+ var tmplContent = string(bhtml)
converter.tmpl, err = converter.tmpl.Parse(tmplContent)
if err != nil {
@@ -90,7 +90,7 @@ func (converter *Converter) convertFileMarkups(fileMarkups map[string]*FileMarku
for _, fmarkup = range fileMarkups {
if !isForce {
- if !converter.shouldConvert(fmarkup) {
+ if !converter.shouldConvert(fmarkup, isForce) {
continue
}
}
@@ -105,7 +105,12 @@ func (converter *Converter) convertFileMarkups(fileMarkups map[string]*FileMarku
}
func (converter *Converter) htmlTemplateUseInternal() (err error) {
- converter.tmpl, err = converter.tmpl.Parse(templateIndexHTML)
+ var node *memfs.Node
+ node, err = staticfs.Get(`/index.gohtml`)
+ if err != nil {
+ return err
+ }
+ converter.tmpl, err = converter.tmpl.Parse(string(node.Content))
if err != nil {
return err
}
@@ -217,9 +222,14 @@ func (converter *Converter) markdownToHTML(fmarkup *FileMarkup) (fhtml *fileHTML
// shouldConvert will return true if the file markup fmarkup needs to be
// converted to HTML.
-// It return true if the HTML file not exist or the template or markup file is
-// newer than the HTML file.
-func (converter *Converter) shouldConvert(fmarkup *FileMarkup) bool {
+// It return true if,
+// - the HTML file not exist, or
+// - the markup file is newer than the HTML file,
+//
+// In development mode, it will return true if,
+// - the template file is newer than the HTML file, or
+// - the CSS file is newer than the HTML file.
+func (converter *Converter) shouldConvert(fmarkup *FileMarkup, isDevelopment bool) bool {
var fi os.FileInfo
fi, _ = os.Stat(fmarkup.pathHTML)
if fi == nil {
@@ -252,5 +262,30 @@ func (converter *Converter) shouldConvert(fmarkup *FileMarkup) bool {
fmarkup.info = fi
return true
}
+
+ if !isDevelopment {
+ return false
+ }
+
+ // Check with staticfs for CSS and index HTML files.
+ if staticfs == nil {
+ return false
+ }
+ var node *memfs.Node
+ node, _ = staticfs.Get(`/index.gohtml`)
+ if node != nil && node.ModTime().After(htmlModtime) {
+ var newtmpl = template.New(``)
+ newtmpl, err = newtmpl.Parse(string(node.Content))
+ if err != nil {
+ return false
+ }
+ converter.tmpl = newtmpl
+ return true
+ }
+ node, _ = staticfs.Get(`/ciigo.css`)
+ if node != nil && node.ModTime().After(htmlModtime) {
+ return true
+ }
+
return false
}
diff --git a/embedded_css.go b/embedded_css.go
deleted file mode 100644
index 4e10014..0000000
--- a/embedded_css.go
+++ /dev/null
@@ -1,270 +0,0 @@
-// SPDX-FileCopyrightText: 2020 Shulhan <ms@kilabit.info>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package ciigo
-
-import "html/template"
-
-var _embeddedCSS *template.CSS
-
-func embeddedCSS() *template.CSS {
- if _embeddedCSS != nil {
- return _embeddedCSS
- }
-
- var css = template.CSS(`
-body {
- margin: 0;
- font-family: 'Go', Arial, sans-serif;
- background-color: #fff;
- line-height: 1.3;
- text-align: center;
- color: #222;
-}
-pre,
-code {
- font-family: 'Go Mono', Menlo, monospace;
- font-size: 0.875rem;
-}
-pre {
- line-height: 1.4;
- overflow-x: auto;
- background: #efefef;
- padding: 0.625rem;
- border-radius: 0.3125rem;
-}
-a {
- color: #007d9c;
- text-decoration: none;
-}
-a:hover {
- text-decoration: underline;
-}
-
-p,
-li {
- max-width: 50rem;
- word-wrap: break-word;
-}
-li p {
- margin: 2px;
-}
-p,
-pre,
-ul,
-ol {
- margin: 1.25rem;
-}
-
-h1,
-h2,
-h3,
-h4 {
- margin: 1.25rem 0 1.25rem;
- padding: 0;
- color: #007d9c;
- font-weight: bold;
-}
-h1 {
- font-size: 1.75rem;
- line-height: 1;
-}
-h1 .text-muted {
- color: #777;
-}
-h2 {
- clear: right;
- font-size: 1.25rem;
- background: #e0ebf5;
- padding: 0.5rem;
- line-height: 1.25;
- font-weight: normal;
- overflow: auto;
- overflow-wrap: break-word;
-}
-h2 a {
- font-weight: bold;
-}
-h3 {
- font-size: 1.25rem;
- line-height: 1.25;
- overflow: auto;
- overflow-wrap: break-word;
-}
-h3,
-h4 {
- margin: 1.25rem 0.3125rem;
-}
-h4 {
- font-size: 1rem;
-}
-
-h2 > span,
-h3 > span {
- float: right;
- margin: 0 25px 0 0;
- font-weight: normal;
- color: #5279c7;
-}
-
-dl {
- margin: 1.25rem;
-}
-dt {
- font-weight: bold
-}
-dd {
- margin: 0 0 0 1.25rem;
-}
-
-/**
- * Custom classes for pages
- */
-
-.admonitionblock > table {
- border-collapse: separate;
- border: 0;
- background: none;
- width: 100%;
-}
-.admonitionblock > table td.icon {
- text-align: center;
- width: 120px;
-}
-.admonitionblock > table td.icon img {
- max-width: none;
-}
-.admonitionblock > table td.icon .title {
- font-weight: bold;
- font-family: "Go","Open Sans","DejaVu Sans",sans-serif;
- text-transform: uppercase;
-}
-.admonitionblock > table td.content {
- padding-left: 1.125em;
- padding-right: 1.25em;
- border-left: 1px solid #dddddf;
- word-wrap: anywhere;
-}
-.admonitionblock > table td.content>:last-child>:last-child {
- margin-bottom: 0;
-}
-.admonitionblock.note td.icon {
- background-color: whitesmoke;
-}
-.admonitionblock.tip td.icon {
- background-color: azure;
-}
-.admonitionblock.important td.icon {
- background-color: honeydew;
-}
-.admonitionblock.caution td.icon {
- background-color: lavenderbush;
-}
-.admonitionblock.warning td.icon {
- background-color: mistyrose;
-}
-
-.topbar {
- background: #e0ebf5;
- height: 4rem;
- overflow: hidden;
-}
-
-.topbar .top-heading,
-.topbar .menu {
- padding: 1.313rem 0;
- font-size: 1.25rem;
- font-weight: normal;
-}
-.topbar .top-heading {
- float: left;
-}
-.topbar .top-heading a {
- color: #222;
- text-decoration: none;
-}
-
-.top-heading .header-logo {
- height: 2rem;
- width: 5.125rem;
-}
-
-.topbar .menu {
- float: right;
-}
-.topbar .menu a {
- margin: 0.625rem 0.125rem;
- padding: 0.625rem;
- color: white;
- background: #007d9c;
- border: 0.0625rem solid #007d9c;
- border-radius: 5px;
-}
-.topbar .menu form {
- display: inline-block;
-}
-
-.page {
- width: 100%;
-}
-
-.page > .container,
-.topbar > .container,
-.footer > .container {
- margin-left: auto;
- margin-right: auto;
- padding: 0 1.25rem;
- max-width: 59.38rem;
-}
-
-.page > .container {
- text-align: left;
-}
-
-.container .meta {
- font-style: italic;
- margin: 1.25rem;
-}
-
-.footer {
- text-align: center;
- color: #666;
- font-size: 0.875rem;
- margin: 2.5rem 0;
-}
-
-.ulist li .paragraph {
- margin-bottom: 1em;
-}
-
-.ulist li .paragraph {
- margin-bottom: 1em;
-}
-
-/** Custom classes */
-#toctitle {
- display: none;
-}
-#toc li {
- list-style: none;
-}
-#toc ul .sectlevel1 {
- padding: 0px;
-}
-#toc ul .sectlevel1,
-#toc ul .sectlevel2,
-#toc ul .sectlevel3,
-#toc ul .sectlevel4,
-#toc ul .sectlevel5 {
- margin: 4px;
-}
-
-@media screen and (max-width: 992px) {
- #toc {
- all: unset;
- }
-}
-`)
- _embeddedCSS = &css
- return _embeddedCSS
-}
diff --git a/filehtml.go b/filehtml.go
index f770ad8..6e5a080 100644
--- a/filehtml.go
+++ b/filehtml.go
@@ -1,11 +1,12 @@
-// SPDX-FileCopyrightText: 2019 Shulhan <ms@kilabit.info>
// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2019 Shulhan <ms@kilabit.info>
package ciigo
import (
"fmt"
"html/template"
+ "log"
"strings"
"git.sr.ht/~shulhan/asciidoctor-go"
@@ -18,7 +19,7 @@ const (
// fileHTML represent an HTML metadata for header and its body.
type fileHTML struct {
Title string
- EmbeddedCSS *template.CSS
+ EmbeddedCSS template.CSS
Styles []string
Body template.HTML
Metadata map[string]string
@@ -38,6 +39,7 @@ func (fhtml *fileHTML) unpackAdocMetadata(doc *asciidoctor.Document) {
k string
v string
)
+ var withStylesheet bool
fhtml.Title = doc.Title.String()
fhtml.Styles = fhtml.Styles[:0]
@@ -47,6 +49,8 @@ func (fhtml *fileHTML) unpackAdocMetadata(doc *asciidoctor.Document) {
case asciidoctor.DocAttrStylesheet:
if len(v) != 0 {
fhtml.Styles = append(fhtml.Styles, v)
+ } else {
+ withStylesheet = true
}
case asciidoctor.DocAttrAuthorNames:
fhtml.Metadata[asciidoctor.DocAttrAuthor] = v
@@ -56,10 +60,7 @@ func (fhtml *fileHTML) unpackAdocMetadata(doc *asciidoctor.Document) {
fhtml.Metadata[k] = v
}
}
-
- if len(fhtml.Styles) == 0 {
- fhtml.EmbeddedCSS = embeddedCSS()
- }
+ fhtml.initCSS(withStylesheet)
}
func (fhtml *fileHTML) unpackMarkdownMetadata(metadata map[string]any) {
@@ -69,6 +70,10 @@ func (fhtml *fileHTML) unpackMarkdownMetadata(metadata map[string]any) {
vstr string
ok bool
)
+ // On markdown, the default stylesheet is true.
+ // User need to explicitly set `stylesheet: false`
+ // on metadata to turn it off.
+ var withStylesheet = true
fhtml.Styles = fhtml.Styles[:0]
@@ -81,7 +86,11 @@ func (fhtml *fileHTML) unpackMarkdownMetadata(metadata map[string]any) {
key = strings.ToLower(key)
switch key {
case asciidoctor.DocAttrStylesheet:
- fhtml.Styles = append(fhtml.Styles, vstr)
+ if vstr == `false` {
+ withStylesheet = false
+ } else {
+ fhtml.Styles = append(fhtml.Styles, vstr)
+ }
case metadataTitle:
fhtml.Title = vstr
default:
@@ -90,8 +99,24 @@ func (fhtml *fileHTML) unpackMarkdownMetadata(metadata map[string]any) {
fhtml.Metadata[key] = vstr
}
}
+ fhtml.initCSS(withStylesheet)
+}
+
+func (fhtml *fileHTML) initCSS(withStylesheet bool) {
+ var logp = `initCSS`
- if len(fhtml.Styles) == 0 {
- fhtml.EmbeddedCSS = embeddedCSS()
+ if len(fhtml.Styles) != 0 {
+ // User defined their custom CSS throught ":stylesheet:"
+ return
+ }
+ if !withStylesheet {
+ // User unset the stylesheet throught ":stylesheet!".
+ return
+ }
+ css, err := staticfs.Get(`/ciigo.css`)
+ if err != nil {
+ log.Printf(`%s: %s`, logp, err)
+ return
}
+ fhtml.EmbeddedCSS = template.CSS(string(css.Content))
}
diff --git a/internal/cmd/staticfs/main.go b/internal/cmd/staticfs/main.go
new file mode 100644
index 0000000..edcd080
--- /dev/null
+++ b/internal/cmd/staticfs/main.go
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2026 Shulhan <ms@kilabit.info>
+
+package main
+
+import (
+ "log"
+
+ "git.sr.ht/~shulhan/pakakeh.go/lib/memfs"
+)
+
+func main() {
+ var opts = &memfs.Options{
+ Embed: memfs.EmbedOptions{
+ PackageName: `ciigo`,
+ VarName: `staticfs`,
+ GoFileName: `staticfs.go`,
+ CommentHeader: `// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2026 Shulhan <ms@kilabit.info>
+
+`,
+ },
+ Root: `./_static`,
+ }
+
+ staticfs, err := memfs.New(opts)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ err = staticfs.GoEmbed()
+ if err != nil {
+ log.Fatal(err)
+ }
+}
diff --git a/server.go b/server.go
index 8a35fad..2fe26c9 100644
--- a/server.go
+++ b/server.go
@@ -1,5 +1,5 @@
-// SPDX-FileCopyrightText: 2019 Shulhan <ms@kilabit.info>
// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2019 Shulhan <ms@kilabit.info>
package ciigo
@@ -44,6 +44,9 @@ func (ciigo *Ciigo) InitHTTPServer(opts ServeOptions) (err error) {
} else {
opts.Mfs.Opts.TryDirect = opts.IsDevelopment
}
+ if staticfs != nil {
+ staticfs.Opts.TryDirect = opts.IsDevelopment
+ }
ciigo.serveOpts = opts
@@ -209,7 +212,7 @@ func (ciigo *Ciigo) onGet(
return node, 0
}
var err error
- if isNew || ciigo.converter.shouldConvert(fmarkup) {
+ if isNew || ciigo.converter.shouldConvert(fmarkup, ciigo.serveOpts.IsDevelopment) {
err = ciigo.converter.ToHTMLFile(fmarkup)
if err != nil {
log.Printf(`%s: failed to convert markup file %q: %s`,
diff --git a/staticfs.go b/staticfs.go
new file mode 100644
index 0000000..933670f
--- /dev/null
+++ b/staticfs.go
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2026 Shulhan <ms@kilabit.info>
+
+// Code generated by git.sr.ht/~shulhan/pakakeh.go/lib/memfs DO NOT EDIT.
+
+package ciigo
+
+import (
+ "git.sr.ht/~shulhan/pakakeh.go/lib/memfs"
+)
+
+func generate____static() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "./_static",
+ Path: "/",
+ ContentType: "",
+ GenFuncName: "generate____static",
+ }
+ node.SetMode(0o20000000755)
+ node.SetModTimeUnix(1769165044, 480833479)
+ node.SetName("/")
+ node.SetSize(0)
+ node.AddChild(_staticfs_getNode(staticfs, "/ciigo.css", generate__static_ciigo_css))
+ node.AddChild(_staticfs_getNode(staticfs, "/index.gohtml", generate__static_index_gohtml))
+ return node
+}
+
+func generate__static_ciigo_css() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "_static/ciigo.css",
+ Path: "/ciigo.css",
+ ContentType: "text/css; charset=utf-8",
+ GenFuncName: "generate__static_ciigo_css",
+ Content: []byte("\x2F\x2A\x20\x53\x50\x44\x58\x2D\x4C\x69\x63\x65\x6E\x73\x65\x2D\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3A\x20\x47\x50\x4C\x2D\x33\x2E\x30\x2D\x6F\x72\x2D\x6C\x61\x74\x65\x72\x20\x2A\x2F\x0A\x2F\x2A\x20\x53\x50\x44\x58\x2D\x46\x69\x6C\x65\x43\x6F\x70\x79\x72\x69\x67\x68\x74\x54\x65\x78\x74\x3A\x20\x32\x30\x32\x30\x20\x53\x68\x75\x6C\x68\x61\x6E\x20\x3C\x6D\x73\x40\x6B\x69\x6C\x61\x62\x69\x74\x2E\x69\x6E\x66\x6F\x3E\x20\x2A\x2F\x0A\x0A\x62\x6F\x64\x79\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x30\x3B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x66\x61\x6D\x69\x6C\x79\x3A\x20\x47\x6F\x2C\x20\x41\x72\x69\x61\x6C\x2C\x20\x73\x61\x6E\x73\x2D\x73\x65\x72\x69\x66\x3B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x2D\x63\x6F\x6C\x6F\x72\x3A\x20\x23\x66\x66\x66\x3B\x0A\x20\x20\x6C\x69\x6E\x65\x2D\x68\x65\x69\x67\x68\x74\x3A\x20\x31\x2E\x33\x3B\x0A\x20\x20\x74\x65\x78\x74\x2D\x61\x6C\x69\x67\x6E\x3A\x20\x63\x65\x6E\x74\x65\x72\x3B\x0A\x20\x20\x63\x6F\x6C\x6F\x72\x3A\x20\x23\x32\x32\x32\x3B\x0A\x7D\x0A\x70\x72\x65\x2C\x0A\x63\x6F\x64\x65\x20\x7B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x66\x61\x6D\x69\x6C\x79\x3A\x20\x22\x47\x6F\x20\x4D\x6F\x6E\x6F\x22\x2C\x20\x4D\x65\x6E\x6C\x6F\x2C\x20\x6D\x6F\x6E\x6F\x73\x70\x61\x63\x65\x3B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x73\x69\x7A\x65\x3A\x20\x30\x2E\x38\x37\x35\x72\x65\x6D\x3B\x0A\x7D\x0A\x70\x72\x65\x20\x7B\x0A\x20\x20\x6C\x69\x6E\x65\x2D\x68\x65\x69\x67\x68\x74\x3A\x20\x31\x2E\x34\x3B\x0A\x20\x20\x6F\x76\x65\x72\x66\x6C\x6F\x77\x2D\x78\x3A\x20\x61\x75\x74\x6F\x3B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x3A\x20\x23\x65\x66\x65\x66\x65\x66\x3B\x0A\x20\x20\x70\x61\x64\x64\x69\x6E\x67\x3A\x20\x30\x2E\x36\x32\x35\x72\x65\x6D\x3B\x0A\x20\x20\x62\x6F\x72\x64\x65\x72\x2D\x72\x61\x64\x69\x75\x73\x3A\x20\x30\x2E\x33\x31\x32\x35\x72\x65\x6D\x3B\x0A\x7D\x0A\x61\x20\x7B\x0A\x20\x20\x63\x6F\x6C\x6F\x72\x3A\x20\x23\x30\x30\x37\x64\x39\x63\x3B\x0A\x7D\x0A\x0A\x70\x2C\x0A\x6C\x69\x20\x7B\x0A\x20\x20\x6D\x61\x78\x2D\x77\x69\x64\x74\x68\x3A\x20\x35\x30\x72\x65\x6D\x3B\x0A\x20\x20\x77\x6F\x72\x64\x2D\x77\x72\x61\x70\x3A\x20\x62\x72\x65\x61\x6B\x2D\x77\x6F\x72\x64\x3B\x0A\x7D\x0A\x6C\x69\x20\x70\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x32\x70\x78\x3B\x0A\x7D\x0A\x70\x2C\x0A\x70\x72\x65\x2C\x0A\x75\x6C\x2C\x0A\x6F\x6C\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x31\x2E\x32\x35\x72\x65\x6D\x3B\x0A\x7D\x0A\x0A\x68\x31\x2C\x0A\x68\x32\x2C\x0A\x68\x33\x2C\x0A\x68\x34\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x31\x2E\x32\x35\x72\x65\x6D\x20\x30\x20\x31\x2E\x32\x35\x72\x65\x6D\x3B\x0A\x20\x20\x70\x61\x64\x64\x69\x6E\x67\x3A\x20\x30\x3B\x0A\x20\x20\x63\x6F\x6C\x6F\x72\x3A\x20\x23\x30\x30\x37\x64\x39\x63\x3B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x77\x65\x69\x67\x68\x74\x3A\x20\x62\x6F\x6C\x64\x3B\x0A\x7D\x0A\x68\x31\x20\x7B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x73\x69\x7A\x65\x3A\x20\x31\x2E\x37\x35\x72\x65\x6D\x3B\x0A\x20\x20\x6C\x69\x6E\x65\x2D\x68\x65\x69\x67\x68\x74\x3A\x20\x31\x3B\x0A\x7D\x0A\x68\x31\x20\x2E\x74\x65\x78\x74\x2D\x6D\x75\x74\x65\x64\x20\x7B\x0A\x20\x20\x63\x6F\x6C\x6F\x72\x3A\x20\x23\x37\x37\x37\x3B\x0A\x7D\x0A\x68\x32\x20\x7B\x0A\x20\x20\x63\x6C\x65\x61\x72\x3A\x20\x72\x69\x67\x68\x74\x3B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x73\x69\x7A\x65\x3A\x20\x31\x2E\x32\x35\x72\x65\x6D\x3B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x3A\x20\x23\x65\x30\x65\x62\x66\x35\x3B\x0A\x20\x20\x70\x61\x64\x64\x69\x6E\x67\x3A\x20\x30\x2E\x35\x72\x65\x6D\x3B\x0A\x20\x20\x6C\x69\x6E\x65\x2D\x68\x65\x69\x67\x68\x74\x3A\x20\x31\x2E\x32\x35\x3B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x77\x65\x69\x67\x68\x74\x3A\x20\x6E\x6F\x72\x6D\x61\x6C\x3B\x0A\x20\x20\x6F\x76\x65\x72\x66\x6C\x6F\x77\x3A\x20\x61\x75\x74\x6F\x3B\x0A\x20\x20\x6F\x76\x65\x72\x66\x6C\x6F\x77\x2D\x77\x72\x61\x70\x3A\x20\x62\x72\x65\x61\x6B\x2D\x77\x6F\x72\x64\x3B\x0A\x7D\x0A\x68\x32\x20\x61\x20\x7B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x77\x65\x69\x67\x68\x74\x3A\x20\x62\x6F\x6C\x64\x3B\x0A\x7D\x0A\x68\x33\x20\x7B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x73\x69\x7A\x65\x3A\x20\x31\x2E\x32\x35\x72\x65\x6D\x3B\x0A\x20\x20\x6C\x69\x6E\x65\x2D\x68\x65\x69\x67\x68\x74\x3A\x20\x31\x2E\x32\x35\x3B\x0A\x20\x20\x6F\x76\x65\x72\x66\x6C\x6F\x77\x3A\x20\x61\x75\x74\x6F\x3B\x0A\x20\x20\x6F\x76\x65\x72\x66\x6C\x6F\x77\x2D\x77\x72\x61\x70\x3A\x20\x62\x72\x65\x61\x6B\x2D\x77\x6F\x72\x64\x3B\x0A\x7D\x0A\x68\x33\x2C\x0A\x68\x34\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x31\x2E\x32\x35\x72\x65\x6D\x20\x30\x2E\x33\x31\x32\x35\x72\x65\x6D\x3B\x0A\x7D\x0A\x68\x34\x20\x7B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x73\x69\x7A\x65\x3A\x20\x31\x72\x65\x6D\x3B\x0A\x7D\x0A\x0A\x68\x32\x20\x3E\x20\x73\x70\x61\x6E\x2C\x0A\x68\x33\x20\x3E\x20\x73\x70\x61\x6E\x20\x7B\x0A\x20\x20\x66\x6C\x6F\x61\x74\x3A\x20\x72\x69\x67\x68\x74\x3B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x30\x20\x32\x35\x70\x78\x20\x30\x20\x30\x3B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x77\x65\x69\x67\x68\x74\x3A\x20\x6E\x6F\x72\x6D\x61\x6C\x3B\x0A\x20\x20\x63\x6F\x6C\x6F\x72\x3A\x20\x23\x35\x32\x37\x39\x63\x37\x3B\x0A\x7D\x0A\x0A\x64\x6C\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x31\x2E\x32\x35\x72\x65\x6D\x3B\x0A\x7D\x0A\x64\x74\x20\x7B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x77\x65\x69\x67\x68\x74\x3A\x20\x62\x6F\x6C\x64\x3B\x0A\x7D\x0A\x64\x64\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x30\x20\x30\x20\x30\x20\x31\x2E\x32\x35\x72\x65\x6D\x3B\x0A\x7D\x0A\x0A\x2F\x2A\x2D\x2D\x2D\x2D\x20\x41\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x20\x62\x6C\x6F\x63\x6B\x20\x2A\x2F\x0A\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x20\x3E\x20\x74\x61\x62\x6C\x65\x20\x7B\x0A\x20\x20\x62\x6F\x72\x64\x65\x72\x2D\x63\x6F\x6C\x6C\x61\x70\x73\x65\x3A\x20\x73\x65\x70\x61\x72\x61\x74\x65\x3B\x0A\x20\x20\x62\x6F\x72\x64\x65\x72\x3A\x20\x30\x3B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x3A\x20\x6E\x6F\x6E\x65\x3B\x0A\x20\x20\x77\x69\x64\x74\x68\x3A\x20\x31\x30\x30\x25\x3B\x0A\x7D\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x20\x3E\x20\x74\x61\x62\x6C\x65\x20\x74\x64\x2E\x69\x63\x6F\x6E\x20\x7B\x0A\x20\x20\x74\x65\x78\x74\x2D\x61\x6C\x69\x67\x6E\x3A\x20\x63\x65\x6E\x74\x65\x72\x3B\x0A\x20\x20\x77\x69\x64\x74\x68\x3A\x20\x31\x32\x30\x70\x78\x3B\x0A\x7D\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x20\x3E\x20\x74\x61\x62\x6C\x65\x20\x74\x64\x2E\x69\x63\x6F\x6E\x20\x69\x6D\x67\x20\x7B\x0A\x20\x20\x6D\x61\x78\x2D\x77\x69\x64\x74\x68\x3A\x20\x6E\x6F\x6E\x65\x3B\x0A\x7D\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x20\x3E\x20\x74\x61\x62\x6C\x65\x20\x74\x64\x2E\x69\x63\x6F\x6E\x20\x2E\x74\x69\x74\x6C\x65\x20\x7B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x77\x65\x69\x67\x68\x74\x3A\x20\x62\x6F\x6C\x64\x3B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x66\x61\x6D\x69\x6C\x79\x3A\x20\x22\x47\x6F\x22\x2C\x20\x22\x4F\x70\x65\x6E\x20\x53\x61\x6E\x73\x22\x2C\x20\x22\x44\x65\x6A\x61\x56\x75\x20\x53\x61\x6E\x73\x22\x2C\x20\x73\x61\x6E\x73\x2D\x73\x65\x72\x69\x66\x3B\x0A\x20\x20\x74\x65\x78\x74\x2D\x74\x72\x61\x6E\x73\x66\x6F\x72\x6D\x3A\x20\x75\x70\x70\x65\x72\x63\x61\x73\x65\x3B\x0A\x7D\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x20\x3E\x20\x74\x61\x62\x6C\x65\x20\x74\x64\x2E\x63\x6F\x6E\x74\x65\x6E\x74\x20\x7B\x0A\x20\x20\x70\x61\x64\x64\x69\x6E\x67\x2D\x6C\x65\x66\x74\x3A\x20\x31\x2E\x31\x32\x35\x65\x6D\x3B\x0A\x20\x20\x70\x61\x64\x64\x69\x6E\x67\x2D\x72\x69\x67\x68\x74\x3A\x20\x31\x2E\x32\x35\x65\x6D\x3B\x0A\x20\x20\x62\x6F\x72\x64\x65\x72\x2D\x6C\x65\x66\x74\x3A\x20\x31\x70\x78\x20\x73\x6F\x6C\x69\x64\x20\x23\x64\x64\x64\x64\x64\x66\x3B\x0A\x20\x20\x77\x6F\x72\x64\x2D\x77\x72\x61\x70\x3A\x20\x61\x6E\x79\x77\x68\x65\x72\x65\x3B\x0A\x7D\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x20\x3E\x20\x74\x61\x62\x6C\x65\x20\x74\x64\x2E\x63\x6F\x6E\x74\x65\x6E\x74\x20\x3E\x20\x3A\x6C\x61\x73\x74\x2D\x63\x68\x69\x6C\x64\x20\x3E\x20\x3A\x6C\x61\x73\x74\x2D\x63\x68\x69\x6C\x64\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x2D\x62\x6F\x74\x74\x6F\x6D\x3A\x20\x30\x3B\x0A\x7D\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x2E\x6E\x6F\x74\x65\x20\x74\x64\x2E\x69\x63\x6F\x6E\x20\x7B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x2D\x63\x6F\x6C\x6F\x72\x3A\x20\x77\x68\x69\x74\x65\x73\x6D\x6F\x6B\x65\x3B\x0A\x7D\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x2E\x74\x69\x70\x20\x74\x64\x2E\x69\x63\x6F\x6E\x20\x7B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x2D\x63\x6F\x6C\x6F\x72\x3A\x20\x61\x7A\x75\x72\x65\x3B\x0A\x7D\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x2E\x69\x6D\x70\x6F\x72\x74\x61\x6E\x74\x20\x74\x64\x2E\x69\x63\x6F\x6E\x20\x7B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x2D\x63\x6F\x6C\x6F\x72\x3A\x20\x68\x6F\x6E\x65\x79\x64\x65\x77\x3B\x0A\x7D\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x2E\x63\x61\x75\x74\x69\x6F\x6E\x20\x74\x64\x2E\x69\x63\x6F\x6E\x20\x7B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x2D\x63\x6F\x6C\x6F\x72\x3A\x20\x6C\x61\x76\x65\x6E\x64\x65\x72\x62\x75\x73\x68\x3B\x0A\x7D\x0A\x2E\x61\x64\x6D\x6F\x6E\x69\x74\x69\x6F\x6E\x62\x6C\x6F\x63\x6B\x2E\x77\x61\x72\x6E\x69\x6E\x67\x20\x74\x64\x2E\x69\x63\x6F\x6E\x20\x7B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x2D\x63\x6F\x6C\x6F\x72\x3A\x20\x6D\x69\x73\x74\x79\x72\x6F\x73\x65\x3B\x0A\x7D\x0A\x0A\x2F\x2A\x20\x54\x6F\x70\x62\x61\x72\x20\x2A\x2F\x0A\x0A\x2E\x74\x6F\x70\x62\x61\x72\x20\x7B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x3A\x20\x23\x65\x30\x65\x62\x66\x35\x3B\x0A\x20\x20\x68\x65\x69\x67\x68\x74\x3A\x20\x34\x72\x65\x6D\x3B\x0A\x20\x20\x6F\x76\x65\x72\x66\x6C\x6F\x77\x3A\x20\x68\x69\x64\x64\x65\x6E\x3B\x0A\x7D\x0A\x0A\x2E\x74\x6F\x70\x62\x61\x72\x20\x2E\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x2C\x0A\x2E\x74\x6F\x70\x62\x61\x72\x20\x2E\x6D\x65\x6E\x75\x20\x7B\x0A\x20\x20\x70\x61\x64\x64\x69\x6E\x67\x3A\x20\x31\x2E\x33\x31\x33\x72\x65\x6D\x20\x30\x3B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x73\x69\x7A\x65\x3A\x20\x31\x2E\x32\x35\x72\x65\x6D\x3B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x77\x65\x69\x67\x68\x74\x3A\x20\x6E\x6F\x72\x6D\x61\x6C\x3B\x0A\x7D\x0A\x2E\x74\x6F\x70\x62\x61\x72\x20\x2E\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x20\x7B\x0A\x20\x20\x66\x6C\x6F\x61\x74\x3A\x20\x6C\x65\x66\x74\x3B\x0A\x7D\x0A\x2E\x74\x6F\x70\x62\x61\x72\x20\x2E\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x20\x61\x20\x7B\x0A\x20\x20\x63\x6F\x6C\x6F\x72\x3A\x20\x23\x32\x32\x32\x3B\x0A\x20\x20\x74\x65\x78\x74\x2D\x64\x65\x63\x6F\x72\x61\x74\x69\x6F\x6E\x3A\x20\x6E\x6F\x6E\x65\x3B\x0A\x7D\x0A\x0A\x2E\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x20\x2E\x68\x65\x61\x64\x65\x72\x2D\x6C\x6F\x67\x6F\x20\x7B\x0A\x20\x20\x68\x65\x69\x67\x68\x74\x3A\x20\x32\x72\x65\x6D\x3B\x0A\x20\x20\x77\x69\x64\x74\x68\x3A\x20\x35\x2E\x31\x32\x35\x72\x65\x6D\x3B\x0A\x7D\x0A\x0A\x2E\x74\x6F\x70\x62\x61\x72\x20\x2E\x6D\x65\x6E\x75\x20\x7B\x0A\x20\x20\x66\x6C\x6F\x61\x74\x3A\x20\x72\x69\x67\x68\x74\x3B\x0A\x7D\x0A\x2E\x74\x6F\x70\x62\x61\x72\x20\x2E\x6D\x65\x6E\x75\x20\x61\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x30\x2E\x36\x32\x35\x72\x65\x6D\x20\x30\x2E\x31\x32\x35\x72\x65\x6D\x3B\x0A\x20\x20\x70\x61\x64\x64\x69\x6E\x67\x3A\x20\x30\x2E\x36\x32\x35\x72\x65\x6D\x3B\x0A\x20\x20\x63\x6F\x6C\x6F\x72\x3A\x20\x77\x68\x69\x74\x65\x3B\x0A\x20\x20\x62\x61\x63\x6B\x67\x72\x6F\x75\x6E\x64\x3A\x20\x23\x30\x30\x37\x64\x39\x63\x3B\x0A\x20\x20\x62\x6F\x72\x64\x65\x72\x3A\x20\x30\x2E\x30\x36\x32\x35\x72\x65\x6D\x20\x73\x6F\x6C\x69\x64\x20\x23\x30\x30\x37\x64\x39\x63\x3B\x0A\x20\x20\x62\x6F\x72\x64\x65\x72\x2D\x72\x61\x64\x69\x75\x73\x3A\x20\x35\x70\x78\x3B\x0A\x7D\x0A\x2E\x74\x6F\x70\x62\x61\x72\x20\x2E\x6D\x65\x6E\x75\x20\x66\x6F\x72\x6D\x20\x7B\x0A\x20\x20\x64\x69\x73\x70\x6C\x61\x79\x3A\x20\x69\x6E\x6C\x69\x6E\x65\x2D\x62\x6C\x6F\x63\x6B\x3B\x0A\x7D\x0A\x0A\x2F\x2A\x20\x50\x61\x67\x65\x20\x2A\x2F\x0A\x0A\x2E\x70\x61\x67\x65\x20\x7B\x0A\x20\x20\x77\x69\x64\x74\x68\x3A\x20\x31\x30\x30\x25\x3B\x0A\x7D\x0A\x0A\x2E\x70\x61\x67\x65\x20\x3E\x20\x2E\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x2C\x0A\x2E\x74\x6F\x70\x62\x61\x72\x20\x3E\x20\x2E\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x2C\x0A\x2E\x66\x6F\x6F\x74\x65\x72\x20\x3E\x20\x2E\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x2D\x6C\x65\x66\x74\x3A\x20\x61\x75\x74\x6F\x3B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x2D\x72\x69\x67\x68\x74\x3A\x20\x61\x75\x74\x6F\x3B\x0A\x20\x20\x70\x61\x64\x64\x69\x6E\x67\x3A\x20\x30\x20\x31\x2E\x32\x35\x72\x65\x6D\x3B\x0A\x20\x20\x6D\x61\x78\x2D\x77\x69\x64\x74\x68\x3A\x20\x35\x39\x2E\x33\x38\x72\x65\x6D\x3B\x0A\x7D\x0A\x0A\x2E\x70\x61\x67\x65\x20\x3E\x20\x2E\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x20\x7B\x0A\x20\x20\x74\x65\x78\x74\x2D\x61\x6C\x69\x67\x6E\x3A\x20\x6C\x65\x66\x74\x3B\x0A\x7D\x0A\x0A\x2E\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x20\x2E\x6D\x65\x74\x61\x20\x7B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x73\x74\x79\x6C\x65\x3A\x20\x69\x74\x61\x6C\x69\x63\x3B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x31\x2E\x32\x35\x72\x65\x6D\x3B\x0A\x7D\x0A\x0A\x2E\x66\x6F\x6F\x74\x65\x72\x20\x7B\x0A\x20\x20\x74\x65\x78\x74\x2D\x61\x6C\x69\x67\x6E\x3A\x20\x63\x65\x6E\x74\x65\x72\x3B\x0A\x20\x20\x63\x6F\x6C\x6F\x72\x3A\x20\x23\x36\x36\x36\x3B\x0A\x20\x20\x66\x6F\x6E\x74\x2D\x73\x69\x7A\x65\x3A\x20\x30\x2E\x38\x37\x35\x72\x65\x6D\x3B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x32\x2E\x35\x72\x65\x6D\x20\x30\x3B\x0A\x7D\x0A\x0A\x2E\x75\x6C\x69\x73\x74\x20\x6C\x69\x20\x2E\x70\x61\x72\x61\x67\x72\x61\x70\x68\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x2D\x62\x6F\x74\x74\x6F\x6D\x3A\x20\x31\x65\x6D\x3B\x0A\x7D\x0A\x0A\x2E\x75\x6C\x69\x73\x74\x20\x6C\x69\x20\x2E\x70\x61\x72\x61\x67\x72\x61\x70\x68\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x2D\x62\x6F\x74\x74\x6F\x6D\x3A\x20\x31\x65\x6D\x3B\x0A\x7D\x0A\x0A\x2F\x2A\x20\x54\x4F\x43\x20\x20\x2A\x2F\x0A\x0A\x23\x74\x6F\x63\x20\x61\x20\x7B\x0A\x20\x20\x74\x65\x78\x74\x2D\x64\x65\x63\x6F\x72\x61\x74\x69\x6F\x6E\x3A\x20\x6E\x6F\x6E\x65\x3B\x0A\x7D\x0A\x23\x74\x6F\x63\x74\x69\x74\x6C\x65\x20\x7B\x0A\x20\x20\x64\x69\x73\x70\x6C\x61\x79\x3A\x20\x6E\x6F\x6E\x65\x3B\x0A\x7D\x0A\x23\x74\x6F\x63\x20\x6C\x69\x20\x7B\x0A\x20\x20\x6C\x69\x73\x74\x2D\x73\x74\x79\x6C\x65\x3A\x20\x6E\x6F\x6E\x65\x3B\x0A\x7D\x0A\x23\x74\x6F\x63\x20\x75\x6C\x20\x2E\x73\x65\x63\x74\x6C\x65\x76\x65\x6C\x31\x20\x7B\x0A\x20\x20\x70\x61\x64\x64\x69\x6E\x67\x3A\x20\x30\x70\x78\x3B\x0A\x7D\x0A\x23\x74\x6F\x63\x20\x75\x6C\x20\x2E\x73\x65\x63\x74\x6C\x65\x76\x65\x6C\x31\x2C\x0A\x23\x74\x6F\x63\x20\x75\x6C\x20\x2E\x73\x65\x63\x74\x6C\x65\x76\x65\x6C\x32\x2C\x0A\x23\x74\x6F\x63\x20\x75\x6C\x20\x2E\x73\x65\x63\x74\x6C\x65\x76\x65\x6C\x33\x2C\x0A\x23\x74\x6F\x63\x20\x75\x6C\x20\x2E\x73\x65\x63\x74\x6C\x65\x76\x65\x6C\x34\x2C\x0A\x23\x74\x6F\x63\x20\x75\x6C\x20\x2E\x73\x65\x63\x74\x6C\x65\x76\x65\x6C\x35\x20\x7B\x0A\x20\x20\x6D\x61\x72\x67\x69\x6E\x3A\x20\x34\x70\x78\x3B\x0A\x7D\x0A\x0A\x40\x6D\x65\x64\x69\x61\x20\x73\x63\x72\x65\x65\x6E\x20\x61\x6E\x64\x20\x28\x6D\x61\x78\x2D\x77\x69\x64\x74\x68\x3A\x20\x39\x39\x32\x70\x78\x29\x20\x7B\x0A\x20\x20\x23\x74\x6F\x63\x20\x7B\x0A\x20\x20\x20\x20\x61\x6C\x6C\x3A\x20\x75\x6E\x73\x65\x74\x3B\x0A\x20\x20\x7D\x0A\x7D\x0A"),
+ }
+ node.SetMode(0o644)
+ node.SetModTimeUnix(1769157703, 702881257)
+ node.SetName("ciigo.css")
+ node.SetSize(3789)
+ return node
+}
+
+func generate__static_index_gohtml() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "_static/index.gohtml",
+ Path: "/index.gohtml",
+ ContentType: "text/html; charset=utf-8",
+ GenFuncName: "generate__static_index_gohtml",
+ Content: []byte("\x3C\x21\x2D\x2D\x20\x53\x50\x44\x58\x2D\x4C\x69\x63\x65\x6E\x73\x65\x2D\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3A\x20\x47\x50\x4C\x2D\x33\x2E\x30\x2D\x6F\x72\x2D\x6C\x61\x74\x65\x72\x20\x2D\x2D\x3E\x0A\x3C\x21\x2D\x2D\x20\x53\x50\x44\x58\x2D\x46\x69\x6C\x65\x43\x6F\x70\x79\x72\x69\x67\x68\x74\x54\x65\x78\x74\x3A\x20\x32\x30\x32\x30\x20\x53\x68\x75\x6C\x68\x61\x6E\x20\x3C\x6D\x73\x40\x6B\x69\x6C\x61\x62\x69\x74\x2E\x69\x6E\x66\x6F\x3E\x20\x2D\x2D\x3E\x0A\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x68\x74\x6D\x6C\x3E\x0A\x3C\x68\x74\x6D\x6C\x3E\x0A\x20\x20\x3C\x68\x65\x61\x64\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x68\x74\x74\x70\x2D\x65\x71\x75\x69\x76\x3D\x22\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x74\x65\x78\x74\x2F\x68\x74\x6D\x6C\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x75\x74\x66\x2D\x38\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x76\x69\x65\x77\x70\x6F\x72\x74\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x77\x69\x64\x74\x68\x3D\x64\x65\x76\x69\x63\x65\x2D\x77\x69\x64\x74\x68\x2C\x20\x69\x6E\x69\x74\x69\x61\x6C\x2D\x73\x63\x61\x6C\x65\x3D\x31\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x74\x68\x65\x6D\x65\x2D\x63\x6F\x6C\x6F\x72\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x23\x33\x37\x35\x45\x41\x42\x22\x3E\x0A\x7B\x7B\x2D\x20\x72\x61\x6E\x67\x65\x20\x24\x6B\x2C\x20\x24\x76\x20\x3A\x3D\x20\x2E\x4D\x65\x74\x61\x64\x61\x74\x61\x7D\x7D\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x7B\x7B\x24\x6B\x7D\x7D\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x7B\x7B\x24\x76\x7D\x7D\x22\x3E\x0A\x7B\x7B\x2D\x20\x65\x6E\x64\x7D\x7D\x0A\x20\x20\x20\x20\x3C\x74\x69\x74\x6C\x65\x3E\x7B\x7B\x2E\x54\x69\x74\x6C\x65\x7D\x7D\x3C\x2F\x74\x69\x74\x6C\x65\x3E\x0A\x7B\x7B\x2D\x20\x69\x66\x20\x6E\x65\x20\x2E\x45\x6D\x62\x65\x64\x64\x65\x64\x43\x53\x53\x20\x22\x22\x7D\x7D\x0A\x20\x20\x20\x20\x3C\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x20\x20\x7B\x7B\x2E\x45\x6D\x62\x65\x64\x64\x65\x64\x43\x53\x53\x7D\x7D\x0A\x20\x20\x20\x20\x3C\x2F\x73\x74\x79\x6C\x65\x3E\x0A\x7B\x7B\x2D\x20\x65\x6E\x64\x7D\x7D\x0A\x7B\x7B\x2D\x20\x72\x61\x6E\x67\x65\x20\x2E\x53\x74\x79\x6C\x65\x73\x7D\x7D\x0A\x20\x20\x20\x20\x3C\x6C\x69\x6E\x6B\x20\x72\x65\x6C\x3D\x22\x73\x74\x79\x6C\x65\x73\x68\x65\x65\x74\x22\x20\x68\x72\x65\x66\x3D\x22\x7B\x7B\x2E\x7D\x7D\x22\x3E\x0A\x7B\x7B\x2D\x20\x65\x6E\x64\x7D\x7D\x0A\x20\x20\x3C\x2F\x68\x65\x61\x64\x3E\x0A\x20\x20\x3C\x62\x6F\x64\x79\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x62\x61\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x61\x20\x68\x72\x65\x66\x3D\x22\x2F\x22\x3E\x7B\x7B\x2E\x54\x69\x74\x6C\x65\x7D\x7D\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x6D\x65\x6E\x75\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x66\x6F\x72\x6D\x20\x63\x6C\x61\x73\x73\x3D\x22\x69\x74\x65\x6D\x22\x20\x61\x63\x74\x69\x6F\x6E\x3D\x22\x2F\x5F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x61\x72\x63\x68\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x69\x6E\x70\x75\x74\x20\x74\x79\x70\x65\x3D\x22\x74\x65\x78\x74\x22\x20\x6E\x61\x6D\x65\x3D\x22\x71\x22\x20\x70\x6C\x61\x63\x65\x68\x6F\x6C\x64\x65\x72\x3D\x22\x53\x65\x61\x72\x63\x68\x22\x20\x2F\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x66\x6F\x72\x6D\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x70\x61\x67\x65\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x7B\x7B\x2E\x42\x6F\x64\x79\x7D\x7D\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x50\x6F\x77\x65\x72\x65\x64\x20\x62\x79\x20\x3C\x61\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x68\x72\x65\x66\x3D\x22\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x69\x74\x2E\x73\x72\x2E\x68\x74\x2F\x7E\x73\x68\x75\x6C\x68\x61\x6E\x2F\x63\x69\x69\x67\x6F\x22\x0A\x20\x20\x20\x20\x20\x20\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x63\x69\x69\x67\x6F\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x3C\x2F\x62\x6F\x64\x79\x3E\x0A\x3C\x2F\x68\x74\x6D\x6C\x3E\x0A\x3C\x21\x2D\x2D\x20\x76\x69\x6D\x3A\x20\x73\x65\x74\x20\x66\x69\x6C\x65\x74\x79\x70\x65\x3D\x61\x6E\x67\x75\x6C\x61\x72\x3A\x20\x2D\x2D\x3E\x0A"),
+ }
+ node.SetMode(0o644)
+ node.SetModTimeUnix(1769168980, 413409444)
+ node.SetName("index.gohtml")
+ node.SetSize(1252)
+ return node
+}
+
+// _staticfs_getNode is internal function to minimize duplicate node
+// created on Node.AddChild() and on generatedPathNode.Set().
+func _staticfs_getNode(mfs *memfs.MemFS, path string, fn func() *memfs.Node) (node *memfs.Node) {
+ node = mfs.PathNodes.Get(path)
+ if node != nil {
+ return node
+ }
+ return fn()
+}
+
+func init() {
+ staticfs = &memfs.MemFS{
+ PathNodes: memfs.NewPathNode(),
+ Opts: &memfs.Options{
+ Root: "./_static",
+ MaxFileSize: 5242880,
+ Includes: []string{
+ },
+ Excludes: []string{
+ },
+ Embed: memfs.EmbedOptions{
+ CommentHeader: `// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2026 Shulhan <ms@kilabit.info>
+
+`,
+ PackageName: "ciigo",
+ VarName: "staticfs",
+ GoFileName: "staticfs.go",
+ WithoutModTime: false,
+ },
+ },
+ }
+ staticfs.PathNodes.Set("/",
+ _staticfs_getNode(staticfs, "/", generate____static))
+ staticfs.PathNodes.Set("/ciigo.css",
+ _staticfs_getNode(staticfs, "/ciigo.css", generate__static_ciigo_css))
+ staticfs.PathNodes.Set("/index.gohtml",
+ _staticfs_getNode(staticfs, "/index.gohtml", generate__static_index_gohtml))
+
+ staticfs.Root = staticfs.PathNodes.Get("/")
+
+ var err = staticfs.Init()
+ if err != nil {
+ panic("staticfs: " + err.Error())
+ }
+}
diff --git a/template_index_html.go b/template_index_html.go
deleted file mode 100644
index 8b43083..0000000
--- a/template_index_html.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// SPDX-FileCopyrightText: 2020 Shulhan <ms@kilabit.info>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package ciigo
-
-const templateIndexHTML = `<!DOCTYPE html>
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="theme-color" content="#375EAB">
-{{- range $k, $v := .Metadata}}
- <meta name="{{$k}}" content="{{$v}}">
-{{- end}}
- <title>{{.Title}}</title>
-{{- if .EmbeddedCSS}}
- <style>
- {{.EmbeddedCSS}}
- </style>
-{{- end}}
-{{- range .Styles}}
- <link rel="stylesheet" href="{{.}}">
-{{- end}}
- </head>
- <body>
- <div class="topbar">
- <div class="container">
- <div class="top-heading">
- <a href="/">{{.Title}}</a>
- </div>
- <div class="menu">
- <form class="item" action="/_internal/search">
- <input type="text" name="q" placeholder="Search" />
- </form>
- </div>
- </div>
- </div>
- <div class="page">
- <div class="container">
-{{.Body}}
- </div>
- </div>
- <div class="footer">
- Powered by <a
- href="https://git.sr.ht/~shulhan/ciigo"
- >
- ciigo
- </a>
- </div>
- </body>
-</html>`
diff --git a/testdata/goembed/GoEmbed_test.txt b/testdata/goembed/GoEmbed_test.txt
deleted file mode 100644
index d800731..0000000
--- a/testdata/goembed/GoEmbed_test.txt
+++ /dev/null
@@ -1,131 +0,0 @@
-
-<<< default.go
-// Code generated by git.sr.ht/~shulhan/pakakeh.go/lib/memfs DO NOT EDIT.
-
-package mypackage
-
-import (
- "git.sr.ht/~shulhan/pakakeh.go/lib/memfs"
-)
-
-func generate_testdata_in() *memfs.Node {
- var node = &memfs.Node{
- SysPath: "testdata/in",
- Path: "/",
- ContentType: "",
- GenFuncName: "generate_testdata_in",
- }
- node.SetMode(0o20000000755)
- node.SetName("/")
- node.SetSize(0)
- node.AddChild(_memfsIn_getNode(memfsIn, "/clu", generate_testdata_in_clu))
- return node
-}
-
-func generate_testdata_in_clu() *memfs.Node {
- var node = &memfs.Node{
- SysPath: "testdata/in/clu",
- Path: "/clu",
- ContentType: "",
- GenFuncName: "generate_testdata_in_clu",
- }
- node.SetMode(0o20000000755)
- node.SetName("clu")
- node.SetSize(0)
- node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de", generate_testdata_in_clu_de))
- return node
-}
-
-func generate_testdata_in_clu_de() *memfs.Node {
- var node = &memfs.Node{
- SysPath: "testdata/in/clu/de",
- Path: "/clu/de",
- ContentType: "",
- GenFuncName: "generate_testdata_in_clu_de",
- }
- node.SetMode(0o20000000755)
- node.SetName("de")
- node.SetSize(0)
- node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de/file.html", generate_testdata_in_clu_de_file_html))
- node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de/markdown.html", generate_testdata_in_clu_de_markdown_html))
- return node
-}
-
-func generate_testdata_in_clu_de_file_html() *memfs.Node {
- var node = &memfs.Node{
- SysPath: "testdata/in/clu/de/file.html",
- Path: "/clu/de/file.html",
- ContentType: "text/html; charset=utf-8",
- GenFuncName: "generate_testdata_in_clu_de_file_html",
- Content: []byte("\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x68\x74\x6D\x6C\x3E\x0A\x3C\x68\x74\x6D\x6C\x3E\x0A\x09\x3C\x68\x65\x61\x64\x3E\x0A\x09\x09\x3C\x6D\x65\x74\x61\x20\x68\x74\x74\x70\x2D\x65\x71\x75\x69\x76\x3D\x22\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x74\x65\x78\x74\x2F\x68\x74\x6D\x6C\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x75\x74\x66\x2D\x38\x22\x3E\x0A\x09\x09\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x76\x69\x65\x77\x70\x6F\x72\x74\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x77\x69\x64\x74\x68\x3D\x64\x65\x76\x69\x63\x65\x2D\x77\x69\x64\x74\x68\x2C\x20\x69\x6E\x69\x74\x69\x61\x6C\x2D\x73\x63\x61\x6C\x65\x3D\x31\x22\x3E\x0A\x09\x09\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x74\x68\x65\x6D\x65\x2D\x63\x6F\x6C\x6F\x72\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x23\x33\x37\x35\x45\x41\x42\x22\x3E\x0A\x09\x09\x3C\x74\x69\x74\x6C\x65\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x74\x69\x74\x6C\x65\x3E\x0A\x09\x09\x3C\x73\x74\x79\x6C\x65\x3E\x0A\x09\x09\x62\x6F\x64\x79\x7B\x7D\x0A\x09\x09\x3C\x2F\x73\x74\x79\x6C\x65\x3E\x0A\x09\x3C\x2F\x68\x65\x61\x64\x3E\x0A\x09\x3C\x62\x6F\x64\x79\x3E\x0A\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x62\x61\x72\x22\x3E\x0A\x09\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x09\x09\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x22\x3E\x0A\x09\x09\x09\x09\x09\x3C\x61\x20\x68\x72\x65\x66\x3D\x22\x2F\x22\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x61\x3E\x0A\x09\x09\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x6D\x65\x6E\x75\x22\x3E\x0A\x09\x09\x09\x09\x09\x3C\x66\x6F\x72\x6D\x20\x63\x6C\x61\x73\x73\x3D\x22\x69\x74\x65\x6D\x22\x20\x61\x63\x74\x69\x6F\x6E\x3D\x22\x2F\x5F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x61\x72\x63\x68\x22\x3E\x0A\x09\x09\x09\x09\x09\x09\x3C\x69\x6E\x70\x75\x74\x20\x74\x79\x70\x65\x3D\x22\x74\x65\x78\x74\x22\x20\x6E\x61\x6D\x65\x3D\x22\x71\x22\x20\x70\x6C\x61\x63\x65\x68\x6F\x6C\x64\x65\x72\x3D\x22\x53\x65\x61\x72\x63\x68\x22\x20\x2F\x3E\x0A\x09\x09\x09\x09\x09\x3C\x2F\x66\x6F\x72\x6D\x3E\x0A\x09\x09\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x70\x61\x67\x65\x22\x3E\x0A\x09\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x68\x65\x61\x64\x65\x72\x22\x3E\x0A\x3C\x68\x31\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x68\x31\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x63\x6F\x6E\x74\x65\x6E\x74\x22\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x66\x6F\x6F\x74\x65\x72\x2D\x74\x65\x78\x74\x22\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x09\x09\x09\x50\x6F\x77\x65\x72\x65\x64\x20\x62\x79\x20\x3C\x61\x0A\x09\x09\x09\x09\x68\x72\x65\x66\x3D\x22\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x69\x74\x2E\x73\x72\x2E\x68\x74\x2F\x7E\x73\x68\x75\x6C\x68\x61\x6E\x2F\x63\x69\x69\x67\x6F\x22\x0A\x09\x09\x09\x3E\x0A\x09\x09\x09\x09\x63\x69\x69\x67\x6F\x0A\x09\x09\x09\x3C\x2F\x61\x3E\x0A\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x3C\x2F\x62\x6F\x64\x79\x3E\x0A\x3C\x2F\x68\x74\x6D\x6C\x3E"),
- }
- node.SetMode(0o644)
- node.SetName("file.html")
- node.SetSize(902)
- return node
-}
-
-func generate_testdata_in_clu_de_markdown_html() *memfs.Node {
- var node = &memfs.Node{
- SysPath: "testdata/in/clu/de/markdown.html",
- Path: "/clu/de/markdown.html",
- ContentType: "text/html; charset=utf-8",
- GenFuncName: "generate_testdata_in_clu_de_markdown_html",
- Content: []byte("\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x68\x74\x6D\x6C\x3E\x0A\x3C\x68\x74\x6D\x6C\x3E\x0A\x09\x3C\x68\x65\x61\x64\x3E\x0A\x09\x09\x3C\x6D\x65\x74\x61\x20\x68\x74\x74\x70\x2D\x65\x71\x75\x69\x76\x3D\x22\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x74\x65\x78\x74\x2F\x68\x74\x6D\x6C\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x75\x74\x66\x2D\x38\x22\x3E\x0A\x09\x09\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x76\x69\x65\x77\x70\x6F\x72\x74\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x77\x69\x64\x74\x68\x3D\x64\x65\x76\x69\x63\x65\x2D\x77\x69\x64\x74\x68\x2C\x20\x69\x6E\x69\x74\x69\x61\x6C\x2D\x73\x63\x61\x6C\x65\x3D\x31\x22\x3E\x0A\x09\x09\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x74\x68\x65\x6D\x65\x2D\x63\x6F\x6C\x6F\x72\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x23\x33\x37\x35\x45\x41\x42\x22\x3E\x0A\x09\x09\x3C\x74\x69\x74\x6C\x65\x3E\x3C\x2F\x74\x69\x74\x6C\x65\x3E\x0A\x09\x09\x3C\x73\x74\x79\x6C\x65\x3E\x0A\x09\x09\x62\x6F\x64\x79\x7B\x7D\x0A\x09\x09\x3C\x2F\x73\x74\x79\x6C\x65\x3E\x0A\x09\x3C\x2F\x68\x65\x61\x64\x3E\x0A\x09\x3C\x62\x6F\x64\x79\x3E\x0A\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x62\x61\x72\x22\x3E\x0A\x09\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x09\x09\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x22\x3E\x0A\x09\x09\x09\x09\x09\x3C\x61\x20\x68\x72\x65\x66\x3D\x22\x2F\x22\x3E\x3C\x2F\x61\x3E\x0A\x09\x09\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x6D\x65\x6E\x75\x22\x3E\x0A\x09\x09\x09\x09\x09\x3C\x66\x6F\x72\x6D\x20\x63\x6C\x61\x73\x73\x3D\x22\x69\x74\x65\x6D\x22\x20\x61\x63\x74\x69\x6F\x6E\x3D\x22\x2F\x5F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x61\x72\x63\x68\x22\x3E\x0A\x09\x09\x09\x09\x09\x09\x3C\x69\x6E\x70\x75\x74\x20\x74\x79\x70\x65\x3D\x22\x74\x65\x78\x74\x22\x20\x6E\x61\x6D\x65\x3D\x22\x71\x22\x20\x70\x6C\x61\x63\x65\x68\x6F\x6C\x64\x65\x72\x3D\x22\x53\x65\x61\x72\x63\x68\x22\x20\x2F\x3E\x0A\x09\x09\x09\x09\x09\x3C\x2F\x66\x6F\x72\x6D\x3E\x0A\x09\x09\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x70\x61\x67\x65\x22\x3E\x0A\x09\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x3C\x68\x31\x3E\x6D\x61\x72\x6B\x64\x6F\x77\x6E\x3C\x2F\x68\x31\x3E\x0A\x0A\x09\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x09\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x09\x09\x09\x50\x6F\x77\x65\x72\x65\x64\x20\x62\x79\x20\x3C\x61\x0A\x09\x09\x09\x09\x68\x72\x65\x66\x3D\x22\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x69\x74\x2E\x73\x72\x2E\x68\x74\x2F\x7E\x73\x68\x75\x6C\x68\x61\x6E\x2F\x63\x69\x69\x67\x6F\x22\x0A\x09\x09\x09\x3E\x0A\x09\x09\x09\x09\x63\x69\x69\x67\x6F\x0A\x09\x09\x09\x3C\x2F\x61\x3E\x0A\x09\x09\x3C\x2F\x64\x69\x76\x3E\x0A\x09\x3C\x2F\x62\x6F\x64\x79\x3E\x0A\x3C\x2F\x68\x74\x6D\x6C\x3E"),
- }
- node.SetMode(0o644)
- node.SetName("markdown.html")
- node.SetSize(790)
- return node
-}
-
-// _memfsIn_getNode is internal function to minimize duplicate node
-// created on Node.AddChild() and on generatedPathNode.Set().
-func _memfsIn_getNode(mfs *memfs.MemFS, path string, fn func() *memfs.Node) (node *memfs.Node) {
- node = mfs.PathNodes.Get(path)
- if node != nil {
- return node
- }
- return fn()
-}
-
-func init() {
- memfsIn = &memfs.MemFS{
- PathNodes: memfs.NewPathNode(),
- Opts: &memfs.Options{
- Root: "testdata/in",
- MaxFileSize: 5242880,
- Includes: []string{
- },
- Excludes: []string{
- `.*\.adoc$`,
- `.*\.md$`,
- `^\..*`,
- },
- Embed: memfs.EmbedOptions{
- CommentHeader: ``,
- PackageName: "mypackage",
- VarName: "memfsIn",
- GoFileName: "testdata/goembed/out/default.go",
- WithoutModTime: true,
- },
- },
- }
- memfsIn.PathNodes.Set("/",
- _memfsIn_getNode(memfsIn, "/", generate_testdata_in))
- memfsIn.PathNodes.Set("/clu",
- _memfsIn_getNode(memfsIn, "/clu", generate_testdata_in_clu))
- memfsIn.PathNodes.Set("/clu/de",
- _memfsIn_getNode(memfsIn, "/clu/de", generate_testdata_in_clu_de))
- memfsIn.PathNodes.Set("/clu/de/file.html",
- _memfsIn_getNode(memfsIn, "/clu/de/file.html", generate_testdata_in_clu_de_file_html))
- memfsIn.PathNodes.Set("/clu/de/markdown.html",
- _memfsIn_getNode(memfsIn, "/clu/de/markdown.html", generate_testdata_in_clu_de_markdown_html))
-
- memfsIn.Root = memfsIn.PathNodes.Get("/")
-
- var err = memfsIn.Init()
- if err != nil {
- panic("memfsIn: " + err.Error())
- }
-}
diff --git a/testdata/goembed/default.go b/testdata/goembed/default.go
new file mode 100644
index 0000000..6f42697
--- /dev/null
+++ b/testdata/goembed/default.go
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2026 Shulhan <ms@kilabit.info>
+// Code generated by git.sr.ht/~shulhan/pakakeh.go/lib/memfs DO NOT EDIT.
+
+package mypackage
+
+import (
+ "git.sr.ht/~shulhan/pakakeh.go/lib/memfs"
+)
+
+func generate_testdata_in() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in",
+ Path: "/",
+ ContentType: "",
+ GenFuncName: "generate_testdata_in",
+ }
+ node.SetMode(0o20000000755)
+ node.SetName("/")
+ node.SetSize(0)
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu", generate_testdata_in_clu))
+ return node
+}
+
+func generate_testdata_in_clu() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu",
+ Path: "/clu",
+ ContentType: "",
+ GenFuncName: "generate_testdata_in_clu",
+ }
+ node.SetMode(0o20000000755)
+ node.SetName("clu")
+ node.SetSize(0)
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de", generate_testdata_in_clu_de))
+ return node
+}
+
+func generate_testdata_in_clu_de() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu/de",
+ Path: "/clu/de",
+ ContentType: "",
+ GenFuncName: "generate_testdata_in_clu_de",
+ }
+ node.SetMode(0o20000000755)
+ node.SetName("de")
+ node.SetSize(0)
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de/file.html", generate_testdata_in_clu_de_file_html))
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de/markdown.html", generate_testdata_in_clu_de_markdown_html))
+ return node
+}
+
+func generate_testdata_in_clu_de_file_html() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu/de/file.html",
+ Path: "/clu/de/file.html",
+ ContentType: "text/html; charset=utf-8",
+ GenFuncName: "generate_testdata_in_clu_de_file_html",
+ Content: []byte("\x0A\x0A\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x68\x74\x6D\x6C\x3E\x0A\x3C\x68\x74\x6D\x6C\x3E\x0A\x20\x20\x3C\x68\x65\x61\x64\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x68\x74\x74\x70\x2D\x65\x71\x75\x69\x76\x3D\x22\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x74\x65\x78\x74\x2F\x68\x74\x6D\x6C\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x75\x74\x66\x2D\x38\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x76\x69\x65\x77\x70\x6F\x72\x74\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x77\x69\x64\x74\x68\x3D\x64\x65\x76\x69\x63\x65\x2D\x77\x69\x64\x74\x68\x2C\x20\x69\x6E\x69\x74\x69\x61\x6C\x2D\x73\x63\x61\x6C\x65\x3D\x31\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x74\x68\x65\x6D\x65\x2D\x63\x6F\x6C\x6F\x72\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x23\x33\x37\x35\x45\x41\x42\x22\x3E\x0A\x20\x20\x20\x20\x3C\x74\x69\x74\x6C\x65\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x74\x69\x74\x6C\x65\x3E\x0A\x20\x20\x20\x20\x3C\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x20\x20\x62\x6F\x64\x79\x7B\x7D\x0A\x20\x20\x20\x20\x3C\x2F\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x3C\x2F\x68\x65\x61\x64\x3E\x0A\x20\x20\x3C\x62\x6F\x64\x79\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x62\x61\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x61\x20\x68\x72\x65\x66\x3D\x22\x2F\x22\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x6D\x65\x6E\x75\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x66\x6F\x72\x6D\x20\x63\x6C\x61\x73\x73\x3D\x22\x69\x74\x65\x6D\x22\x20\x61\x63\x74\x69\x6F\x6E\x3D\x22\x2F\x5F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x61\x72\x63\x68\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x69\x6E\x70\x75\x74\x20\x74\x79\x70\x65\x3D\x22\x74\x65\x78\x74\x22\x20\x6E\x61\x6D\x65\x3D\x22\x71\x22\x20\x70\x6C\x61\x63\x65\x68\x6F\x6C\x64\x65\x72\x3D\x22\x53\x65\x61\x72\x63\x68\x22\x20\x2F\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x66\x6F\x72\x6D\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x70\x61\x67\x65\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x68\x65\x61\x64\x65\x72\x22\x3E\x0A\x3C\x68\x31\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x68\x31\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x63\x6F\x6E\x74\x65\x6E\x74\x22\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x66\x6F\x6F\x74\x65\x72\x2D\x74\x65\x78\x74\x22\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x50\x6F\x77\x65\x72\x65\x64\x20\x62\x79\x20\x3C\x61\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x68\x72\x65\x66\x3D\x22\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x69\x74\x2E\x73\x72\x2E\x68\x74\x2F\x7E\x73\x68\x75\x6C\x68\x61\x6E\x2F\x63\x69\x69\x67\x6F\x22\x0A\x20\x20\x20\x20\x20\x20\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x63\x69\x69\x67\x6F\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x3C\x2F\x62\x6F\x64\x79\x3E\x0A\x3C\x2F\x68\x74\x6D\x6C\x3E\x0A\x0A"),
+ }
+ node.SetMode(0o644)
+ node.SetName("file.html")
+ node.SetSize(1002)
+ return node
+}
+
+func generate_testdata_in_clu_de_markdown_html() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu/de/markdown.html",
+ Path: "/clu/de/markdown.html",
+ ContentType: "text/html; charset=utf-8",
+ GenFuncName: "generate_testdata_in_clu_de_markdown_html",
+ Content: []byte("\x0A\x0A\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x68\x74\x6D\x6C\x3E\x0A\x3C\x68\x74\x6D\x6C\x3E\x0A\x20\x20\x3C\x68\x65\x61\x64\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x68\x74\x74\x70\x2D\x65\x71\x75\x69\x76\x3D\x22\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x74\x65\x78\x74\x2F\x68\x74\x6D\x6C\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x75\x74\x66\x2D\x38\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x76\x69\x65\x77\x70\x6F\x72\x74\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x77\x69\x64\x74\x68\x3D\x64\x65\x76\x69\x63\x65\x2D\x77\x69\x64\x74\x68\x2C\x20\x69\x6E\x69\x74\x69\x61\x6C\x2D\x73\x63\x61\x6C\x65\x3D\x31\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x74\x68\x65\x6D\x65\x2D\x63\x6F\x6C\x6F\x72\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x23\x33\x37\x35\x45\x41\x42\x22\x3E\x0A\x20\x20\x20\x20\x3C\x74\x69\x74\x6C\x65\x3E\x3C\x2F\x74\x69\x74\x6C\x65\x3E\x0A\x20\x20\x20\x20\x3C\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x20\x20\x62\x6F\x64\x79\x7B\x7D\x0A\x20\x20\x20\x20\x3C\x2F\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x3C\x2F\x68\x65\x61\x64\x3E\x0A\x20\x20\x3C\x62\x6F\x64\x79\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x62\x61\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x61\x20\x68\x72\x65\x66\x3D\x22\x2F\x22\x3E\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x6D\x65\x6E\x75\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x66\x6F\x72\x6D\x20\x63\x6C\x61\x73\x73\x3D\x22\x69\x74\x65\x6D\x22\x20\x61\x63\x74\x69\x6F\x6E\x3D\x22\x2F\x5F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x61\x72\x63\x68\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x69\x6E\x70\x75\x74\x20\x74\x79\x70\x65\x3D\x22\x74\x65\x78\x74\x22\x20\x6E\x61\x6D\x65\x3D\x22\x71\x22\x20\x70\x6C\x61\x63\x65\x68\x6F\x6C\x64\x65\x72\x3D\x22\x53\x65\x61\x72\x63\x68\x22\x20\x2F\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x66\x6F\x72\x6D\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x70\x61\x67\x65\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x3C\x68\x31\x3E\x6D\x61\x72\x6B\x64\x6F\x77\x6E\x3C\x2F\x68\x31\x3E\x0A\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x50\x6F\x77\x65\x72\x65\x64\x20\x62\x79\x20\x3C\x61\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x68\x72\x65\x66\x3D\x22\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x69\x74\x2E\x73\x72\x2E\x68\x74\x2F\x7E\x73\x68\x75\x6C\x68\x61\x6E\x2F\x63\x69\x69\x67\x6F\x22\x0A\x20\x20\x20\x20\x20\x20\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x63\x69\x69\x67\x6F\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x3C\x2F\x62\x6F\x64\x79\x3E\x0A\x3C\x2F\x68\x74\x6D\x6C\x3E\x0A\x0A"),
+ }
+ node.SetMode(0o644)
+ node.SetName("markdown.html")
+ node.SetSize(890)
+ return node
+}
+
+// _memfsIn_getNode is internal function to minimize duplicate node
+// created on Node.AddChild() and on generatedPathNode.Set().
+func _memfsIn_getNode(mfs *memfs.MemFS, path string, fn func() *memfs.Node) (node *memfs.Node) {
+ node = mfs.PathNodes.Get(path)
+ if node != nil {
+ return node
+ }
+ return fn()
+}
+
+func init() {
+ memfsIn = &memfs.MemFS{
+ PathNodes: memfs.NewPathNode(),
+ Opts: &memfs.Options{
+ Root: "testdata/in",
+ MaxFileSize: 5242880,
+ Includes: []string{
+ },
+ Excludes: []string{
+ `.*\.adoc$`,
+ `.*\.md$`,
+ `^\..*`,
+ },
+ Embed: memfs.EmbedOptions{
+ CommentHeader: `// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2026 Shulhan <ms@kilabit.info>
+`,
+ PackageName: "mypackage",
+ VarName: "memfsIn",
+ GoFileName: "testdata/goembed/default.go",
+ WithoutModTime: true,
+ },
+ },
+ }
+ memfsIn.PathNodes.Set("/",
+ _memfsIn_getNode(memfsIn, "/", generate_testdata_in))
+ memfsIn.PathNodes.Set("/clu",
+ _memfsIn_getNode(memfsIn, "/clu", generate_testdata_in_clu))
+ memfsIn.PathNodes.Set("/clu/de",
+ _memfsIn_getNode(memfsIn, "/clu/de", generate_testdata_in_clu_de))
+ memfsIn.PathNodes.Set("/clu/de/file.html",
+ _memfsIn_getNode(memfsIn, "/clu/de/file.html", generate_testdata_in_clu_de_file_html))
+ memfsIn.PathNodes.Set("/clu/de/markdown.html",
+ _memfsIn_getNode(memfsIn, "/clu/de/markdown.html", generate_testdata_in_clu_de_markdown_html))
+
+ memfsIn.Root = memfsIn.PathNodes.Get("/")
+
+ var err = memfsIn.Init()
+ if err != nil {
+ panic("memfsIn: " + err.Error())
+ }
+}
diff --git a/testdata/goembed/default.go.exp b/testdata/goembed/default.go.exp
new file mode 100644
index 0000000..6f42697
--- /dev/null
+++ b/testdata/goembed/default.go.exp
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2026 Shulhan <ms@kilabit.info>
+// Code generated by git.sr.ht/~shulhan/pakakeh.go/lib/memfs DO NOT EDIT.
+
+package mypackage
+
+import (
+ "git.sr.ht/~shulhan/pakakeh.go/lib/memfs"
+)
+
+func generate_testdata_in() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in",
+ Path: "/",
+ ContentType: "",
+ GenFuncName: "generate_testdata_in",
+ }
+ node.SetMode(0o20000000755)
+ node.SetName("/")
+ node.SetSize(0)
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu", generate_testdata_in_clu))
+ return node
+}
+
+func generate_testdata_in_clu() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu",
+ Path: "/clu",
+ ContentType: "",
+ GenFuncName: "generate_testdata_in_clu",
+ }
+ node.SetMode(0o20000000755)
+ node.SetName("clu")
+ node.SetSize(0)
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de", generate_testdata_in_clu_de))
+ return node
+}
+
+func generate_testdata_in_clu_de() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu/de",
+ Path: "/clu/de",
+ ContentType: "",
+ GenFuncName: "generate_testdata_in_clu_de",
+ }
+ node.SetMode(0o20000000755)
+ node.SetName("de")
+ node.SetSize(0)
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de/file.html", generate_testdata_in_clu_de_file_html))
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de/markdown.html", generate_testdata_in_clu_de_markdown_html))
+ return node
+}
+
+func generate_testdata_in_clu_de_file_html() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu/de/file.html",
+ Path: "/clu/de/file.html",
+ ContentType: "text/html; charset=utf-8",
+ GenFuncName: "generate_testdata_in_clu_de_file_html",
+ Content: []byte("\x0A\x0A\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x68\x74\x6D\x6C\x3E\x0A\x3C\x68\x74\x6D\x6C\x3E\x0A\x20\x20\x3C\x68\x65\x61\x64\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x68\x74\x74\x70\x2D\x65\x71\x75\x69\x76\x3D\x22\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x74\x65\x78\x74\x2F\x68\x74\x6D\x6C\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x75\x74\x66\x2D\x38\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x76\x69\x65\x77\x70\x6F\x72\x74\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x77\x69\x64\x74\x68\x3D\x64\x65\x76\x69\x63\x65\x2D\x77\x69\x64\x74\x68\x2C\x20\x69\x6E\x69\x74\x69\x61\x6C\x2D\x73\x63\x61\x6C\x65\x3D\x31\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x74\x68\x65\x6D\x65\x2D\x63\x6F\x6C\x6F\x72\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x23\x33\x37\x35\x45\x41\x42\x22\x3E\x0A\x20\x20\x20\x20\x3C\x74\x69\x74\x6C\x65\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x74\x69\x74\x6C\x65\x3E\x0A\x20\x20\x20\x20\x3C\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x20\x20\x62\x6F\x64\x79\x7B\x7D\x0A\x20\x20\x20\x20\x3C\x2F\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x3C\x2F\x68\x65\x61\x64\x3E\x0A\x20\x20\x3C\x62\x6F\x64\x79\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x62\x61\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x61\x20\x68\x72\x65\x66\x3D\x22\x2F\x22\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x6D\x65\x6E\x75\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x66\x6F\x72\x6D\x20\x63\x6C\x61\x73\x73\x3D\x22\x69\x74\x65\x6D\x22\x20\x61\x63\x74\x69\x6F\x6E\x3D\x22\x2F\x5F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x61\x72\x63\x68\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x69\x6E\x70\x75\x74\x20\x74\x79\x70\x65\x3D\x22\x74\x65\x78\x74\x22\x20\x6E\x61\x6D\x65\x3D\x22\x71\x22\x20\x70\x6C\x61\x63\x65\x68\x6F\x6C\x64\x65\x72\x3D\x22\x53\x65\x61\x72\x63\x68\x22\x20\x2F\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x66\x6F\x72\x6D\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x70\x61\x67\x65\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x68\x65\x61\x64\x65\x72\x22\x3E\x0A\x3C\x68\x31\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x68\x31\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x63\x6F\x6E\x74\x65\x6E\x74\x22\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x66\x6F\x6F\x74\x65\x72\x2D\x74\x65\x78\x74\x22\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x50\x6F\x77\x65\x72\x65\x64\x20\x62\x79\x20\x3C\x61\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x68\x72\x65\x66\x3D\x22\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x69\x74\x2E\x73\x72\x2E\x68\x74\x2F\x7E\x73\x68\x75\x6C\x68\x61\x6E\x2F\x63\x69\x69\x67\x6F\x22\x0A\x20\x20\x20\x20\x20\x20\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x63\x69\x69\x67\x6F\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x3C\x2F\x62\x6F\x64\x79\x3E\x0A\x3C\x2F\x68\x74\x6D\x6C\x3E\x0A\x0A"),
+ }
+ node.SetMode(0o644)
+ node.SetName("file.html")
+ node.SetSize(1002)
+ return node
+}
+
+func generate_testdata_in_clu_de_markdown_html() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu/de/markdown.html",
+ Path: "/clu/de/markdown.html",
+ ContentType: "text/html; charset=utf-8",
+ GenFuncName: "generate_testdata_in_clu_de_markdown_html",
+ Content: []byte("\x0A\x0A\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x68\x74\x6D\x6C\x3E\x0A\x3C\x68\x74\x6D\x6C\x3E\x0A\x20\x20\x3C\x68\x65\x61\x64\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x68\x74\x74\x70\x2D\x65\x71\x75\x69\x76\x3D\x22\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x74\x65\x78\x74\x2F\x68\x74\x6D\x6C\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x75\x74\x66\x2D\x38\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x76\x69\x65\x77\x70\x6F\x72\x74\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x77\x69\x64\x74\x68\x3D\x64\x65\x76\x69\x63\x65\x2D\x77\x69\x64\x74\x68\x2C\x20\x69\x6E\x69\x74\x69\x61\x6C\x2D\x73\x63\x61\x6C\x65\x3D\x31\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x74\x68\x65\x6D\x65\x2D\x63\x6F\x6C\x6F\x72\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x23\x33\x37\x35\x45\x41\x42\x22\x3E\x0A\x20\x20\x20\x20\x3C\x74\x69\x74\x6C\x65\x3E\x3C\x2F\x74\x69\x74\x6C\x65\x3E\x0A\x20\x20\x20\x20\x3C\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x20\x20\x62\x6F\x64\x79\x7B\x7D\x0A\x20\x20\x20\x20\x3C\x2F\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x3C\x2F\x68\x65\x61\x64\x3E\x0A\x20\x20\x3C\x62\x6F\x64\x79\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x62\x61\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x61\x20\x68\x72\x65\x66\x3D\x22\x2F\x22\x3E\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x6D\x65\x6E\x75\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x66\x6F\x72\x6D\x20\x63\x6C\x61\x73\x73\x3D\x22\x69\x74\x65\x6D\x22\x20\x61\x63\x74\x69\x6F\x6E\x3D\x22\x2F\x5F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x61\x72\x63\x68\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x69\x6E\x70\x75\x74\x20\x74\x79\x70\x65\x3D\x22\x74\x65\x78\x74\x22\x20\x6E\x61\x6D\x65\x3D\x22\x71\x22\x20\x70\x6C\x61\x63\x65\x68\x6F\x6C\x64\x65\x72\x3D\x22\x53\x65\x61\x72\x63\x68\x22\x20\x2F\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x66\x6F\x72\x6D\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x70\x61\x67\x65\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x3C\x68\x31\x3E\x6D\x61\x72\x6B\x64\x6F\x77\x6E\x3C\x2F\x68\x31\x3E\x0A\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x50\x6F\x77\x65\x72\x65\x64\x20\x62\x79\x20\x3C\x61\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x68\x72\x65\x66\x3D\x22\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x69\x74\x2E\x73\x72\x2E\x68\x74\x2F\x7E\x73\x68\x75\x6C\x68\x61\x6E\x2F\x63\x69\x69\x67\x6F\x22\x0A\x20\x20\x20\x20\x20\x20\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x63\x69\x69\x67\x6F\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x3C\x2F\x62\x6F\x64\x79\x3E\x0A\x3C\x2F\x68\x74\x6D\x6C\x3E\x0A\x0A"),
+ }
+ node.SetMode(0o644)
+ node.SetName("markdown.html")
+ node.SetSize(890)
+ return node
+}
+
+// _memfsIn_getNode is internal function to minimize duplicate node
+// created on Node.AddChild() and on generatedPathNode.Set().
+func _memfsIn_getNode(mfs *memfs.MemFS, path string, fn func() *memfs.Node) (node *memfs.Node) {
+ node = mfs.PathNodes.Get(path)
+ if node != nil {
+ return node
+ }
+ return fn()
+}
+
+func init() {
+ memfsIn = &memfs.MemFS{
+ PathNodes: memfs.NewPathNode(),
+ Opts: &memfs.Options{
+ Root: "testdata/in",
+ MaxFileSize: 5242880,
+ Includes: []string{
+ },
+ Excludes: []string{
+ `.*\.adoc$`,
+ `.*\.md$`,
+ `^\..*`,
+ },
+ Embed: memfs.EmbedOptions{
+ CommentHeader: `// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2026 Shulhan <ms@kilabit.info>
+`,
+ PackageName: "mypackage",
+ VarName: "memfsIn",
+ GoFileName: "testdata/goembed/default.go",
+ WithoutModTime: true,
+ },
+ },
+ }
+ memfsIn.PathNodes.Set("/",
+ _memfsIn_getNode(memfsIn, "/", generate_testdata_in))
+ memfsIn.PathNodes.Set("/clu",
+ _memfsIn_getNode(memfsIn, "/clu", generate_testdata_in_clu))
+ memfsIn.PathNodes.Set("/clu/de",
+ _memfsIn_getNode(memfsIn, "/clu/de", generate_testdata_in_clu_de))
+ memfsIn.PathNodes.Set("/clu/de/file.html",
+ _memfsIn_getNode(memfsIn, "/clu/de/file.html", generate_testdata_in_clu_de_file_html))
+ memfsIn.PathNodes.Set("/clu/de/markdown.html",
+ _memfsIn_getNode(memfsIn, "/clu/de/markdown.html", generate_testdata_in_clu_de_markdown_html))
+
+ memfsIn.Root = memfsIn.PathNodes.Get("/")
+
+ var err = memfsIn.Init()
+ if err != nil {
+ panic("memfsIn: " + err.Error())
+ }
+}
diff --git a/testdata/goembed/out/.gitignore b/testdata/goembed/out/.gitignore
deleted file mode 100644
index d6b7ef3..0000000
--- a/testdata/goembed/out/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
diff --git a/testdata/goembed/out/default.go b/testdata/goembed/out/default.go
new file mode 100644
index 0000000..0c21721
--- /dev/null
+++ b/testdata/goembed/out/default.go
@@ -0,0 +1,129 @@
+// Code generated by git.sr.ht/~shulhan/pakakeh.go/lib/memfs DO NOT EDIT.
+
+package mypackage
+
+import (
+ "git.sr.ht/~shulhan/pakakeh.go/lib/memfs"
+)
+
+func generate_testdata_in() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in",
+ Path: "/",
+ ContentType: "",
+ GenFuncName: "generate_testdata_in",
+ }
+ node.SetMode(0o20000000755)
+ node.SetName("/")
+ node.SetSize(0)
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu", generate_testdata_in_clu))
+ return node
+}
+
+func generate_testdata_in_clu() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu",
+ Path: "/clu",
+ ContentType: "",
+ GenFuncName: "generate_testdata_in_clu",
+ }
+ node.SetMode(0o20000000755)
+ node.SetName("clu")
+ node.SetSize(0)
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de", generate_testdata_in_clu_de))
+ return node
+}
+
+func generate_testdata_in_clu_de() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu/de",
+ Path: "/clu/de",
+ ContentType: "",
+ GenFuncName: "generate_testdata_in_clu_de",
+ }
+ node.SetMode(0o20000000755)
+ node.SetName("de")
+ node.SetSize(0)
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de/file.html", generate_testdata_in_clu_de_file_html))
+ node.AddChild(_memfsIn_getNode(memfsIn, "/clu/de/markdown.html", generate_testdata_in_clu_de_markdown_html))
+ return node
+}
+
+func generate_testdata_in_clu_de_file_html() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu/de/file.html",
+ Path: "/clu/de/file.html",
+ ContentType: "text/html; charset=utf-8",
+ GenFuncName: "generate_testdata_in_clu_de_file_html",
+ Content: []byte("\x0A\x0A\x0A\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x68\x74\x6D\x6C\x3E\x0A\x3C\x68\x74\x6D\x6C\x3E\x0A\x20\x20\x3C\x68\x65\x61\x64\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x68\x74\x74\x70\x2D\x65\x71\x75\x69\x76\x3D\x22\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x74\x65\x78\x74\x2F\x68\x74\x6D\x6C\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x75\x74\x66\x2D\x38\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x76\x69\x65\x77\x70\x6F\x72\x74\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x77\x69\x64\x74\x68\x3D\x64\x65\x76\x69\x63\x65\x2D\x77\x69\x64\x74\x68\x2C\x20\x69\x6E\x69\x74\x69\x61\x6C\x2D\x73\x63\x61\x6C\x65\x3D\x31\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x74\x68\x65\x6D\x65\x2D\x63\x6F\x6C\x6F\x72\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x23\x33\x37\x35\x45\x41\x42\x22\x3E\x0A\x20\x20\x20\x20\x3C\x74\x69\x74\x6C\x65\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x74\x69\x74\x6C\x65\x3E\x0A\x20\x20\x20\x20\x3C\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x20\x20\x62\x6F\x64\x79\x7B\x7D\x0A\x20\x20\x20\x20\x3C\x2F\x73\x74\x79\x6C\x65\x3E\x0A\x20\x20\x3C\x2F\x68\x65\x61\x64\x3E\x0A\x20\x20\x3C\x62\x6F\x64\x79\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x62\x61\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x61\x20\x68\x72\x65\x66\x3D\x22\x2F\x22\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x6D\x65\x6E\x75\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x66\x6F\x72\x6D\x20\x63\x6C\x61\x73\x73\x3D\x22\x69\x74\x65\x6D\x22\x20\x61\x63\x74\x69\x6F\x6E\x3D\x22\x2F\x5F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x61\x72\x63\x68\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x69\x6E\x70\x75\x74\x20\x74\x79\x70\x65\x3D\x22\x74\x65\x78\x74\x22\x20\x6E\x61\x6D\x65\x3D\x22\x71\x22\x20\x70\x6C\x61\x63\x65\x68\x6F\x6C\x64\x65\x72\x3D\x22\x53\x65\x61\x72\x63\x68\x22\x20\x2F\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x66\x6F\x72\x6D\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x70\x61\x67\x65\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x68\x65\x61\x64\x65\x72\x22\x3E\x0A\x3C\x68\x31\x3E\x64\x75\x6D\x6D\x79\x3C\x2F\x68\x31\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x63\x6F\x6E\x74\x65\x6E\x74\x22\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x3C\x64\x69\x76\x20\x69\x64\x3D\x22\x66\x6F\x6F\x74\x65\x72\x2D\x74\x65\x78\x74\x22\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x50\x6F\x77\x65\x72\x65\x64\x20\x62\x79\x20\x3C\x61\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x68\x72\x65\x66\x3D\x22\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x69\x74\x2E\x73\x72\x2E\x68\x74\x2F\x7E\x73\x68\x75\x6C\x68\x61\x6E\x2F\x63\x69\x69\x67\x6F\x22\x0A\x20\x20\x20\x20\x20\x20\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x63\x69\x69\x67\x6F\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x3C\x2F\x62\x6F\x64\x79\x3E\x0A\x3C\x2F\x68\x74\x6D\x6C\x3E\x0A\x0A"),
+ }
+ node.SetMode(0o644)
+ node.SetName("file.html")
+ node.SetSize(1003)
+ return node
+}
+
+func generate_testdata_in_clu_de_markdown_html() *memfs.Node {
+ var node = &memfs.Node{
+ SysPath: "testdata/in/clu/de/markdown.html",
+ Path: "/clu/de/markdown.html",
+ ContentType: "text/html; charset=utf-8",
+ GenFuncName: "generate_testdata_in_clu_de_markdown_html",
+ Content: []byte("\x0A\x0A\x0A\x3C\x21\x44\x4F\x43\x54\x59\x50\x45\x20\x68\x74\x6D\x6C\x3E\x0A\x3C\x68\x74\x6D\x6C\x3E\x0A\x20\x20\x3C\x68\x65\x61\x64\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x68\x74\x74\x70\x2D\x65\x71\x75\x69\x76\x3D\x22\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x74\x65\x78\x74\x2F\x68\x74\x6D\x6C\x3B\x20\x63\x68\x61\x72\x73\x65\x74\x3D\x75\x74\x66\x2D\x38\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x76\x69\x65\x77\x70\x6F\x72\x74\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x77\x69\x64\x74\x68\x3D\x64\x65\x76\x69\x63\x65\x2D\x77\x69\x64\x74\x68\x2C\x20\x69\x6E\x69\x74\x69\x61\x6C\x2D\x73\x63\x61\x6C\x65\x3D\x31\x22\x3E\x0A\x20\x20\x20\x20\x3C\x6D\x65\x74\x61\x20\x6E\x61\x6D\x65\x3D\x22\x74\x68\x65\x6D\x65\x2D\x63\x6F\x6C\x6F\x72\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x23\x33\x37\x35\x45\x41\x42\x22\x3E\x0A\x20\x20\x20\x20\x3C\x74\x69\x74\x6C\x65\x3E\x3C\x2F\x74\x69\x74\x6C\x65\x3E\x0A\x20\x20\x3C\x2F\x68\x65\x61\x64\x3E\x0A\x20\x20\x3C\x62\x6F\x64\x79\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x62\x61\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x74\x6F\x70\x2D\x68\x65\x61\x64\x69\x6E\x67\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x61\x20\x68\x72\x65\x66\x3D\x22\x2F\x22\x3E\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x6D\x65\x6E\x75\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x66\x6F\x72\x6D\x20\x63\x6C\x61\x73\x73\x3D\x22\x69\x74\x65\x6D\x22\x20\x61\x63\x74\x69\x6F\x6E\x3D\x22\x2F\x5F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x61\x72\x63\x68\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x69\x6E\x70\x75\x74\x20\x74\x79\x70\x65\x3D\x22\x74\x65\x78\x74\x22\x20\x6E\x61\x6D\x65\x3D\x22\x71\x22\x20\x70\x6C\x61\x63\x65\x68\x6F\x6C\x64\x65\x72\x3D\x22\x53\x65\x61\x72\x63\x68\x22\x20\x2F\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x66\x6F\x72\x6D\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x70\x61\x67\x65\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x22\x3E\x0A\x3C\x68\x31\x3E\x6D\x61\x72\x6B\x64\x6F\x77\x6E\x3C\x2F\x68\x31\x3E\x0A\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x20\x20\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x66\x6F\x6F\x74\x65\x72\x22\x3E\x0A\x20\x20\x20\x20\x20\x20\x50\x6F\x77\x65\x72\x65\x64\x20\x62\x79\x20\x3C\x61\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x68\x72\x65\x66\x3D\x22\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x69\x74\x2E\x73\x72\x2E\x68\x74\x2F\x7E\x73\x68\x75\x6C\x68\x61\x6E\x2F\x63\x69\x69\x67\x6F\x22\x0A\x20\x20\x20\x20\x20\x20\x3E\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x63\x69\x69\x67\x6F\x0A\x20\x20\x20\x20\x20\x20\x3C\x2F\x61\x3E\x0A\x20\x20\x20\x20\x3C\x2F\x64\x69\x76\x3E\x0A\x20\x20\x3C\x2F\x62\x6F\x64\x79\x3E\x0A\x3C\x2F\x68\x74\x6D\x6C\x3E\x0A\x0A"),
+ }
+ node.SetMode(0o644)
+ node.SetName("markdown.html")
+ node.SetSize(855)
+ return node
+}
+
+// _memfsIn_getNode is internal function to minimize duplicate node
+// created on Node.AddChild() and on generatedPathNode.Set().
+func _memfsIn_getNode(mfs *memfs.MemFS, path string, fn func() *memfs.Node) (node *memfs.Node) {
+ node = mfs.PathNodes.Get(path)
+ if node != nil {
+ return node
+ }
+ return fn()
+}
+
+func init() {
+ memfsIn = &memfs.MemFS{
+ PathNodes: memfs.NewPathNode(),
+ Opts: &memfs.Options{
+ Root: "testdata/in",
+ MaxFileSize: 5242880,
+ Includes: []string{
+ },
+ Excludes: []string{
+ `.*\.adoc$`,
+ `.*\.md$`,
+ `^\..*`,
+ },
+ Embed: memfs.EmbedOptions{
+ CommentHeader: ``,
+ PackageName: "mypackage",
+ VarName: "memfsIn",
+ GoFileName: "testdata/goembed/out/default.go",
+ WithoutModTime: true,
+ },
+ },
+ }
+ memfsIn.PathNodes.Set("/",
+ _memfsIn_getNode(memfsIn, "/", generate_testdata_in))
+ memfsIn.PathNodes.Set("/clu",
+ _memfsIn_getNode(memfsIn, "/clu", generate_testdata_in_clu))
+ memfsIn.PathNodes.Set("/clu/de",
+ _memfsIn_getNode(memfsIn, "/clu/de", generate_testdata_in_clu_de))
+ memfsIn.PathNodes.Set("/clu/de/file.html",
+ _memfsIn_getNode(memfsIn, "/clu/de/file.html", generate_testdata_in_clu_de_file_html))
+ memfsIn.PathNodes.Set("/clu/de/markdown.html",
+ _memfsIn_getNode(memfsIn, "/clu/de/markdown.html", generate_testdata_in_clu_de_markdown_html))
+
+ memfsIn.Root = memfsIn.PathNodes.Get("/")
+
+ var err = memfsIn.Init()
+ if err != nil {
+ panic("memfsIn: " + err.Error())
+ }
+}
diff --git a/testdata/watcher_test.txt b/testdata/watcher_test.txt
index df24c48..9c41cec 100644
--- a/testdata/watcher_test.txt
+++ b/testdata/watcher_test.txt
@@ -1,34 +1,39 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2023 Shulhan <ms@kilabit.info>
+
>>> create.adoc
= watch create
:generator!:
<<< create.adoc.html
+
+
<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="theme-color" content="#375EAB">
- <title>watch create</title>
- <style>
- body{}
- </style>
- </head>
- <body>
- <div class="topbar">
- <div class="container">
- <div class="top-heading">
- <a href="/">watch create</a>
- </div>
- <div class="menu">
- <form class="item" action="/_internal/search">
- <input type="text" name="q" placeholder="Search" />
- </form>
- </div>
- </div>
- </div>
- <div class="page">
- <div class="container">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="theme-color" content="#375EAB">
+ <title>watch create</title>
+ <style>
+ body{}
+ </style>
+ </head>
+ <body>
+ <div class="topbar">
+ <div class="container">
+ <div class="top-heading">
+ <a href="/">watch create</a>
+ </div>
+ <div class="menu">
+ <form class="item" action="/_internal/search">
+ <input type="text" name="q" placeholder="Search" />
+ </form>
+ </div>
+ </div>
+ </div>
+ <div class="page">
+ <div class="container">
<div id="header">
<h1>watch create</h1>
</div>
@@ -45,31 +50,33 @@
Hello, body.
<<< update.adoc.html
+
+
<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="theme-color" content="#375EAB">
- <meta name="keywords" content="ciigo,asciidoc">
- <title>watch updated</title>
- <link rel="stylesheet" href="/path/to/style.css">
- </head>
- <body>
- <div class="topbar">
- <div class="container">
- <div class="top-heading">
- <a href="/">watch updated</a>
- </div>
- <div class="menu">
- <form class="item" action="/_internal/search">
- <input type="text" name="q" placeholder="Search" />
- </form>
- </div>
- </div>
- </div>
- <div class="page">
- <div class="container">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="theme-color" content="#375EAB">
+ <meta name="keywords" content="ciigo,asciidoc">
+ <title>watch updated</title>
+ <link rel="stylesheet" href="/path/to/style.css">
+ </head>
+ <body>
+ <div class="topbar">
+ <div class="container">
+ <div class="top-heading">
+ <a href="/">watch updated</a>
+ </div>
+ <div class="menu">
+ <form class="item" action="/_internal/search">
+ <input type="text" name="q" placeholder="Search" />
+ </form>
+ </div>
+ </div>
+ </div>
+ <div class="page">
+ <div class="container">
<div id="header">
<h1>watch updated</h1>
</div>
@@ -87,37 +94,39 @@ Title: a title
# watch create
<<< create.md.html
+
+
<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="theme-color" content="#375EAB">
- <title>a title</title>
- <style>
- body{}
- </style>
- </head>
- <body>
- <div class="topbar">
- <div class="container">
- <div class="top-heading">
- <a href="/">a title</a>
- </div>
- <div class="menu">
- <form class="item" action="/_internal/search">
- <input type="text" name="q" placeholder="Search" />
- </form>
- </div>
- </div>
- </div>
- <div class="page">
- <div class="container">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="theme-color" content="#375EAB">
+ <title>a title</title>
+ <style>
+ body{}
+ </style>
+ </head>
+ <body>
+ <div class="topbar">
+ <div class="container">
+ <div class="top-heading">
+ <a href="/">a title</a>
+ </div>
+ <div class="menu">
+ <form class="item" action="/_internal/search">
+ <input type="text" name="q" placeholder="Search" />
+ </form>
+ </div>
+ </div>
+ </div>
+ <div class="page">
+ <div class="container">
<h1>watch create</h1>
- </div>
- </div>
- <div class="footer">
+ </div>
+ </div>
+ <div class="footer">
>>> update.md
---
@@ -128,33 +137,35 @@ keywords: ciigo,markdown
# watch updated
<<< update.md.html
+
+
<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="theme-color" content="#375EAB">
- <meta name="keywords" content="ciigo,markdown">
- <title>A new title</title>
- <link rel="stylesheet" href="/path/to/style.css">
- </head>
- <body>
- <div class="topbar">
- <div class="container">
- <div class="top-heading">
- <a href="/">A new title</a>
- </div>
- <div class="menu">
- <form class="item" action="/_internal/search">
- <input type="text" name="q" placeholder="Search" />
- </form>
- </div>
- </div>
- </div>
- <div class="page">
- <div class="container">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="theme-color" content="#375EAB">
+ <meta name="keywords" content="ciigo,markdown">
+ <title>A new title</title>
+ <link rel="stylesheet" href="/path/to/style.css">
+ </head>
+ <body>
+ <div class="topbar">
+ <div class="container">
+ <div class="top-heading">
+ <a href="/">A new title</a>
+ </div>
+ <div class="menu">
+ <form class="item" action="/_internal/search">
+ <input type="text" name="q" placeholder="Search" />
+ </form>
+ </div>
+ </div>
+ </div>
+ <div class="page">
+ <div class="container">
<h1>watch updated</h1>
- </div>
- </div>
- <div class="footer">
+ </div>
+ </div>
+ <div class="footer">
diff --git a/watcher_test.go b/watcher_test.go
index 1b9f3fa..64bb08c 100644
--- a/watcher_test.go
+++ b/watcher_test.go
@@ -105,7 +105,7 @@ func testAdocCreate(t *testing.T, testWatcher *watcher, tdata *test.Data, pathFi
t.Fatal(err)
}
- gotBody = removeFooter(gotBody, 15)
+ gotBody = removeFooter(gotBody, 17)
expBody = tdata.Output[`create.adoc.html`]
test.Assert(t, `HTML body`, string(expBody), string(gotBody))
@@ -135,7 +135,7 @@ func testAdocUpdate(t *testing.T, testWatcher *watcher, tdata *test.Data, pathFi
t.Fatal(err)
}
- gotBody = removeFooter(gotBody, 15)
+ gotBody = removeFooter(gotBody, 17)
expBody = tdata.Output[`update.adoc.html`]
test.Assert(t, `HTML body`, string(expBody), string(gotBody))
@@ -186,7 +186,7 @@ func testMarkdownCreate(t *testing.T, testWatcher *watcher, tdata *test.Data, pa
if err != nil {
t.Fatal(err)
}
- gotBody = removeFooter(gotBody, 8)
+ gotBody = removeFooter(gotBody, 10)
expBody = string(tdata.Output[`create.md.html`])
test.Assert(t, `HTML body`, expBody, string(gotBody))
@@ -216,7 +216,7 @@ func testMarkdownUpdate(t *testing.T, testWatcher *watcher, tdata *test.Data, pa
if err != nil {
t.Fatal(err)
}
- gotBody = removeFooter(gotBody, 8)
+ gotBody = removeFooter(gotBody, 10)
expBody = string(tdata.Output[`update.md.html`])
test.Assert(t, `HTML body`, expBody, string(gotBody))