diff --git a/README.md b/README.md index a79b849..4c002ed 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,16 @@ Forked from [knadh](https://github.com/knadh/hugo-ink) with custom adjustments. ## Ink-Free vs Hugo-Ink -This repository is a purely local (i.e., no CDNs), simplified version of `hugo-ink` with several **simplifications** for the sake of privacy: +This repository is a purely local (i.e., no CDNs[^1]), simplified version of `hugo-ink` with several **simplifications** for the sake of privacy: - Removed all references to Google's font-CDN - Removed Analytics code, even if it was controlled by a variable As well as some additional **features**: - Added a Back button to all posts -- Added a TOC, controlled by a variable, to all posts +- Added a Table of Contents (TOC), controlled by a variable, to all posts + - The TOC can either be static at the top + - Or floating on the side + - Added a word count, tags, and an approximate read time to the overview - Added random footer messages - Added "Edit this on GitHub" button @@ -26,15 +29,20 @@ And some **bugfixes**: - Change the background color for Syntax Highlighting, otherwise we're looking at grey code on a grey background - Added some classes for a Back button -It is also missing some features, which might be added later: -- Dark mode - ## Demo -![Screenshot](https://raw.githubusercontent.com/chollinger93/ink-free/master/images/screenshot.png "Ink-Free theme") +### Overview + +![Screenshot](https://raw.githubusercontent.com/chollinger93/ink-free/master/images/screenshot.png "Ink-Free theme") ![Screenshot](https://raw.githubusercontent.com/chollinger93/ink-free/master/images/screenshot2.png "Ink-Free theme") +### Static vs Floating TOC + +![image-20230620114414684](images/floating_toc.png) + +![image-20230620114454738](images/static_toc.png) + ### Run the example ``` cd exampleSite @@ -110,3 +118,5 @@ EOF ## License Licensed under the MIT license. + +[^1]: Note that the Feather CDN can still be enabled, but you can also host it statically. diff --git a/exampleSite/config.toml b/exampleSite/config.toml index 154c456..0e32f72 100644 --- a/exampleSite/config.toml +++ b/exampleSite/config.toml @@ -22,8 +22,10 @@ copyright = "© Copyright notice" # Site color - dark/light/auto mode = "auto" - # Enable a table of contents - toc = true + # Enable a table of contents: + # Either "static"/true, "floating", or "none" + # The floating TOC dissapears on mobile and adds 200px vertical space + toc = "floating" # Max tags maxTags = 7 diff --git a/exampleSite/content/posts/post-8.md b/exampleSite/content/posts/post-8.md index ff0303c..33db67d 100644 --- a/exampleSite/content/posts/post-8.md +++ b/exampleSite/content/posts/post-8.md @@ -1,6 +1,6 @@ --- title: "Markdown Syntax Guide" -date: "2021-09-03" +date: "2023-06-20" description: "Sample article showcasing basic Markdown syntax and formatting for HTML elements." tags: [markdown, css, html, themes] categories: [themes, syntax] @@ -13,7 +13,6 @@ This article offers a sample of basic Markdown syntax that can be used in Hugo c The following HTML `

`—`

` elements represent six levels of section headings. `

` is the highest section level while `

` is the lowest. -# H1 ## H2 ### H3 #### H4 @@ -30,12 +29,12 @@ Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sap The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations. -#### Blockquote without attribution +### Blockquote without attribution > Tiam, ad mint andaepu dandae nostion secatur sequo quae. > **Note** that you can use *Markdown syntax* within a blockquote. -#### Blockquote with attribution +### Blockquote with attribution > Don't communicate by sharing memory, share memory by communicating.

> — Rob Pike[^1] @@ -52,7 +51,7 @@ Tables aren't part of the core Markdown spec, but Hugo supports supports them ou Bob | 27 Alice | 23 -#### Inline Markdown within tables +### Inline Markdown within tables | Inline    | Markdown    | In    | Table | | ---------- | --------- | ----------------- | ---------- | @@ -60,10 +59,9 @@ Tables aren't part of the core Markdown spec, but Hugo supports supports them ou ## Code Blocks -#### Code block with backticks +### Code block with backticks -``` -html +```html @@ -75,7 +73,18 @@ html ``` -#### Code block indented with four spaces + +### Extra wide code block + +```scala +def make[F[_]: Sync: Parallel: ThrowableMonadError](cfg: ServiceConfig, client: Client[F]): HealthMonitorService[F] = + new HealthMonitorService[F] { + + override def checkWorkerStatus(workerCfg: WorkerConfig): F[WorkerStatus] = ??? + } +``` + +### Code block indented with four spaces @@ -88,7 +97,7 @@ html -#### Code block with Hugo's internal highlight shortcode +### Code block with Hugo's internal highlight shortcode {{< highlight html >}} @@ -104,19 +113,19 @@ html ## List Types -#### Ordered List +### Ordered List 1. First item 2. Second item 3. Third item -#### Unordered List +### Unordered List * List item * Another item * And another item -#### Nested list +### Nested list * Item 1. First Sub-item diff --git a/images/floating_toc.png b/images/floating_toc.png new file mode 100644 index 0000000..d122ac3 Binary files /dev/null and b/images/floating_toc.png differ diff --git a/images/static_toc.png b/images/static_toc.png new file mode 100644 index 0000000..62dbdf5 Binary files /dev/null and b/images/static_toc.png differ diff --git a/layouts/_default/single.html b/layouts/_default/single.html index 9650f83..a912b9b 100644 --- a/layouts/_default/single.html +++ b/layouts/_default/single.html @@ -3,94 +3,26 @@ {{ partial "header.html" . }} -
- {{ partial "head.html" . }} - -
-
- {{ if ne .Date.Year 1 }} -
-
- {{ dateFormat "02" .Date }} - {{ if $.Site.Data.month }}{{ index $.Site.Data.month (printf "%d" - .Date.Month) }} {{ .Date.Year }}{{ else }}{{ dateFormat "Jan 2006" .Date }}{{ end }} -
-
- {{ end }} -
-

{{ .Title }}

-
-
- - - {{ if and (gt .WordCount 400 ) (.Site.Params.toc) (ne .Params.toc false) }} - - {{ end }} - -
- {{ .Content }} -
- -
- {{ if ne .Type "page" }} - {{ if gt .Params.tags 0 }} -
    - {{ range .Params.tags }} -
  • {{ . }}
  • - {{ end }} -
- {{ end }} - {{ end }} -
- - {{ if isset .Site.Params "github" }} - - {{ end }} -
- -
+ {{ if and (gt .WordCount 400 ) (eq .Site.Params.toc "floating") }} +
+ {{ partial "head.html" . }} -
- {{ if isset .Site.Params "footers" }} - {{ if ne .Type "page" }} - Next time, we'll talk about "{{ range .Site.Params.footers | shuffle | first 1 }}{{ . }}"{{ end - }} - {{ end }} - {{ end }} -
- - {{- if .Site.DisqusShortname -}} - {{- $.Scratch.Set "isDisqus" true -}} - - {{- if and (isset .Params "type") (in .Site.Params.disableDisqusTypes .Params.type) -}} - {{- $.Scratch.Set "isDisqus" false -}} - {{- end -}} - - {{- if and (isset .Params "disqus") (eq .Params.disqus false) -}} - {{- $.Scratch.Set "isDisqus" false -}} - {{- else if and (isset .Params "disqus") (eq .Params.disqus true) -}} - {{- $.Scratch.Set "isDisqus" true -}} - {{- end -}} - - {{- if eq ($.Scratch.Get "isDisqus") true -}} - {{- partial "disqus.html" . -}} - {{- end -}} - {{- end -}} -
+ {{ partial "content_floating_toc.html" . }} +
+ {{ else }} +
+ {{ partial "head.html" . }} + {{ partial "content_static.html" . }}
+ {{ end }} {{ partial "footer.html" . }} + {{ if and (gt .WordCount 400 ) (eq .Site.Params.toc "floating") }} + {{ partial "toc_script.html" . }} + {{ end }} diff --git a/layouts/index.html b/layouts/index.html index 3b16e1a..663bffe 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -36,8 +36,9 @@

{{ if gt .Params.tags 0 }}
    + {{ $tagUrl := "/tags/"}} {{ range first .Site.Params.maxTags .Params.tags }} -
  • {{ . +
  • {{ . }}
  • {{ end }}
diff --git a/layouts/partials/article_footer.html b/layouts/partials/article_footer.html new file mode 100644 index 0000000..0fb7c48 --- /dev/null +++ b/layouts/partials/article_footer.html @@ -0,0 +1,36 @@ + +
+ {{ if ne .Type "page" }} + {{ if gt .Params.tags 0 }} +
    + {{ range .Params.tags }} + {{ $tagUrl := "/tags/"}} +
  • {{ . }} +
  • + {{ end }} +
+ {{ end }} + {{ end }} +
+ +{{ if isset .Site.Params "github" }} + +{{ end }} + + + + +
+ {{ if isset .Site.Params "footers" }} + {{ if ne .Type "page" }} + Next time, we'll talk about "{{ range .Site.Params.footers | shuffle | first 1 }}{{ . + }}"{{ end + }} + {{ end }} + {{ end }} +
diff --git a/layouts/partials/content_floating_toc.html b/layouts/partials/content_floating_toc.html new file mode 100644 index 0000000..619da00 --- /dev/null +++ b/layouts/partials/content_floating_toc.html @@ -0,0 +1,23 @@ + +
+
+ {{ partial "post_header.html" . }} + + + + + {{ .Content }} + +
+ +
+
+ {{ partial "article_footer.html" . }} +
diff --git a/layouts/partials/content_static.html b/layouts/partials/content_static.html new file mode 100644 index 0000000..b8d2ac0 --- /dev/null +++ b/layouts/partials/content_static.html @@ -0,0 +1,15 @@ +
+ {{ partial "post_header.html" . }} + + + {{ if and (gt .WordCount 400 ) (or (eq .Site.Params.toc "static") (eq .Site.Params.toc "true") )}} + + {{ end }} + {{ .Content }} + {{ partial "article_footer.html" . }} +
diff --git a/layouts/partials/disqus.html b/layouts/partials/disqus.html deleted file mode 100644 index 48b5f42..0000000 --- a/layouts/partials/disqus.html +++ /dev/null @@ -1,16 +0,0 @@ -
- - -comments powered by Disqus diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html index 2d92e25..4ed9d6d 100644 --- a/layouts/partials/footer.html +++ b/layouts/partials/footer.html @@ -1,6 +1,6 @@ diff --git a/layouts/partials/post_header.html b/layouts/partials/post_header.html new file mode 100644 index 0000000..7742736 --- /dev/null +++ b/layouts/partials/post_header.html @@ -0,0 +1,14 @@ +
+ {{ if ne .Date.Year 1 }} +
+
+ {{ dateFormat "02" .Date }} + {{ if $.Site.Data.month }}{{ index $.Site.Data.month (printf "%d" + .Date.Month) }} {{ .Date.Year }}{{ else }}{{ dateFormat "Jan 2006" .Date }}{{ end }} +
+
+ {{ end }} +
+

{{ .Title }}

+
+
diff --git a/layouts/partials/toc_script.html b/layouts/partials/toc_script.html new file mode 100644 index 0000000..9fd10c4 --- /dev/null +++ b/layouts/partials/toc_script.html @@ -0,0 +1,33 @@ + diff --git a/static/css/dark.css b/static/css/dark.css index 412633d..a1a8f57 100644 --- a/static/css/dark.css +++ b/static/css/dark.css @@ -83,3 +83,8 @@ html.dark code:not(pre *) { color: #ddd; background-color: #333; } + +html.dark .section-nav li.active > a { + font-weight: 600; + color: #ddd; +} diff --git a/static/css/main.css b/static/css/main.css index 6801f25..68a37f4 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -205,17 +205,19 @@ ul { display: inline; } +/* Code */ .highlight pre { margin-bottom: 0; margin-top: 0; - padding: 20px; + padding: 5px; /* background-color: black !important; */ } .highlight { /* background: 0 0; */ font-size: 0.8em; - + max-width: 800px; + overflow-x: auto; } .wrapper { @@ -228,6 +230,11 @@ ul { margin-top: 50px; } +.container-wide { + max-width: 1000px; + margin-top: 50px; +} + .header { margin-bottom: 20px; padding-bottom: 20px; @@ -369,8 +376,8 @@ ul { background-color: #f9f2f4; } -.post .tags a { - display: inline-block; +.post .tags a { + display: inline-block; border: 1px solid #3700ff; border-radius: 3px; padding: 0px 6px; @@ -491,9 +498,6 @@ ul { font-size: 1em; } -.toc { - line-height: normal; -} .inline-img { margin: 0 0 0 0 !important; @@ -521,4 +525,74 @@ code:not(pre *) { code { font-size: 0.8rem; + white-space: pre; +} + +.footer-separator { + border-top: 0.1em dashed lightgray; +} +/* Table of contents */ + +.toc { + line-height: normal; +} + +.show-on-mobile { + display: none !important; } +@media screen and (max-width: 1024px) { + .hide-on-mobile { + display: none !important; + } + .show-on-mobile { + display: block !important; + } + .container-wide { + max-width: 800px; + } + } + +@media only screen and (min-width: 1025px) { + .article-nav { + display: grid; + grid-template-columns: 1fr 15em; + max-width: 100em; + width: 100%; + margin: 0 auto; + } + } + + nav { + position: sticky; + top: 2rem; + align-self: start; + } + + .section-nav li.active > a { + font-weight: 600; + color: black; + } + + .section-nav { + font-size: smaller; + padding-left: 0; + border-left: 2px solid #efefef; + } + + .section-nav a { + text-decoration: none; + display: block; + color: #ccc; + transition: all 50ms ease-in-out; + } + + .section-nav li::marker { + color: #ccc; + } + + .section-nav a:hover, +.section-nav a:focus { + color: #666; + font-weight: 600; +} +