Org html: revamp TOC
This commit is contained in:
parent
b702523770
commit
0c93a6b858
34
config.org
34
config.org
|
@ -4778,6 +4778,40 @@ directly to the ~table~ element, so we have to wrap it in a ~div~.
|
|||
(funcall orig-fn table contents info)
|
||||
"</div>"))
|
||||
#+END_SRC
|
||||
***** TOC as a collapsable tree
|
||||
The TOC is much nicer to navigate as a collapsable tree. Unfortunately we cannot
|
||||
achieve this with CSS alone. Thankfully we can avoid JS though, by adapting the
|
||||
TOC generation code to use a ~label~ for each item, and a hidden ~checkbox~ to keep
|
||||
track of state.
|
||||
|
||||
To add this, we need to change one line in [[file:~/.emacs.d/.local/straight/repos/org-mode/lisp/ox-html.el::(format "<a href=\"#%s\">%s</a>"][org-html--format-toc-headline]].
|
||||
|
||||
Since we can actually accomplish the desired effect by adding advice /around/ the
|
||||
function, without overriding it --- let's do that to reduce the bug surface of
|
||||
this config a tad.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defadvice! org-html--format-toc-headline-colapseable (orig-fn headline info)
|
||||
"Add a label and checkbox to `org-html--format-toc-headline's usual output,
|
||||
to allow the TOC to be a collapseable tree."
|
||||
:around #'org-html--format-toc-headline
|
||||
(let ((id (or (org-element-property :CUSTOM_ID headline)
|
||||
(org-export-get-reference headline info))))
|
||||
(format "<input type='checkbox' id='toc--%s'/><label for='toc--%s'>%s</label>"
|
||||
id id (funcall orig-fn headline info))))
|
||||
#+END_SRC
|
||||
|
||||
Now, leaves (headings with no children) shouldn't have the ~label~ item. The
|
||||
obvious way to achieve this is by including some /if no children.../ logic in
|
||||
~org-html--format-toc-headline-colapseable~. Unfortunately, I can't my elisp isn't
|
||||
up to par to extract the number of child headings from the mountain of info that
|
||||
org provides.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defadvice! org-html--toc-text-stripped-leaves (orig-fn toc-entries)
|
||||
"Remove label"
|
||||
:around #'org-html--toc-text
|
||||
(replace-regexp-in-string "<input [^>]+><label [^>]+>\\(.+?\\)</label></li>" "\\1</li>"
|
||||
(funcall orig-fn toc-entries)))
|
||||
#+END_SRC
|
||||
***** Make verbatim different to code
|
||||
Since we have =verbatim= and ~code~, let's use =verbatim= for key strokes.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
|
|
|
@ -43,15 +43,6 @@ nav#table-of-contents {
|
|||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
#text-table-of-contents {
|
||||
display: block;
|
||||
}
|
||||
h2 {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
transform: rotate(-90deg);
|
||||
position: relative;
|
||||
|
@ -69,71 +60,135 @@ nav#table-of-contents {
|
|||
//
|
||||
|
||||
::-webkit-scrollbar { width: 10px; height: 8px; }
|
||||
::-webkit-scrollbar-track { background:transparent; }
|
||||
::-webkit-scrollbar-thumb { background:transparent; border-radius: 10px; }
|
||||
::-webkit-scrollbar-thumb:hover { background:transparent; }
|
||||
::-webkit-scrollbar-track { background:#9992; }
|
||||
::-webkit-scrollbar-thumb { background:#ccc; }
|
||||
::-webkit-scrollbar-thumb:hover { background:#888; }
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
#table-of-contents {
|
||||
position: fixed;
|
||||
right: 4rem;
|
||||
width: 18rem;
|
||||
right: 1rem;
|
||||
top: 0;
|
||||
padding: 1em;
|
||||
width: 15rem;
|
||||
line-height: 1.5;
|
||||
margin-top: 4rem;
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
> div > ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
max-height: calc(100vh - 5rem - 40px);
|
||||
overflow-y: auto;
|
||||
overflow-x: visible;
|
||||
scrollbar-color: transparent transparent;
|
||||
scrollbar-width: thin;
|
||||
ul {
|
||||
padding-left: 2em;
|
||||
#text-table-of-contents {
|
||||
position: relative;
|
||||
&::before, &::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
width: calc(100% - 10px);
|
||||
height: 0.7rem;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
> li {
|
||||
display: block;
|
||||
&::before {
|
||||
top: 0;
|
||||
background: linear-gradient(180deg, $back-light 0%, $back-light 35%, rgba(0,0,0,0) 100%);
|
||||
}
|
||||
&::after {
|
||||
bottom: 0;
|
||||
background: linear-gradient(0deg, $back-light 0%, $back-light 35%, rgba(0,0,0,0) 100%);
|
||||
}
|
||||
> ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
max-height: calc(100vh - 5rem - 50px);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
scrollbar-width: thin;
|
||||
ul {
|
||||
padding-left: 2em;
|
||||
}
|
||||
ul.active {
|
||||
display: inline-block;
|
||||
}
|
||||
li.active > ul {
|
||||
display: inline-block;
|
||||
}
|
||||
li.active > label a, li.active > a {
|
||||
color: $text-dark;
|
||||
}
|
||||
li.active > input:not(:checked) ~ label::after {
|
||||
transform: rotate(90deg);
|
||||
top: 5px;
|
||||
opacity: 0.35;
|
||||
}
|
||||
> li:last-child {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
ul.active > li {
|
||||
display: block;
|
||||
}
|
||||
li {
|
||||
display: none;
|
||||
a {
|
||||
display: inline-block;
|
||||
color: $text-light;
|
||||
text-decoration: none;
|
||||
-webkit-transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
// negating earlir styles
|
||||
text-shadow: none;
|
||||
background: none !important;
|
||||
}
|
||||
}
|
||||
li:hover, li:hover > ul > li {
|
||||
display: block !important;
|
||||
a {
|
||||
color: $text-gray;
|
||||
}
|
||||
}
|
||||
li.active > a {
|
||||
color: $text-dark;
|
||||
}
|
||||
li::before {
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
}
|
||||
#table-of-contents {
|
||||
// width: 20rem;
|
||||
// right: 1rem;
|
||||
@media (min-width: 1440px) {
|
||||
width: 20rem;
|
||||
right: 2rem;
|
||||
}
|
||||
@media (min-width: 1640px) {
|
||||
right: 5rem;
|
||||
}
|
||||
@media (min-width: 2000px) {
|
||||
width: 25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1640px) {
|
||||
#table-of-contents {
|
||||
right: 10rem;
|
||||
#table-of-contents {
|
||||
#text-table-of-contents {
|
||||
> ul ul {
|
||||
display: none;
|
||||
}
|
||||
li {
|
||||
input[type=checkbox] {
|
||||
display: none;
|
||||
}
|
||||
label {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
a {
|
||||
display: inline-block;
|
||||
color: $text-light;
|
||||
text-decoration: none !important;
|
||||
// negating other <a> styles
|
||||
text-shadow: none;
|
||||
background: none !important;
|
||||
}
|
||||
label::after {
|
||||
content: "\25b6";
|
||||
color: $text-light;
|
||||
margin-left: 0.5em;
|
||||
font-size: 10px;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 3.4px;
|
||||
left: -20px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
input:checked ~ ul {
|
||||
display: inline-block !important; // needs to override more deeper selector div > ul ul
|
||||
}
|
||||
input:checked ~ label {
|
||||
a {
|
||||
font-weight: bold;
|
||||
}
|
||||
&::after {
|
||||
transform: rotate(90deg);
|
||||
top: 5px;
|
||||
}
|
||||
}
|
||||
&::before {
|
||||
content: "" !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2373,10 +2373,6 @@ nav#table-of-contents {
|
|||
overflow: auto; }
|
||||
nav#table-of-contents #text-table-of-contents ul {
|
||||
margin: 0; }
|
||||
nav#table-of-contents:hover #text-table-of-contents {
|
||||
display: block; }
|
||||
nav#table-of-contents:hover h2 {
|
||||
display: none; }
|
||||
nav#table-of-contents h2 {
|
||||
transform: rotate(-90deg);
|
||||
position: relative;
|
||||
|
@ -2389,63 +2385,117 @@ nav#table-of-contents {
|
|||
height: 8px; }
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent; }
|
||||
background: #9992; }
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: transparent;
|
||||
border-radius: 10px; }
|
||||
background: #ccc; }
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: transparent; }
|
||||
background: #888; }
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
#table-of-contents {
|
||||
position: fixed;
|
||||
right: 4rem;
|
||||
width: 18rem;
|
||||
right: 1rem;
|
||||
top: 0;
|
||||
padding: 1em;
|
||||
width: 15rem;
|
||||
line-height: 1.5;
|
||||
margin-top: 4rem; }
|
||||
#table-of-contents h2 {
|
||||
margin-top: 0; }
|
||||
#table-of-contents > div > ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
max-height: calc(100vh - 5rem - 40px);
|
||||
overflow-y: auto;
|
||||
overflow-x: visible;
|
||||
scrollbar-color: transparent transparent;
|
||||
scrollbar-width: thin; }
|
||||
#table-of-contents > div > ul ul {
|
||||
padding-left: 2em; }
|
||||
#table-of-contents > div > ul > li {
|
||||
display: block; }
|
||||
#table-of-contents ul.active > li {
|
||||
display: block; }
|
||||
#table-of-contents li {
|
||||
display: none; }
|
||||
#table-of-contents li a {
|
||||
display: inline-block;
|
||||
color: var(--text-light);
|
||||
text-decoration: none;
|
||||
-webkit-transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
text-shadow: none;
|
||||
background: none !important; }
|
||||
#table-of-contents li:hover, #table-of-contents li:hover > ul > li {
|
||||
display: block !important; }
|
||||
#table-of-contents li:hover a, #table-of-contents li:hover > ul > li a {
|
||||
color: var(--text-gray); }
|
||||
#table-of-contents li.active > a {
|
||||
color: var(--text-dark); }
|
||||
#table-of-contents li::before {
|
||||
content: ""; } }
|
||||
#table-of-contents #text-table-of-contents {
|
||||
position: relative; }
|
||||
#table-of-contents #text-table-of-contents::before, #table-of-contents #text-table-of-contents::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
width: calc(100% - 10px);
|
||||
height: 0.7rem;
|
||||
left: 0;
|
||||
z-index: 1; }
|
||||
#table-of-contents #text-table-of-contents::before {
|
||||
top: 0;
|
||||
background: linear-gradient(180deg, var(--back-light) 0%, var(--back-light) 35%, rgba(0, 0, 0, 0) 100%); }
|
||||
#table-of-contents #text-table-of-contents::after {
|
||||
bottom: 0;
|
||||
background: linear-gradient(0deg, var(--back-light) 0%, var(--back-light) 35%, rgba(0, 0, 0, 0) 100%); }
|
||||
#table-of-contents #text-table-of-contents > ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
max-height: calc(100vh - 5rem - 50px);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
scrollbar-width: thin; }
|
||||
#table-of-contents #text-table-of-contents > ul ul {
|
||||
padding-left: 2em; }
|
||||
#table-of-contents #text-table-of-contents > ul ul.active {
|
||||
display: inline-block; }
|
||||
#table-of-contents #text-table-of-contents > ul li.active > ul {
|
||||
display: inline-block; }
|
||||
#table-of-contents #text-table-of-contents > ul li.active > label a, #table-of-contents #text-table-of-contents > ul li.active > a {
|
||||
color: var(--text-dark); }
|
||||
#table-of-contents #text-table-of-contents > ul li.active > input:not(:checked) ~ label::after {
|
||||
transform: rotate(90deg);
|
||||
top: 5px;
|
||||
opacity: 0.35; }
|
||||
#table-of-contents #text-table-of-contents > ul > li:last-child {
|
||||
margin-bottom: 2rem; } }
|
||||
|
||||
@media (min-width: 1440px) {
|
||||
#table-of-contents {
|
||||
width: 20rem;
|
||||
right: 2rem; } }
|
||||
|
||||
@media (min-width: 1640px) {
|
||||
#table-of-contents {
|
||||
right: 10rem; } }
|
||||
right: 5rem; } }
|
||||
|
||||
@media (min-width: 2000px) {
|
||||
#table-of-contents {
|
||||
width: 25rem; } }
|
||||
|
||||
#table-of-contents #text-table-of-contents > ul ul {
|
||||
display: none; }
|
||||
|
||||
#table-of-contents #text-table-of-contents li input[type=checkbox] {
|
||||
display: none; }
|
||||
|
||||
#table-of-contents #text-table-of-contents li label {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
position: relative; }
|
||||
|
||||
#table-of-contents #text-table-of-contents li a {
|
||||
display: inline-block;
|
||||
color: var(--text-light);
|
||||
text-decoration: none !important;
|
||||
text-shadow: none;
|
||||
background: none !important; }
|
||||
|
||||
#table-of-contents #text-table-of-contents li label::after {
|
||||
content: "\25b6";
|
||||
color: var(--text-light);
|
||||
margin-left: 0.5em;
|
||||
font-size: 10px;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 3.4px;
|
||||
left: -20px;
|
||||
opacity: 0.8; }
|
||||
|
||||
#table-of-contents #text-table-of-contents li input:checked ~ ul {
|
||||
display: inline-block !important; }
|
||||
|
||||
#table-of-contents #text-table-of-contents li input:checked ~ label a {
|
||||
font-weight: bold; }
|
||||
|
||||
#table-of-contents #text-table-of-contents li input:checked ~ label::after {
|
||||
transform: rotate(90deg);
|
||||
top: 5px; }
|
||||
|
||||
#table-of-contents #text-table-of-contents li::before {
|
||||
content: "" !important; }
|
||||
|
||||
#breadcrumbs {
|
||||
font-family: "Open Sans";
|
||||
|
|
Loading…
Reference in New Issue