Breaking changes, rewrite; add support for plain text output and single page mode

This commit is contained in:
Alex Shpak
2026-05-14 23:55:08 +02:00
parent 4018d4b51d
commit c6ef0a08c2
36 changed files with 165 additions and 72 deletions
+2
View File
@@ -3,4 +3,6 @@ exampleSite/public/
.DS_Store
.hugo_build.lock
.obsidian
.vscode
.zed
resources/
+13 -4
View File
@@ -235,7 +235,7 @@ bookHref = ''
bookIcon = 'calendar'
```
### Partials
## Partials
There are layout partials available for you to easily override components of the theme in `layouts/partials/`.
@@ -253,7 +253,7 @@ In addition to this, there are several empty partials you can override to easily
| `layouts/partials/docs/inject/toc-before.html` | At the beginning of table of contents block |
| `layouts/partials/docs/inject/toc-after.html` | At the end of table of contents block |
### Extra Customisation
## Extra Customisation
| File | Description |
| ------------------------ | ------------------------------------------------------------------------------------- |
@@ -264,7 +264,7 @@ In addition to this, there are several empty partials you can override to easily
| `assets/mermaid.json` | Replace Mermaid initialization config |
| `assets/katex.json` | Replace KaTeX initialization config |
### Plugins
## Plugins
There are a few features implemented as pluggable `scss` styles. Usually these are features that don't make it to the core but can still be useful.
@@ -276,7 +276,7 @@ There are a few features implemented as pluggable `scss` styles. Usually these a
To enable plugins, add `@import "plugins/{name}";` to `assets/_custom.scss` in your website root.
### Hugo Internal Templates
## Hugo Internal Templates
There are a few hugo templates inserted in `<head>`
@@ -289,6 +289,15 @@ In fact almost empty not quite empty because an empty file looks like absent for
<!-- -->
```
## Special layouts
There are extra page layouts apart from documentation pages, to apply set `layout: {name}` in page frontmatter
| Layout | Description |
| --------------------------------- | ------------ |
| `landing` | Renders a langing/home page, hides side menus and adds home menu at the top |
| `book` | Renders a single-page with all pages in configured BookSection section |
## Shortcodes
- [Buttons](https://hugo-book-demo.netlify.app/docs/shortcodes/buttons/)
+1 -1
View File
@@ -4,7 +4,7 @@
line-height: 1.6;
// remove padding at the beginning of page
> :first-child {
>:first-child, >section:first-child :first-child {
margin-top: 0;
}
-9
View File
@@ -222,15 +222,6 @@
margin: $padding-16 0;
}
.book-hero {
min-height: $padding-16 * 24;
align-content: center;
h1 {
font-size: 3em;
}
}
.book-codeblock-filename {
background: var(--gray-100);
border: $padding-1 solid var(--gray-200);
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M320-240h320v-80H320v80Zm0-160h320v-80H320v80ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>

After

Width:  |  Height:  |  Size: 333 B

+10 -1
View File
@@ -4,4 +4,13 @@
// @import "plugins/scrollbars";
// @import "plugins/themes";
@import "plugins/themes";
@import "plugins/themes";
.book-hero {
min-height: $padding-16 * 24;
align-content: center;
h1 {
font-size: 3em;
}
}
+7
View File
@@ -0,0 +1,7 @@
---
title: Single Page
layout: book
menu:
after:
weight: 7
---
@@ -17,7 +17,7 @@ bookHidden: true
{{<button href="/">}}A Button{{</button>}}
- ## Card
{{<card href="/docs/shortcodes/cards">}}
{{<card href="/docs/shortcodes/experimental/cards">}}
**Markdown**
Suspendisse sed congue orci, eu congue metus. Nullam feugiat urna massa.
{{</card>}}
+1 -1
View File
@@ -1,6 +1,6 @@
---
title: Blog
menu:
after:
weight: 5
title: Blog
---
+11
View File
@@ -14,6 +14,17 @@ copyright = '[© CC BY 4.0](https://creativecommons.org/licenses/by/4.0/legalcod
disablePathToLower = true
enableGitInfo = true
[outputFormats]
[outputFormats.txt]
mediaType = 'text/plain'
baseName = 'source'
isPlainText = true
[outputs]
home = ['html', 'txt', 'rss']
page = ['html', 'txt']
section = ['html', 'txt']
# Needed for mermaid/katex shortcodes
[markup]
[markup.goldmark.renderer]
+13 -3
View File
@@ -14,6 +14,16 @@ copyright: "[© CC BY 4.0](https://creativecommons.org/licenses/by/4.0/legalcode
disablePathToLower: true
enableGitInfo: true
outputFormats:
txt:
mediaType: "text/plain"
baseName: "source"
isPlainText: true
outputs:
home: ["html", "txt", "rss"]
page: ["html", "txt"]
section: ["html", "txt"]
# Needed for mermaid/katex shortcodes
markup:
goldmark:
@@ -97,12 +107,12 @@ params:
# (Optional, default none) Set template for commit link for the page. Requires enableGitInfo.
# When set enabled 'Last Modified' and a link to the commit in the footer of the page.
# Param is executed as template using .Site, .Page and .GitInfo as context.
BookLastChangeLink: 'https://github.com/alex-shpak/hugo-book/commit/{{ .GitInfo.Hash }}'
BookLastChangeLink: "https://github.com/alex-shpak/hugo-book/commit/{{ .GitInfo.Hash }}"
# (Optional, default none) Set template for edit page link.
# When set enabled 'Edit this page' link in the footer of the page.
# Param is executed as template using .Site, .Page and .Path as context.
BookEditLink: 'https://github.com/alex-shpak/hugo-book/edit/main/exampleSite/{{ .Path }}'
BookEditLink: "https://github.com/alex-shpak/hugo-book/edit/main/exampleSite/{{ .Path }}"
# (Optional, default 'January 2, 2006') Configure the date format used on the pages
# - In git information
@@ -126,7 +136,7 @@ params:
# Portable links meant to work with text editors and let you write markdown without {{< relref >}} shortcode
# Hugo Book will print warning or error if page referenced in markdown does not exists.
# Possible values are false | 'warning' | 'error'
BookPortableLinks: 'warning'
BookPortableLinks: "warning"
# /!\ This is an experimental feature, might be removed or changed at any time
# (Optional, experimental, default false)
+1 -1
View File
@@ -1,5 +1,5 @@
<h2 class="book-brand">
<a class="flex align-center" href="{{ cond (not .Site.Home.File) hugo.Sites.Default.Home.RelPermalink .Site.Home.RelPermalink }}">
<a class="flex align-center" href="{{ partial "docs/links/home" . }}">
{{- with .Site.Params.BookLogo -}}
<img src="{{ . | relURL }}" alt="{{ partial "docs/text/i18n" "Logo" }}" />
{{- end -}}
+1 -1
View File
@@ -1,2 +1,2 @@
<!-- This partial can be replaced to support other commenting engines -->
{{/* This partial can be replaced to support other commenting engines */}}
{{ partial "disqus.html" . }}
+2 -2
View File
@@ -1,6 +1,6 @@
<!--
{{/*
Returns formatted date.
Usage: partial "docs/date" (dict "Date" .Date "Format" .Site.Params.BookDateFormat)
-->
*/}}
{{- $format := default "January 2, 2006" .Format -}}
{{- return (time.Format $format .Date) -}}
+9
View File
@@ -10,6 +10,15 @@
{{ end }}
</div>
<div>
{{ with .OutputFormats.Get "txt" }}
<a class="flex align-center" href="{{ .RelPermalink }}">
<img src="{{ partial "docs/icon" "markdown" }}" class="book-icon" alt="{{ partial "docs/text/i18n" "Markdown" }}" />
<span>{{ partial "docs/text/i18n" "Source" }}</span>
</a>
{{ end }}
</div>
<div>
{{ if and .File .Site.Params.BookEditLink }}
<a class="flex align-center" href="{{ partial "docs/links/edit" . }}" target="_blank" rel="noopener edit">
+2 -3
View File
@@ -47,9 +47,8 @@ https://github.com/alex-shpak/hugo-book
{{ partial "google_analytics.html" . }}
<!-- RSS -->
{{- with .OutputFormats.Get "rss" -}}
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
{{- range .AlternativeOutputFormats -}}
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Title | safeHTML }}
{{ end -}}
{{- define "integrity" -}}
+1
View File
@@ -0,0 +1 @@
{{ return cond (not .Site.Home.File) hugo.Sites.Default.Home.RelPermalink .Site.Home.RelPermalink }}
+1 -6
View File
@@ -1,9 +1,4 @@
{{ $bookSection := default "docs" .Site.Params.BookSection }}
{{ if eq $bookSection "*" }}
{{ $bookSection = "/" }}{{/* Backward compatibility */}}
{{ end }}
{{ with .Site.GetPage $bookSection }}
{{ with (partialCached "docs/menu-section" .Site) }}
{{ template "book-section-children" (dict "Section" . "CurrentPage" $) }}
{{ end }}
+2 -2
View File
@@ -1,7 +1,7 @@
<!--
{{/*
This is template for hugo menus, accepts Page and Menu as context
https://gohugo.io/variables/menus/
-->
*/}}
{{- if .Menu -}}
{{- template "book-menu-hugo" . -}}
{{- end -}}
@@ -0,0 +1,16 @@
{{/* Recursively creates a slice of pages under given page */}}
{{ define "book-menu-recurse" }}
{{ if not .Page.Params.BookHidden }}
{{ if .Page.Content }}
{{ .Scratch.Add "BookPages" (slice .Page) }}
{{ end }}
{{ range .Page.Pages }}
{{ template "book-menu-recurse" (dict "Scratch" $.Scratch "Page" .) }}
{{ end }}
{{ end }}
{{ end }}
{{ $scratch := newScratch }}
{{ template "book-menu-recurse" (dict "Scratch" $scratch "Page" .) }}
{{ return $scratch.Get "BookPages" }}
+8
View File
@@ -0,0 +1,8 @@
{{/* returns the section to be rendered as menu */}}
{{ $bookSection := default "docs" .Params.BookSection }}
{{ $section := .GetPage (cond (eq $bookSection "*") "/" $bookSection) }}
{{ if $section }}
{{ return $section }}
{{ else }}
{{ errorf "%s: Section '%s' not found, check BookSection theme parameter" $ $bookSection }}
{{ end }}
@@ -1,14 +0,0 @@
{{ $scratch := newScratch }}
{{ template "recurse" (dict "Scratch" $scratch "Sections" .) }}
{{ define "recurse" }}
{{ range .Sections }}
{{ if and .Content (not .Params.BookHidden) }}
{{ $.Scratch.Add "BookPages" (slice .) }}
{{ end }}
{{ if .IsSection }}
{{ template "recurse" (dict "Scratch" $.Scratch "Sections" .Pages) }}
{{ end }}
{{ end }}
{{ end }}
{{ return $scratch.Get "BookPages" }}
+7 -12
View File
@@ -1,14 +1,9 @@
{{ $bookSection := default "docs" .Site.Params.BookSection }}
{{ if eq $bookSection "*" }}
{{ $bookSection = "/" }}{{/* Backward compatibility */}}
{{ end }}
{{- with (partialCached "docs/menu-section" .Site) -}}
{{- $pages := partialCached "docs/menu-section-pages" . -}}
{{- $prev := $pages.Next $ -}}
{{- $next := $pages.Prev $ -}}
{{ with .Site.GetPage $bookSection }}
{{ $pages := partialCached "docs/prev-next-cache" .Pages }}
{{ $prev := $pages.Next $ }}
{{ $next := $pages.Prev $ }}
{{- if or $prev $next }}
{{- if or $prev $next -}}
<div class="flex flex-wrap justify-between">
<span>
{{ with $prev }}
@@ -27,5 +22,5 @@
{{ end }}
</span>
</div>
{{ end -}}
{{ end }}
{{- end -}}
{{- end -}}
+2 -3
View File
@@ -1,8 +1,7 @@
<!--
{{/*
Returns rendered string from template and context.
Usage: partial "docs/string-template" (dict "Template" "param={{ . }}" "Context" "Input")
-->
*/}}
{{- $checksum := . | encoding.Jsonify | crypto.SHA1 | printf "book-%s" -}}
{{- $template := resources.FromString $checksum .Template -}}
{{- $template = $template | resources.ExecuteAsTemplate $checksum .Context -}}
+2 -2
View File
@@ -1,7 +1,7 @@
<!--
{{/*
Partial to generate page name from Title or File name.
Accepts Page as context
-->
*/}}
{{ $title := "" }}
{{ if .LinkTitle }}
-1
View File
@@ -1,5 +1,4 @@
{{- return and
(not (eq .Params.bookToC false))
(not (eq .Site.Params.BookToC false))
(not (eq .TableOfContents "<nav id=\"TableOfContents\"></nav>"))
-}}
+1 -1
View File
@@ -1,6 +1,6 @@
{{- $ratio := (split (.Get "ratio") ":") -}}
{{- if strings.Contains .InnerDeindent "<--->" -}}
{{- warnf "Columns shortcode separator '<--->' is deprecated, use markdown list instead." -}}
{{- warnf "{{<columns>}} shortcode separator '<--->' is deprecated, use markdown list instead." -}}
{{- $attributes := partial "docs/text/mapper" (dict
"attributes" (cond .IsNamedParams .Params dict)
"merge" (dict
+1 -1
View File
@@ -1,4 +1,4 @@
{{- warnf "Hint shortcode is deprecated, use markdown alerts format: '> [!NOTE] ...'" -}}
{{- warnf "{{<hint>}} shortcode is deprecated, use markdown alerts format: '> [!NOTE] ...'" -}}
{{- $attributes := partial "docs/text/mapper" (dict
"attributes" (cond .IsNamedParams .Params dict)
"merge" (dict
+1 -1
View File
@@ -1,4 +1,4 @@
{{- warnf "Section shortcode is deprecated and will be removed" -}}
{{- warnf "{{<section>}} shortcode is deprecated and will be removed" -}}
<dl>
{{ range .Page.Pages }}
<dt>
+7
View File
@@ -0,0 +1,7 @@
{{ .Site.Title }}
{{ $section := partialCached "docs/menu-section" .Site -}}
{{- range (partialCached "docs/menu-section-pages" $section) }}
- {{ partial "docs/title" . }}: {{ default .Permalink .Params.BookHref }}
{{- end }}
{{ .RawContent }}
-1
View File
@@ -64,7 +64,6 @@
{{ end }}
{{ define "clipboard" }}
<!-- Clipboard -->
{{ with resources.Get "clipboard.js" | resources.Minify }}
<script>{{ .Content | safeJS }}</script>
{{ end }}
+30
View File
@@ -0,0 +1,30 @@
{{ define "menu-container" }}
<!-- -->
{{ end }}
{{ define "toc" }}
{{ partial "docs/brand" . }}
<nav id="TableOfContents">
<ul>
{{- $section := partialCached "docs/menu-section" .Site -}}
{{- range (partialCached "docs/menu-section-pages" $section) }}
<li>
<a href="#{{ partial "docs/title" . | anchorize }}">{{ partial "docs/title" . }}</a>
</li>
{{ end }}
</ul>
</nav>
{{ end }}
{{ define "footer" }}
<!-- -->
{{ end }}
{{ define "main" }}
<article class="markdown">
{{- $section := partialCached "docs/menu-section" .Site -}}
{{- range partialCached "docs/menu-section-pages" $section }}
<section id="{{ partial "docs/title" . | anchorize }}">{{ .Content }}</section>
{{ end }}
</article>
{{ end }}
+10
View File
@@ -0,0 +1,10 @@
{{ .Site.Title }}
{{ $section := partialCached "docs/menu-section" .Site -}}
{{- range (partialCached "docs/menu-section-pages" $section) }}
- {{ partial "docs/title" . }}: {{ default .Permalink .Params.BookHref }}
{{- end }}
{{ $section := partialCached "docs/menu-section" .Site -}}
{{- range (partialCached "docs/menu-section-pages" $section) -}}
{{- .RawContent }}
{{ end -}}
+1 -1
View File
@@ -16,4 +16,4 @@
{{ define "footer" }}
{{ partial "docs/post-prev-next" . }}
{{ end }}
{{ end }}