mirror of
https://github.com/tcsenpai/obsidiangarden_netlify.git
synced 2025-06-04 12:00:02 +00:00
Implemented support for table of content
This commit is contained in:
parent
8b03626f82
commit
8da3c9317a
49
.eleventy.js
49
.eleventy.js
@ -3,6 +3,10 @@ const markdownIt = require("markdown-it");
|
||||
const fs = require('fs');
|
||||
const matter = require('gray-matter');
|
||||
const faviconPlugin = require('eleventy-favicon');
|
||||
const tocPlugin = require('eleventy-plugin-toc');
|
||||
|
||||
const {headerToId, namedHeadingsFilter} = require("./src/helpers/utils")
|
||||
|
||||
module.exports = function(eleventyConfig) {
|
||||
|
||||
let markdownLib = markdownIt({
|
||||
@ -184,6 +188,7 @@ module.exports = function(eleventyConfig) {
|
||||
|
||||
eleventyConfig.addPassthroughCopy("src/site/img");
|
||||
eleventyConfig.addPlugin(faviconPlugin, { destination: 'dist' });
|
||||
eleventyConfig.addPlugin(tocPlugin, {ul:true, tags: ['h1','h2', 'h3', 'h4', 'h5', 'h6']});
|
||||
eleventyConfig.addFilter('jsonify', function (variable) {
|
||||
return JSON.stringify(variable);
|
||||
});
|
||||
@ -201,47 +206,3 @@ module.exports = function(eleventyConfig) {
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
function headerToId(heading) {
|
||||
return slugify(heading);
|
||||
}
|
||||
|
||||
//https://github.com/rstacruz/markdown-it-named-headings/blob/master/index.js
|
||||
function namedHeadingsFilter(md, options) {
|
||||
md.core.ruler.push('named_headings', namedHeadings.bind(null, md));
|
||||
}
|
||||
|
||||
function namedHeadings(md, state) {
|
||||
|
||||
var ids = {}
|
||||
|
||||
state.tokens.forEach(function(token, i) {
|
||||
if (token.type === 'heading_open') {
|
||||
var text = md.renderer.render(state.tokens[i + 1].children, md.options)
|
||||
var id = headerToId(text);
|
||||
var uniqId = uncollide(ids, id)
|
||||
ids[uniqId] = true
|
||||
setAttr(token, 'id', uniqId)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function uncollide(ids, id) {
|
||||
if (!ids[id]) return id
|
||||
var i = 1
|
||||
while (ids[id + '-' + i]) { i++ }
|
||||
return id + '-' + i
|
||||
}
|
||||
|
||||
function setAttr(token, attr, value, options) {
|
||||
var idx = token.attrIndex(attr)
|
||||
|
||||
if (idx === -1) {
|
||||
token.attrPush([attr, value])
|
||||
} else if (options && options.append) {
|
||||
token.attrs[idx][1] =
|
||||
token.attrs[idx][1] + ' ' + value
|
||||
} else {
|
||||
token.attrs[idx][1] = value
|
||||
}
|
||||
}
|
||||
|
17
package-lock.json
generated
17
package-lock.json
generated
@ -15,6 +15,7 @@
|
||||
"axios": "^0.26.1",
|
||||
"dotenv": "^10.0.0",
|
||||
"eleventy-favicon": "^1.1.2",
|
||||
"eleventy-plugin-toc": "^1.1.5",
|
||||
"fs-file-tree": "^1.1.1",
|
||||
"gray-matter": "^4.0.3",
|
||||
"lunr": "^2.3.9",
|
||||
@ -1729,6 +1730,14 @@
|
||||
"to-ico": "^1.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/eleventy-plugin-toc": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/eleventy-plugin-toc/-/eleventy-plugin-toc-1.1.5.tgz",
|
||||
"integrity": "sha512-Fo5AZZSBH8CKvz0axJQA9nmnTFOflAMFrngaKER4rOz3C6oDwqxK8N+kNFepmIsieTPkrH+iREWLJ+/9j5JjUg==",
|
||||
"dependencies": {
|
||||
"cheerio": "^1.0.0-rc.10"
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
@ -7649,6 +7658,14 @@
|
||||
"to-ico": "^1.1.5"
|
||||
}
|
||||
},
|
||||
"eleventy-plugin-toc": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/eleventy-plugin-toc/-/eleventy-plugin-toc-1.1.5.tgz",
|
||||
"integrity": "sha512-Fo5AZZSBH8CKvz0axJQA9nmnTFOflAMFrngaKER4rOz3C6oDwqxK8N+kNFepmIsieTPkrH+iREWLJ+/9j5JjUg==",
|
||||
"requires": {
|
||||
"cheerio": "^1.0.0-rc.10"
|
||||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
|
@ -28,6 +28,7 @@
|
||||
"axios": "^0.26.1",
|
||||
"dotenv": "^10.0.0",
|
||||
"eleventy-favicon": "^1.1.2",
|
||||
"eleventy-plugin-toc": "^1.1.5",
|
||||
"fs-file-tree": "^1.1.1",
|
||||
"gray-matter": "^4.0.3",
|
||||
"lunr": "^2.3.9",
|
||||
|
@ -5,5 +5,6 @@ exports.ALL_NOTE_SETTINGS= [
|
||||
"dgShowLocalGraph",
|
||||
"dgShowInlineTitle",
|
||||
"dgShowFileTree",
|
||||
"dgEnableSearch"
|
||||
"dgEnableSearch",
|
||||
"dgShowToc"
|
||||
];
|
47
src/helpers/utils.js
Normal file
47
src/helpers/utils.js
Normal file
@ -0,0 +1,47 @@
|
||||
const slugify = require("@sindresorhus/slugify");
|
||||
|
||||
function headerToId(heading) {
|
||||
return slugify(heading);
|
||||
}
|
||||
|
||||
function namedHeadings(md, state) {
|
||||
|
||||
var ids = {}
|
||||
|
||||
state.tokens.forEach(function(token, i) {
|
||||
if (token.type === 'heading_open') {
|
||||
var text = md.renderer.render(state.tokens[i + 1].children, md.options)
|
||||
var id = headerToId(text);
|
||||
var uniqId = uncollide(ids, id)
|
||||
ids[uniqId] = true
|
||||
setAttr(token, 'id', uniqId)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function uncollide(ids, id) {
|
||||
if (!ids[id]) return id
|
||||
var i = 1
|
||||
while (ids[id + '-' + i]) { i++ }
|
||||
return id + '-' + i
|
||||
}
|
||||
|
||||
function setAttr(token, attr, value, options) {
|
||||
var idx = token.attrIndex(attr)
|
||||
|
||||
if (idx === -1) {
|
||||
token.attrPush([attr, value])
|
||||
} else if (options && options.append) {
|
||||
token.attrs[idx][1] =
|
||||
token.attrs[idx][1] + ' ' + value
|
||||
} else {
|
||||
token.attrs[idx][1] = value
|
||||
}
|
||||
}
|
||||
|
||||
//https://github.com/rstacruz/markdown-it-named-headings/blob/master/index.js
|
||||
exports.namedHeadingsFilter = function (md, options) {
|
||||
md.core.ruler.push('named_headings', namedHeadings.bind(null, md));
|
||||
}
|
||||
|
||||
exports.headerToId = headerToId;
|
@ -117,7 +117,7 @@
|
||||
ctx.textBaseline = 'top';
|
||||
ctx.fillText(label, node.x, node.y + nodeR + 2);
|
||||
})
|
||||
.linkColor(() => getCssVar("--text-normal"))
|
||||
.linkColor(() => getCssVar("--text-muted") || getCssVar("--text-normal"))
|
||||
.graphData(gData)
|
||||
.onNodeClick(node => {
|
||||
window.location = node.url;
|
||||
|
@ -5,32 +5,53 @@
|
||||
{%if settings.dgShowLocalGraph === true%}
|
||||
<div class="graph">
|
||||
<div style="display: flex; justify-content: flex-end;">
|
||||
<div class="graph-title">Interactive graph</div>
|
||||
<div class="graph-title">Connected Pages</div>
|
||||
</div>
|
||||
<div id="link-graph"></div>
|
||||
</div>
|
||||
{%endif%}
|
||||
{%endif%}
|
||||
|
||||
{%if settings.dgShowBacklinks === true %}
|
||||
<div class="backlinks">
|
||||
<div class="backlink-title" style="margin: 4px 0 !important;">Links to this page</div>
|
||||
{%- if backlinks.length === 0 -%}
|
||||
<div class="backlink-card">
|
||||
No backlinks
|
||||
{%if settings.dgShowToc === true%}
|
||||
{%set tocHtml= (content and (content|toc)) %}
|
||||
{%if tocHtml %}
|
||||
<div class="toc">
|
||||
<div class="toc-title-container">
|
||||
<div class="toc-title">
|
||||
On this page
|
||||
</div>
|
||||
</div>
|
||||
<div class="toc-container">
|
||||
{{ tocHtml | safe }}
|
||||
</div>
|
||||
</div>
|
||||
{%- endif -%}
|
||||
{%endif%}
|
||||
|
||||
{%- for backlink in backlinks -%}
|
||||
<div class="backlink-card">
|
||||
<a href="{{backlink.url}}">{{backlink.title}}</a>
|
||||
{%endif%}
|
||||
|
||||
{%if settings.dgShowBacklinks === true %}
|
||||
<div class="backlinks">
|
||||
<div class="backlink-title" style="margin: 4px 0 !important;">Pages mentioning this page</div>
|
||||
<div class="backlink-list">
|
||||
|
||||
{%- if backlinks.length === 0 -%}
|
||||
<div class="backlink-card">
|
||||
<span class="no-backlinks-message">No other pages mentions this page</span>
|
||||
</div>
|
||||
{%- endif -%}
|
||||
|
||||
{%- for backlink in backlinks -%}
|
||||
<div class="backlink-card">
|
||||
<i class="fa fa-link"></i> <a href="{{backlink.url}}">{{backlink.title}}</a>
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
{%endif%}
|
||||
</div>
|
||||
</div>
|
||||
{%endif%}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{%if settings.dgShowLocalGraph === true %}
|
||||
{%include "components/graphScript.njk"%}
|
||||
{% endif %}
|
||||
{%if settings.dgShowLocalGraph === true %}
|
||||
{%include "components/graphScript.njk"%}
|
||||
{% endif %}
|
@ -27,7 +27,7 @@ permalink: "notes/{{ page.fileSlug | slugify }}/"
|
||||
{% endif %}
|
||||
{{ content | link | highlight | safe}}
|
||||
|
||||
{% if settings.dgShowBacklinks === true or settings.dgShowLocalGraph === true%}
|
||||
{% if settings.dgShowBacklinks === true or settings.dgShowLocalGraph === true or settings.dgShowToc === true%}
|
||||
{%include "components/sidebar.njk"%}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -4,6 +4,11 @@ const settings = require("../helpers/constants");
|
||||
|
||||
const wikilink = /\[\[(.*?\|.*?)\]\]/g
|
||||
|
||||
const markdownIt = require("markdown-it");
|
||||
const md = markdownIt({
|
||||
html: true,
|
||||
}).use(require("../helpers/utils").namedHeadingsFilter);
|
||||
|
||||
function caselessCompare(a, b) {
|
||||
return a.toLowerCase() === b.toLowerCase();
|
||||
}
|
||||
@ -111,6 +116,13 @@ module.exports = {
|
||||
return currentnote.data.page.fileSlug;
|
||||
}
|
||||
return "";
|
||||
},
|
||||
content: (data) => {
|
||||
const currentnote = data.collections.gardenEntry && data.collections.gardenEntry[0];
|
||||
if (currentnote && currentnote.template && currentnote.template.frontMatter && currentnote.template.frontMatter.content) {
|
||||
return md.render(currentnote.template.frontMatter.content);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
{%- endfor -%}
|
||||
|
||||
|
||||
{%if settings.dgShowBacklinks === true or settings.dgShowLocalGraph === true%}
|
||||
{% if settings.dgShowBacklinks === true or settings.dgShowLocalGraph === true or settings.dgShowToc === true%}
|
||||
{%include "components/sidebar.njk" %}
|
||||
{%endif%}
|
||||
</div>
|
||||
|
@ -99,6 +99,6 @@ module.exports = {
|
||||
noteSettings[setting] = settingValue;
|
||||
});
|
||||
return noteSettings;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.content {
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
@ -72,14 +73,13 @@ ul.task-list {
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
transform: translateY(calc(-50% + 75px));
|
||||
right: 0;
|
||||
height: 100%;
|
||||
min-width: 25px;
|
||||
display: flex;
|
||||
z-index: 3;
|
||||
max-width: 350px;
|
||||
margin-top: 75px;
|
||||
}
|
||||
|
||||
.expand-line {
|
||||
@ -92,11 +92,67 @@ ul.task-list {
|
||||
padding-right: 20px;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
height: 87%;
|
||||
}
|
||||
|
||||
.toc {
|
||||
padding-right: 5px;
|
||||
background-color: var(--background-primary);
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.toc-container {
|
||||
font-size: 1rem;
|
||||
max-height: 220px;
|
||||
overflow-y: auto;
|
||||
margin-bottom:10px;
|
||||
border-left: 1px solid var(--text-accent);
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding-inline-start: 15px !important;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
ul:not(:first-child) {
|
||||
margin-bottom:3px;
|
||||
}
|
||||
|
||||
li{
|
||||
padding-top: 4px;
|
||||
&::before{
|
||||
content: '# ' !important;
|
||||
color: var(--text-accent);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
a{
|
||||
text-decoration: none;
|
||||
&:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toc-title-container {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
.toc-title {
|
||||
font-size: 1.2rem !important;
|
||||
color: var(--h6-color);
|
||||
width: fit-content;
|
||||
padding: 3px 7px 3px 0;
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.backlinks {
|
||||
margin-top: 50px;
|
||||
background-color: var(--background-secondary);
|
||||
flex: 1;
|
||||
margin-top: 10px;
|
||||
background-color: var(--background-primary);
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
|
||||
@ -107,20 +163,37 @@ ul.task-list {
|
||||
}
|
||||
}
|
||||
|
||||
.backlink-list {
|
||||
border-left: 1px solid var(--text-accent);
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
overflow-x:hidden;
|
||||
}
|
||||
|
||||
.backlink-card {
|
||||
padding-bottom: 4px;
|
||||
padding-bottom: 8px;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
font-size: 1rem;
|
||||
margin-left: 10px;
|
||||
color: var(--text-accent);
|
||||
i {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.graph{
|
||||
.graph-title{
|
||||
.no-backlinks-message{
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-normal);
|
||||
}
|
||||
|
||||
.graph {
|
||||
.graph-title {
|
||||
width: fit-content;
|
||||
background-color: var(--background-secondary);
|
||||
margin: 10px 0 0 0;
|
||||
padding: 12px;
|
||||
font-size: 18px !important;
|
||||
padding: 3px 7px;
|
||||
font-size: 1.2rem !important;
|
||||
border-radius: 10px 10px 0 0;
|
||||
color: var(--h6-color);
|
||||
}
|
||||
@ -141,9 +214,10 @@ ul.task-list {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.graph{
|
||||
.graph {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.backlinks {
|
||||
margin-top: 0;
|
||||
}
|
||||
@ -152,24 +226,24 @@ ul.task-list {
|
||||
.filetree-sidebar {
|
||||
margin: 0;
|
||||
z-index: 10;
|
||||
padding: 10px;
|
||||
top:0px;
|
||||
left:0;
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
background-color: var(--background-secondary);
|
||||
color: var(--text-muted);
|
||||
overflow-y:auto;
|
||||
padding: 10px;
|
||||
top: 0px;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
background-color: var(--background-secondary);
|
||||
color: var(--text-muted);
|
||||
overflow-y: auto;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.empty-navbar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: -60px;
|
||||
|
||||
@media(max-width: 800px) {
|
||||
justify-content: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.search-button {
|
||||
@ -191,12 +265,12 @@ ul.task-list {
|
||||
align-items: center;
|
||||
|
||||
.navbar-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.search-button{
|
||||
.search-button {
|
||||
|
||||
@media(max-width: 800px) {
|
||||
min-width: 120px;
|
||||
@ -207,6 +281,11 @@ ul.task-list {
|
||||
|
||||
.notelink {
|
||||
padding: 5px 0 5px 25px;
|
||||
a{
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.foldername-wrapper {
|
||||
@ -219,31 +298,31 @@ ul.task-list {
|
||||
}
|
||||
|
||||
.filelist {
|
||||
border-left: 1px solid var(--text-accent);
|
||||
}
|
||||
|
||||
.notelink.active-note{
|
||||
a{
|
||||
.notelink.active-note {
|
||||
a {
|
||||
color: var(--text-accent);
|
||||
}
|
||||
|
||||
color: var(--text-accent);
|
||||
background-color: var(--background-primary);
|
||||
transform: translateX(10px);
|
||||
}
|
||||
|
||||
.fullpage-overlay{
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
position: absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
left:0;
|
||||
bottom:0;
|
||||
.fullpage-overlay {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 5
|
||||
}
|
||||
|
||||
|
||||
.search-container {
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
@ -279,6 +358,7 @@ ul.task-list {
|
||||
color: var(--text-primary);
|
||||
|
||||
}
|
||||
|
||||
.search-box input:focus {
|
||||
outline: none;
|
||||
}
|
||||
@ -317,6 +397,7 @@ ul.task-list {
|
||||
color: var(--text-secondary);
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.search-link {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
@ -333,14 +414,16 @@ ul.task-list {
|
||||
margin: 10px 65px;
|
||||
border: 1px solid var(--text-normal);
|
||||
cursor: pointer;
|
||||
>span{
|
||||
|
||||
>span {
|
||||
padding: 3px 3px 3px 10px;
|
||||
}
|
||||
>i{
|
||||
|
||||
>i {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
&:hover{
|
||||
&:hover {
|
||||
border: 1px solid var(--text-accent);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user