From acc4aee752ce9313938938a6a441e3a92c190804 Mon Sep 17 00:00:00 2001 From: James Panther <4462786+jpanther@users.noreply.github.com> Date: Tue, 18 Jan 2022 16:24:33 +1100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20Tables=20of=20Contents=20to?= =?UTF-8?q?=20articles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + assets/css/compiled/main.css | 121 +++++++++++++++++++++++- assets/css/main.css | 15 +++ config/_default/markup.toml | 4 + config/_default/params.toml | 1 + exampleSite/config/_default/markup.toml | 4 + exampleSite/config/_default/params.toml | 1 + i18n/de.yaml | 1 + i18n/en.yaml | 1 + i18n/es.yaml | 1 + i18n/fr.yaml | 1 + i18n/pt-BR.yaml | 1 + i18n/zh.yaml | 1 + layouts/_default/single.html | 19 +++- layouts/partials/toc.html | 12 +++ 15 files changed, 175 insertions(+), 9 deletions(-) create mode 100644 layouts/partials/toc.html diff --git a/CHANGELOG.md b/CHANGELOG.md index 350d9613..6359de93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Site search powered by Fuse.js - Automatic Markdown image resizing and srcset generation - Performance and Accessibility improvements to achieve perfect Lighthouse scores +- Tables of Contents on article pages - Taxonomies on article and list pages - Author `headline` parameter - Skip to content links diff --git a/assets/css/compiled/main.css b/assets/css/compiled/main.css index f2649d20..edcc3118 100644 --- a/assets/css/compiled/main.css +++ b/assets/css/compiled/main.css @@ -994,6 +994,40 @@ body a, body button { padding-left: 0px; } +/* Table of Contents */ + +.toc ul, .toc li { + margin-top: 0.25rem; + margin-bottom: 0.25rem; + list-style-type: none; + padding-left: 0px; + padding-right: 0px; + line-height: 1.375; +} + +[dir="ltr"] .toc ul ul { + padding-left: 1rem; +} + +[dir="rtl"] .toc ul ul { + padding-right: 1rem; +} + +.toc a { + font-weight: 400; + --tw-text-opacity: 1; + color: rgba(var(--color-neutral-700), var(--tw-text-opacity)); +} + +.dark .toc a { + --tw-text-opacity: 1; + color: rgba(var(--color-neutral-400), var(--tw-text-opacity)); +} + +[dir="rtl"] .toc ul > li { + margin-right: 0px; +} + /* -- Chroma Highlight -- */ /* Background */ @@ -1418,6 +1452,10 @@ body a, body button { z-index: 10; } +.order-first { + order: -9999; +} + .m-auto { margin: auto; } @@ -1636,6 +1674,10 @@ body a, body button { max-width: 65ch; } +.max-w-full { + max-width: 100%; +} + .max-w-\[10rem\] { max-width: 10rem; } @@ -1644,10 +1686,6 @@ body a, body button { max-width: 48rem; } -.max-w-full { - max-width: 100%; -} - .flex-none { flex: none; } @@ -1739,6 +1777,10 @@ body a, body button { border-radius: 0.25rem; } +.rounded-lg { + border-radius: 0.5rem; +} + .\!rounded-md { border-radius: 0.375rem !important; } @@ -1861,6 +1903,11 @@ body a, body button { padding-bottom: 2rem; } +.px-0 { + padding-left: 0px; + padding-right: 0px; +} + .px-2 { padding-left: 0.5rem; padding-right: 0.5rem; @@ -2229,6 +2276,10 @@ body a, body button { margin-left: 0.25rem; } +[dir="ltr"] .ltr\:-ml-5 { + margin-left: -1.25rem; +} + [dir="ltr"] .ltr\:block { display: block; } @@ -2241,10 +2292,18 @@ body a, body button { display: none; } +[dir="ltr"] .ltr\:border-l { + border-left-width: 1px; +} + [dir="ltr"] .ltr\:pr-2 { padding-right: 0.5rem; } +[dir="ltr"] .ltr\:pl-5 { + padding-left: 1.25rem; +} + [dir="ltr"] .ltr\:pr-3 { padding-right: 0.75rem; } @@ -2269,6 +2328,10 @@ body a, body button { margin-right: 0.25rem; } +[dir="rtl"] .rtl\:-mr-5 { + margin-right: -1.25rem; +} + [dir="rtl"] .rtl\:block { display: block; } @@ -2281,10 +2344,18 @@ body a, body button { display: none; } +[dir="rtl"] .rtl\:border-r { + border-right-width: 1px; +} + [dir="rtl"] .rtl\:pl-2 { padding-left: 0.5rem; } +[dir="rtl"] .rtl\:pr-5 { + padding-right: 1.25rem; +} + [dir="rtl"] .rtl\:pl-3 { padding-left: 0.75rem; } @@ -2413,6 +2484,11 @@ body a, body button { color: rgba(var(--color-neutral-800), var(--tw-text-opacity)); } +.dark .dark\:text-neutral-100 { + --tw-text-opacity: 1; + color: rgba(var(--color-neutral-100), var(--tw-text-opacity)); +} + .dark .dark\:hover\:border-primary-600:hover { --tw-border-opacity: 1; border-color: rgba(var(--color-primary-600), var(--tw-border-opacity)); @@ -2530,10 +2606,39 @@ body a, body button { } @media (min-width: 1024px) { + .lg\:sticky { + position: -webkit-sticky; + position: sticky; + } + + .lg\:top-10 { + top: 2.5rem; + } + + .lg\:order-last { + order: 9999; + } + + .lg\:mt-3 { + margin-top: 0.75rem; + } + + .lg\:hidden { + display: none; + } + .lg\:w-1\/4 { width: 25%; } + .lg\:max-w-xs { + max-width: 20rem; + } + + .lg\:flex-row { + flex-direction: row; + } + .lg\:p-\[12vh\] { padding: 12vh; } @@ -2542,6 +2647,14 @@ body a, body button { padding-left: 8rem; padding-right: 8rem; } + + [dir="ltr"] .ltr\:lg\:pl-8 { + padding-left: 2rem; + } + + [dir="rtl"] .rtl\:lg\:pr-8 { + padding-right: 2rem; + } } @media (min-width: 1280px) { diff --git a/assets/css/main.css b/assets/css/main.css index 2e7cb22d..43e65a78 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -62,6 +62,21 @@ body button { @apply rtl:pl-0; } +/* Table of Contents */ +.toc ul, +.toc li { + @apply px-0 my-1 leading-snug list-none; +} +.toc ul ul { + @apply ltr:pl-4 rtl:pr-4; +} +.toc a { + @apply font-normal text-neutral-700 dark:text-neutral-400; +} +.toc ul > li { + @apply rtl:mr-0; +} + /* -- Chroma Highlight -- */ /* Background */ .markdown .chroma { diff --git a/config/_default/markup.toml b/config/_default/markup.toml index 2ca49b3b..c5449fc3 100644 --- a/config/_default/markup.toml +++ b/config/_default/markup.toml @@ -7,3 +7,7 @@ [highlight] noClasses = false + +[tableOfContents] + startLevel = 2 + endLevel = 4 diff --git a/config/_default/params.toml b/config/_default/params.toml index f9946871..f271555e 100644 --- a/config/_default/params.toml +++ b/config/_default/params.toml @@ -30,6 +30,7 @@ enableSearch = false showPagination = true showReadingTime = true showTaxonomies = false + showTableOfContents = false showWordCount = false # sharingLinks = ["facebook", "twitter", "pinterest", "reddit", "linkedin", "email"] diff --git a/exampleSite/config/_default/markup.toml b/exampleSite/config/_default/markup.toml index 2ca49b3b..c5449fc3 100644 --- a/exampleSite/config/_default/markup.toml +++ b/exampleSite/config/_default/markup.toml @@ -7,3 +7,7 @@ [highlight] noClasses = false + +[tableOfContents] + startLevel = 2 + endLevel = 4 diff --git a/exampleSite/config/_default/params.toml b/exampleSite/config/_default/params.toml index 8d270d6f..8bed8c36 100644 --- a/exampleSite/config/_default/params.toml +++ b/exampleSite/config/_default/params.toml @@ -30,6 +30,7 @@ mainSections = ["samples"] showPagination = true showReadingTime = true showTaxonomies = false + showTableOfContents = true showWordCount = false # sharingLinks = ["facebook", "twitter", "pinterest", "reddit", "linkedin", "email"] diff --git a/i18n/de.yaml b/i18n/de.yaml index 20aa1897..bbb922e4 100644 --- a/i18n/de.yaml +++ b/i18n/de.yaml @@ -6,6 +6,7 @@ article: one: "{{ .Count }} min" other: "{{ .Count }} min" reading_time_title: "Lesezeit" + # table_of_contents: "Table of Contents" # word_count: # one: "{{ .Count }} word" # other: "{{ .Count }} words" diff --git a/i18n/en.yaml b/i18n/en.yaml index 1ea40ef4..f80eb850 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -6,6 +6,7 @@ article: one: "{{ .Count }} min" other: "{{ .Count }} mins" reading_time_title: "Reading time" + table_of_contents: "Table of Contents" word_count: one: "{{ .Count }} word" other: "{{ .Count }} words" diff --git a/i18n/es.yaml b/i18n/es.yaml index 6579ee88..59430b00 100644 --- a/i18n/es.yaml +++ b/i18n/es.yaml @@ -6,6 +6,7 @@ article: one: "{{ .Count }} min" other: "{{ .Count }} mins" reading_time_title: "Tiempo de lectura" + # table_of_contents: "Table of Contents" # word_count: # one: "{{ .Count }} word" # other: "{{ .Count }} words" diff --git a/i18n/fr.yaml b/i18n/fr.yaml index f2725de8..f1cf5cfc 100644 --- a/i18n/fr.yaml +++ b/i18n/fr.yaml @@ -6,6 +6,7 @@ article: one: "{{ .Count }} min" other: "{{ .Count }} mins" reading_time_title: "Temps de lecture" + # table_of_contents: "Table of Contents" # word_count: # one: "{{ .Count }} word" # other: "{{ .Count }} words" diff --git a/i18n/pt-BR.yaml b/i18n/pt-BR.yaml index ce619e8b..05a79866 100644 --- a/i18n/pt-BR.yaml +++ b/i18n/pt-BR.yaml @@ -6,6 +6,7 @@ article: one: "{{ .Count }} minuto" other: "{{ .Count }} minutos" reading_time_title: "Tempo de leitura" + # table_of_contents: "Table of Contents" # word_count: # one: "{{ .Count }} word" # other: "{{ .Count }} words" diff --git a/i18n/zh.yaml b/i18n/zh.yaml index c5dfb519..dbf0ea1a 100644 --- a/i18n/zh.yaml +++ b/i18n/zh.yaml @@ -5,6 +5,7 @@ article: reading_time: other: "{{ .Count }} 分钟" reading_time_title: "预计阅读" + # table_of_contents: "Table of Contents" word_count: one: "{{ .Count }} 字" other: "{{ .Count }} 字" diff --git a/layouts/_default/single.html b/layouts/_default/single.html index dcc05fc7..0492f6bc 100644 --- a/layouts/_default/single.html +++ b/layouts/_default/single.html @@ -1,6 +1,6 @@ {{ define "main" }} -
-
+
+
{{ if .Site.Params.article.showBreadcrumbs | default false }} {{ partial "breadcrumbs.html" . }} {{ end }} @@ -11,10 +11,19 @@ {{ partial "article-meta.html" (dict "context" . "scope" "single") }}
-
- {{ .Content | emojify }} +
+ {{ if and (.Params.showTableOfContents | default (.Site.Params.article.showTableOfContents | default false)) (in .TableOfContents " +
+ {{ partial "toc.html" . }} +
+ + {{ end }} +
+ {{ .Content | emojify }} +
-