From 1e6f7a276688d00f222dbe2fa0f189ed3deff3aa Mon Sep 17 00:00:00 2001 From: ache Date: Mon, 2 May 2022 02:08:35 +0200 Subject: New version of ache.one --- src/build/index.mjs | 83 + src/build/list-articles.mjs | 7 + src/build/load-svg.mjs | 17 + src/build/remove-footnote-header.mjs | 17 + src/build/rss.mjs | 42 + src/build/special_box.mjs | 24 + src/build/to-html.mjs | 47 + src/css/_contenu.scss | 201 +- src/css/_sommaire.scss | 57 +- src/css/_style.scss | 2 +- src/css/design.scss | 36 +- src/img/ache.ico | Bin 0 -> 1094 bytes src/img/ache.svg | 27 + src/img/computer.svg | 13214 ++++++++++++++++++++++++++++++++ src/img/favicon.ico | Bin 0 -> 1094 bytes src/img/git.svg | 3 + src/img/ic_attention_black_48px.svg | 5 + src/img/ic_bad_black_48px.svg | 4 + src/img/ic_comment_black_48px.svg | 5 + src/img/ic_good_black_48px.svg | 5 + src/img/ic_information_black_48px.svg | 5 + src/img/ic_question_black_48px.svg | 5 + src/img/lab.svg | 153 + src/img/lt.svg | 30 + src/img/masto.svg | 1 + src/img/rss.svg | 10 + src/img/twitter.svg | 5 + src/js/sidenotes.js | 70 + src/templates/article.tmpl | 16 + src/templates/header.tmpl | 14 + src/templates/index.tmpl | 19 + src/templates/left.tmpl | 28 + src/templates/parent.tmpl | 13 + src/templates/son.tmpl | 9 + 34 files changed, 14065 insertions(+), 109 deletions(-) create mode 100644 src/build/index.mjs create mode 100644 src/build/list-articles.mjs create mode 100644 src/build/load-svg.mjs create mode 100644 src/build/remove-footnote-header.mjs create mode 100644 src/build/rss.mjs create mode 100644 src/build/special_box.mjs create mode 100644 src/build/to-html.mjs create mode 100644 src/img/ache.ico create mode 100644 src/img/ache.svg create mode 100644 src/img/computer.svg create mode 100644 src/img/favicon.ico create mode 100644 src/img/git.svg create mode 100644 src/img/ic_attention_black_48px.svg create mode 100644 src/img/ic_bad_black_48px.svg create mode 100644 src/img/ic_comment_black_48px.svg create mode 100644 src/img/ic_good_black_48px.svg create mode 100644 src/img/ic_information_black_48px.svg create mode 100644 src/img/ic_question_black_48px.svg create mode 100755 src/img/lab.svg create mode 100644 src/img/lt.svg create mode 100644 src/img/masto.svg create mode 100755 src/img/rss.svg create mode 100644 src/img/twitter.svg create mode 100644 src/js/sidenotes.js create mode 100644 src/templates/article.tmpl create mode 100644 src/templates/header.tmpl create mode 100644 src/templates/index.tmpl create mode 100644 src/templates/left.tmpl create mode 100644 src/templates/parent.tmpl create mode 100644 src/templates/son.tmpl (limited to 'src') diff --git a/src/build/index.mjs b/src/build/index.mjs new file mode 100644 index 0000000..84d4d9a --- /dev/null +++ b/src/build/index.mjs @@ -0,0 +1,83 @@ +import fs from 'node:fs'; +import mustache from 'mustache'; +import {u} from 'unist-builder'; +import {select} from 'hast-util-select'; +import {toString as hastToString} from 'mdast-util-to-string'; + +import {toHtmlRaw, toString} from './to-html.mjs'; +import loadSVG from './load-svg.mjs'; +import listArticles from './list-articles.mjs'; +import getRSS from './rss.mjs'; + +const loadMD = (listFile, suffix) => { + const listContent = []; + for (const file of listFile) { + const content = fs.readFileSync(`${suffix}/${file}`, 'utf8'); + const htmlContent = toHtmlRaw(content); + const htmlRender = toString(htmlContent); + + const titleHtml = select('h1', htmlContent); + const intro = select('p', htmlContent); + const logo = select('img', htmlContent); + logo.properties.src = `${suffix}/${logo.properties.src}`; + titleHtml.children[0].properties.href = `${suffix}/${file.slice(0, -3)}.html`; + + const title = hastToString(titleHtml); + const domTitle = title.replace(/\s+/g, '-').toLowerCase(); // Maybe encodeURI + console.log(`Create : ${title}`); + + listContent.push({ + name: file.slice(0, -3), + content: htmlRender, + intro: toString(u('root', [titleHtml, intro])), + introDesc: hastToString(intro), + imageUrl: logo.properties.src, + title, + domTitle, + }); + } + + return listContent; +}; + +const leftPanelTmpl = fs.readFileSync('src/templates/left.tmpl', 'utf8'); +const headerTmpl = fs.readFileSync('src/templates/header.tmpl', 'utf8'); +const articleTmpl = fs.readFileSync('src/templates/article.tmpl', 'utf8'); +const indexTmpl = fs.readFileSync('src/templates/index.tmpl', 'utf8'); + +const partials = { + header: headerTmpl, + leftPanel: leftPanelTmpl, +}; + +const svg = loadSVG(); + +const articles = loadMD(listArticles, 'articles'); + +for (const article of articles) { + const context = { + svg, + title: `${article.title} - ache`, + content: article.content, + domTitle: article.domTitle, + }; + const output = mustache.render(articleTmpl, context, partials); + + fs.writeFileSync(`articles/${article.name}.html`, output); +} + +console.log('Create : rss.xml'); +const xmlFeed = getRSS(articles); +fs.writeFileSync('rss.xml', xmlFeed); + +{ + const context = { + title: 'ache: Blog personnel', + svg, + articles, + }; + + console.log('Create : Home page'); + const output = mustache.render(indexTmpl, context, partials); + fs.writeFileSync('index.html', output); +} diff --git a/src/build/list-articles.mjs b/src/build/list-articles.mjs new file mode 100644 index 0000000..d327573 --- /dev/null +++ b/src/build/list-articles.mjs @@ -0,0 +1,7 @@ +const listArticles = [ + 'bizarreries-du-langage-c.md', + 'retour-sur-laoc-2021-semaine-1.md', + '2FA-discord-sur-pc.md', + 'duckduckgo-google-en-mieux.md', +]; +export default listArticles; diff --git a/src/build/load-svg.mjs b/src/build/load-svg.mjs new file mode 100644 index 0000000..6bf8db4 --- /dev/null +++ b/src/build/load-svg.mjs @@ -0,0 +1,17 @@ +import fs from 'node:fs'; + +const loadSVG = () => { + const svg = {}; + + for (const file of fs.readdirSync('s/imgM')) { + if (file.endsWith('.svg')) { + const contentFile = fs.readFileSync(`s/imgM/${file}`, 'utf8'); + const name = file.slice(0, -'.svg'.length); + svg[name] = contentFile; + } + } + + return svg; +}; + +export default loadSVG; diff --git a/src/build/remove-footnote-header.mjs b/src/build/remove-footnote-header.mjs new file mode 100644 index 0000000..a238692 --- /dev/null +++ b/src/build/remove-footnote-header.mjs @@ -0,0 +1,17 @@ +import {visit} from 'unist-util-visit'; + +// This plugin is an example to let users write HTML with directives. +// It’s informative but rather useless. +// See below for others examples. +/** @type {import('unified').Plugin<[], import('mdast').Root>} */ +export default function specialBox() { + return tree => { + visit(tree, node => { + if (node?.tagName === 'h2' && node?.properties?.id === 'footnote-label') { + node.tagName = 'hr'; + node.children = []; // Exposure of children, Roman's way + } + }); + }; +} + diff --git a/src/build/rss.mjs b/src/build/rss.mjs new file mode 100644 index 0000000..606cdef --- /dev/null +++ b/src/build/rss.mjs @@ -0,0 +1,42 @@ +import RSS from 'rss'; + +const siteUrl = 'https://ache.one'; + +const getRSS = articles => { + const rssFeed = new RSS({ + title: 'ache: Blog personnel', + description: 'Programmation, Algorithmique, Système, *pick you poison*', + // eslint-disable-next-line camelcase + feed_url: `${siteUrl}/feed.xml`, + // eslint-disable-next-line camelcase + site_url: siteUrl, + // eslint-disable-next-line camelcase + image_url: `${siteUrl}/ache.svg`, + language: 'fr', + pubDate: (new Date().toLocaleString()), + ttl: '1440', + // eslint-disable-next-line camelcase + custom_elements: [''], + }); + + for (const article of articles.slice(0, 10)) { + rssFeed.item({ + title: article.title, + description: '
' + article.content + '
', + // eslint-disable-next-line camelcase + image_url: article.imageUrl, + url: `${siteUrl}/articles/${article.domTitle}`, + guid: article.domTitle, + author: 'ache', + // eslint-disable-next-line camelcase + custom_elements: [ + {logo: article.imageUrl}, + {intro: article.introDesc}, + ], + }); + } + + return rssFeed.xml({indent: false}).replace(/<\?xml version="1.0" encoding="UTF-8"\?>/g, ''); +}; + +export default getRSS; diff --git a/src/build/special_box.mjs b/src/build/special_box.mjs new file mode 100644 index 0000000..0b284ec --- /dev/null +++ b/src/build/special_box.mjs @@ -0,0 +1,24 @@ +import {visit} from 'unist-util-visit'; + +// This plugin is an example to let users write HTML with directives. +// It’s informative but rather useless. +// See below for others examples. +/** @type {import('unified').Plugin<[], import('mdast').Root>} */ +export default function specialBox() { + return tree => { + visit(tree, node => { + if (node.type === 'containerDirective' && ( + node.name === 'attention' + || node.name === 'question' + || node.name === 'information')) { + const data = node.data || (node.data = {}); + + data.hName = 'div'; + data.hProperties = { + className: 'special-box ' + node.name, + }; + } + }); + }; +} + diff --git a/src/build/to-html.mjs b/src/build/to-html.mjs new file mode 100644 index 0000000..d8c3a84 --- /dev/null +++ b/src/build/to-html.mjs @@ -0,0 +1,47 @@ +import {unified} from 'unified'; +import remarkParse from 'remark-parse'; +import remarkGfm from 'remark-gfm'; +import remarkToc from 'remark-toc'; +import remarkDirective from 'remark-directive'; +import remarkMath from 'remark-math'; +import remarkRehype from 'remark-rehype'; +import rehypeSlug from 'rehype-slug'; +import rehypeKaTeX from 'rehype-katex'; +import rehypeRaw from 'rehype-raw'; +import rehypeAutolinkHeadings from 'rehype-autolink-headings'; +import rehypeStringify from 'rehype-stringify'; +import rehypeHighlight from 'rehype-highlight'; +import {h} from 'hastscript'; +import remarkSpecialBox from './special_box.mjs'; +import remarkRemoveFootnoteHeader from './remove-footnote-header.mjs'; + +const autoLinkOption = { + behavior: 'wrap', + properties: { + ariaHidden: true, + tabIndex: -1, + className: 'anchor', + }, +}; + +const generator = unified() + .use(remarkParse) + .use(remarkGfm) + .use(remarkToc, {heading: 'Sommaire', tight: true, ordered: true}) + .use(remarkMath) + .use(remarkDirective) + .use(remarkSpecialBox) + .use(remarkRehype, {allowDangerousHtml: true}) + .use(rehypeRaw) + .use(remarkRemoveFootnoteHeader) + .use(rehypeKaTeX) + .use(rehypeSlug) + .use(rehypeHighlight) + .use(rehypeAutolinkHeadings, autoLinkOption) + .use(rehypeStringify); + +const toHtml = content => generator.processSync(content); + +export const toHtmlRaw = content => generator.runSync(generator.parse(content)); +export const toString = content => generator.stringify(content); +export default toHtml; diff --git a/src/css/_contenu.scss b/src/css/_contenu.scss index f9f81c9..45639fb 100755 --- a/src/css/_contenu.scss +++ b/src/css/_contenu.scss @@ -1,50 +1,73 @@ article { - margin-right: 2%; - margin-left: 3%; - float: left; - width: 83%; +/* + margin-left: #{"max(0px, (100vw - var(--width_panel) - 10px - 950px - 6vw - 2px - 15px)*11/24)"}; + margin-right: #{"max(0px, (100vw - var(--width_panel) - 10px - 950px - 6vw - 2px - 15px)*13/24)"}; +*/ + margin: auto auto 0 2.5%; + background: #FFF; - margin-bottom: 2.5%; - padding-right: 0; - padding-left: 0; padding: 1.6em 1.6em; - font-family: Merriweather, "Liberation Serif", "Segoe UI"; + font-family: "noto serif", 'Georgia', serif; position: relative; max-width: 950px; ; + line-height: 1.6rem; .pubdate { position: absolute; top: 0; right: 0; - padding: 55px 10px; + margin: 55px 10px; transform: rotate(20deg); text-shadow: 1px 1px 0.2px green; + overflow: clip; color: pink; text-align: right; } ul { line-height: 1.6; } - code { - color: #a00; - background: #eee; - border: 1px solid #ccc; - padding: 0 5px; - font-weight: 630; + + h1 { + font-size: 3rem; + line-height: 3rem; + color: #605; + } + h2 { + font-size: 2rem; + line-height: 3rem; + color: #551; + } + h3 { + font-size: 1.6rem; + line-height: 3rem; + color: #660; } + .anchor { + user-select: none; + text-decoration: none; + color: inherit; + &:link { + text-decoration: none; + color: inherit; + } + &:visited { + text-decoration: none; + color: inherit; + } + } + + @media #{$gt-gsm} { ul { line-height: 1.4; } float: none; - margin-right: auto; - margin-left: auto; width: auto; - padding-right: 4vh; - padding-left: 4vh; + padding-right: 3vw; + padding-left: 3vw; border: 1px solid #eaeaea; border: 1px solid rgba(51, 51, 51, 0.1); @@ -73,7 +96,6 @@ article { list-style-type: lower-roman; } } - .footnotes { color: #777; font-size: 0.8em; @@ -86,85 +108,65 @@ article { } } - font-size: 1.3em; - h1 { - font-size: 2.2em; - color: #A5B; - } - h2 { - font-size: 1.9em; - color: #BB8; - } - h3 { - font-size: 1.6em; - color: #AC4; - } - h2:before { - content: "# "; - color: #ABB; - font: bold 1.3em arial, sans-serif; - } - h3:before { - content: "## "; - color: #ABB; - font: bold 1.2em arial, sans-serif; - } - h4:before { - content: "### "; - color: #ABB; - font: bold 1.1em arial, sans-serif; + font-size: 1.3rem; + h1 h2 h3 { + line-height: initial; } - @media #{$gt-gsm} { - font-size: 1.1em; - h1 { - font-size: 2em; - color: #A5B; - } - h2 { - font-size: 1.5em; - color: #BB8; - } - h3 { - font-size: 1.25em; - color: #AC4; - } - h2:before { - content: "# "; - color: #ABB; - font: bold 0.95em arial, sans-serif; + + + @media #{$gsm} { + margin: 0; + padding: 50px 5px; + width: calc(100% - 10px); + font-size: 1rem; + code { + font-size: 0.9rem; } - h3:before { - content: "## "; - color: #ABB; - font: bold 0.95em arial, sans-serif; + } + + @mixin darkMode { + background-color: #1C1C1C; + h1, h2, h3, h4, h5 { + color: #EFEFEF; + text-indent: -10px; } - h4:before { - content: "### "; - color: #ABB; - font: bold 1em arial, sans-serif; + img { + filter: invert(1); } + color: #EFEFEF; } + @media (prefers-color-scheme: dark) { @include darkMode; } &.dark { @include darkMode; } } + section { > p:nth-of-type(1):after { content: " "; display: table; clear: both; } - > p:nth-of-type(1) > img { - height: 150px; - float: right; - } - - @media #{$gt-gsm} { - > p:first-of-type { + > p:first-of-type { + color: #944040; + > img { + height: 150px; + float: right; + } + @media #{$gt-gsm} { margin-top: 2.5%; margin-bottom: 2.5%; padding-left: 6%; - color: #944040; } } + + @mixin darkMode { + > p:first-of-type { + color: #6bbfbf; + > img { + filter: invert(0); + } + } + } + @media (prefers-color-scheme: dark) { @include darkMode; } &.dark { @include darkMode; } } .keybs { border: 1px solid gray; @@ -178,3 +180,40 @@ section { white-space: nowrap; } +.marge { + display: block; +} +.marge { + @media #{$tab} { + display: none; + } +} +.sidenotes { + @media #{$tab} { + display: none; + } + + @mixin darkMode { + color: #eee; + } + @media (prefers-color-scheme: dark) { @include darkMode; } &.dark { @include darkMode; } + margin: 0 20px; + transition: width 0.25s ease-out 0.25s; + position: relative; + max-width: 600px; + p { + margin: 0; + } + .sidenote { + position: absolute; + font-style: oblique; + font-size: 1.05rem; + } +} +code { + color: #a00; + background: #eee; + border: 0px; + border-radius: 8px; + padding: 0 5px; +} diff --git a/src/css/_sommaire.scss b/src/css/_sommaire.scss index 15947ef..68d43a0 100755 --- a/src/css/_sommaire.scss +++ b/src/css/_sommaire.scss @@ -1,7 +1,6 @@ .sommaire_blien { - display: inline-block; - width: 33%; text-align: left; + line-height: 1.45rem; color: #121311; font-size: 0.8em; font-weight: bold; @@ -22,20 +21,39 @@ } #side-bar { - text-align: center; - display: block; - height: auto; - text-rendering: optimizelegibility; - box-sizing: border-box; - background: #F5F6F5; - padding-top: 10px; + ul { + columns: 2; + list-style-type: none; + } + + @mixin darkMode { + background: #101110; + color: #FFF; + #logo-ache { + filter: invert(1); + } + #desc_intro { + text-shadow: 2px 4px 0 #333; + } + .about_bar { + } + .sommaire_blien { + text-shadow: 0 1px 0 #444; + color: #F5F5F5; + a { + color: #F5F5F5; + } + } + .about { + color: #BBB; + } + } + @media (prefers-color-scheme: dark) { @include darkMode; } &.dark { @include darkMode; } + + h1 { font-family: monospace, "Helvetica Neue", Arial, sans-serif; - - /* - font-family: "PT Sans","Helvetica Neue",Helvetica,Arial,sans-serif; - */ } svg { margin: 0 auto; @@ -50,10 +68,6 @@ transition: left 0.5s ease-in 0.25s; text-align: center; - /* - background: none repeat scroll 0% 0% #F5F6F5; - */ - background: #FFF; border-right: 3px solid rgba(51, 51, 51, 0.1); &.hidden { @@ -94,7 +108,7 @@ @keyframes typing { 0% { width: 0; - } + }; } .about_bar { display: inline-block; @@ -116,19 +130,16 @@ @media screen and (max-height: 519px) { visibility: hidden; } - padding-left: 0; position: absolute; bottom: 0px; left: 0px; + width: var(--width_panel); + ul { - position: initial; - width: 30vh; padding-left: 0; display: flex; justify-content: space-evenly; - li { - } } } } diff --git a/src/css/_style.scss b/src/css/_style.scss index 6b90d1f..1c8c9b7 100644 --- a/src/css/_style.scss +++ b/src/css/_style.scss @@ -42,7 +42,7 @@ blockquote { font-family: monospace, serif; font-size: 14px; &:before { - background-image: url("/s/img/ic_" + $name + "_black_48px.svg"); + background-image: url("/s/imgM/ic_" + $name + "_black_48px.svg"); } } } diff --git a/src/css/design.scss b/src/css/design.scss index 8a1f33b..91c3e44 100755 --- a/src/css/design.scss +++ b/src/css/design.scss @@ -1,14 +1,22 @@ -$gsm: "screen and (max-width: 768px)"; -$tab: "screen and (max-width: 1024px)"; -$gt-gsm: "screen and (min-width: 768px)"; +$gsm: "screen and (max-width: 768px)"; +$gt-gsm: "screen and (min-width: 768px)"; +$tab: "screen and (max-width: 1024px)"; +$laptop: "screen and (min-width: 1024px)"; +$big-laptop: "screen and (min-width: 1400px)"; +$big-screen: "screen and (min-width: 1720px)"; @import 'contenu'; @import 'sommaire'; @import 'style'; @import 'rainbow'; + html { background: #f1f1f1; + @mixin darkMode { + background: #222; + } + @media (prefers-color-scheme: dark) { @include darkMode; } &.dark { @include darkMode; } } /* @@ -22,7 +30,6 @@ html { */ body { - font-family: 'Noto Serif', Verdana, "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; margin: 0; line-height: 1.35; color: #333333; @@ -36,6 +43,16 @@ body { } #side-bar { + box-sizing: border-box; + + @mixin lightMode { + background: #F5F6F5; + } + @media (prefers-color-scheme: light) { @include lightMode; } &.dark { @include lightMode; } + padding-top: 10px; + + + text-rendering: optimizelegibility; width: var(--width_panel); left: calc(var(--width_panel_bis) - var(--width_panel); transition: width 1s ease-in-out 1s; @@ -50,6 +67,9 @@ body { cursor: pointer; } .hide_arrow { + @media (prefers-color-scheme: dark) { filter: invert(1); } + &.dark { filter: invert(1); } + position: fixed; display: none; top: 30%; @@ -122,3 +142,11 @@ table, th, td { text-shadow: 0 1px 0 #DDD; } +.decal_panel { + @media #{$big-laptop} { + display: grid; + grid-template-columns: #{"max(0px, (100vw - var(--width_panel_bis) - 10px - 950px - 6vw - 2px - 15px)*7/24)"} auto #{"max(0px, (100vw - var(--width_panel_bis) - 10px - 950px - 6vw - 2px - 15px)*17/24)"}; + } + transition: margin-left 0.25s ease-out 0.25s, grid-template-columns 0.25s ease-out 0.25s; +} + diff --git a/src/img/ache.ico b/src/img/ache.ico new file mode 100644 index 0000000..ba2b618 Binary files /dev/null and b/src/img/ache.ico differ diff --git a/src/img/ache.svg b/src/img/ache.svg new file mode 100644 index 0000000..f797c03 --- /dev/null +++ b/src/img/ache.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/computer.svg b/src/img/computer.svg new file mode 100644 index 0000000..8ed3927 --- /dev/null +++ b/src/img/computer.svg @@ -0,0 +1,13214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/favicon.ico b/src/img/favicon.ico new file mode 100644 index 0000000..ba2b618 Binary files /dev/null and b/src/img/favicon.ico differ diff --git a/src/img/git.svg b/src/img/git.svg new file mode 100644 index 0000000..1ddbe4e --- /dev/null +++ b/src/img/git.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/img/ic_attention_black_48px.svg b/src/img/ic_attention_black_48px.svg new file mode 100644 index 0000000..d8eb238 --- /dev/null +++ b/src/img/ic_attention_black_48px.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/img/ic_bad_black_48px.svg b/src/img/ic_bad_black_48px.svg new file mode 100644 index 0000000..0b02d88 --- /dev/null +++ b/src/img/ic_bad_black_48px.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/img/ic_comment_black_48px.svg b/src/img/ic_comment_black_48px.svg new file mode 100644 index 0000000..e0d89e2 --- /dev/null +++ b/src/img/ic_comment_black_48px.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/img/ic_good_black_48px.svg b/src/img/ic_good_black_48px.svg new file mode 100644 index 0000000..0995688 --- /dev/null +++ b/src/img/ic_good_black_48px.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/img/ic_information_black_48px.svg b/src/img/ic_information_black_48px.svg new file mode 100644 index 0000000..266453e --- /dev/null +++ b/src/img/ic_information_black_48px.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/img/ic_question_black_48px.svg b/src/img/ic_question_black_48px.svg new file mode 100644 index 0000000..c92b2ad --- /dev/null +++ b/src/img/ic_question_black_48px.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/img/lab.svg b/src/img/lab.svg new file mode 100755 index 0000000..32db14d --- /dev/null +++ b/src/img/lab.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/lt.svg b/src/img/lt.svg new file mode 100644 index 0000000..253bca5 --- /dev/null +++ b/src/img/lt.svg @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/src/img/masto.svg b/src/img/masto.svg new file mode 100644 index 0000000..1e057ad --- /dev/null +++ b/src/img/masto.svg @@ -0,0 +1 @@ +Mastodon Logo diff --git a/src/img/rss.svg b/src/img/rss.svg new file mode 100755 index 0000000..1d8e286 --- /dev/null +++ b/src/img/rss.svg @@ -0,0 +1,10 @@ + + + + RSS feed icon + + + + + + \ No newline at end of file diff --git a/src/img/twitter.svg b/src/img/twitter.svg new file mode 100644 index 0000000..017e4bd --- /dev/null +++ b/src/img/twitter.svg @@ -0,0 +1,5 @@ + + Twitter Logo + + + diff --git a/src/js/sidenotes.js b/src/js/sidenotes.js new file mode 100644 index 0000000..00c9367 --- /dev/null +++ b/src/js/sidenotes.js @@ -0,0 +1,70 @@ +'use strict'; + +function getPos(element) { + /* Element.getBoundingClientRect() + * Return box of the element relatively to viewport. + */ + const rect = element.getBoundingClientRect(); + + /* The properties window.scrollX and window.scrollY + * return the viewport position relatively to the document + */ + return { + x: rect.left + window.scrollX, + y: rect.top + window.scrollY, + }; +} + +const getTop = element => element.offsetTop + (element.offsetParent && getTop(element.offsetParent)); + +const resize = () => { + const sidenotes = document.querySelectorAll('.sidenotes'); + + console.log('Sidenote width: ' + sidenotes.offsetWidth); + for (const sidenote of sidenotes) { + if (sidenote.offsetWidth < 100 || window.screen.width < 1400) { + sidenote.innerHTML = ''; + return; + } + + const articleRef = sidenote.attributes.for.value; + const article = document.querySelector(`#${articleRef}`); + const notes = Array.from(article.querySelectorAll('li')) + .filter(element => element.id.startsWith('user-content-fn')); + const newSidenotes = notes.map(sidenoteLi => { + const div = document.createElement('div'); + const refName = sidenoteLi.querySelector('.data-footnote-backref').attributes.href.value; + const refSideNode = article.querySelector(refName); + + const sup = document.createElement('sup'); + sup.textContent = refSideNode.textContent + ' '; + + for (const element of sidenoteLi.children) { + const child = element.cloneNode(true); + div.append(child); + } + + div.children[0].prepend(sup); + div.style.top = `${getPos(refSideNode).y}px`; + div.classList.add('sidenote'); + + return div; + }); + + sidenote.replaceChildren(...newSidenotes); + + if (sidenote.offsetWidth < 100 || window.screen.width < 1400) { + sidenote.innerHTML = ''; + return; + } + } +}; + +window.addEventListener('resize', resize); + +window.addEventListener('DOMContentLoaded', resize); +window.addEventListener('DOMContentLoaded', () => { + if(document.querySelectorAll('.math-display').length > 0) { + document.head.innerHTML += ''; + } +}); diff --git a/src/templates/article.tmpl b/src/templates/article.tmpl new file mode 100644 index 0000000..7481a59 --- /dev/null +++ b/src/templates/article.tmpl @@ -0,0 +1,16 @@ + + + {{> header }} + +
+
+
+
+ {{{ content }}} +
+
+
+
+ {{> leftPanel }} + + diff --git a/src/templates/header.tmpl b/src/templates/header.tmpl new file mode 100644 index 0000000..d30cae8 --- /dev/null +++ b/src/templates/header.tmpl @@ -0,0 +1,14 @@ + + + {{ title }} + + + + + + + + + diff --git a/src/templates/index.tmpl b/src/templates/index.tmpl new file mode 100644 index 0000000..cabaf7f --- /dev/null +++ b/src/templates/index.tmpl @@ -0,0 +1,19 @@ + + + + {{>header }} + + {{#articles}} +
+
+
+
+ {{{ intro }}} +
+
+
+
+ {{/articles}} + {{> leftPanel }} + + diff --git a/src/templates/left.tmpl b/src/templates/left.tmpl new file mode 100644 index 0000000..985f356 --- /dev/null +++ b/src/templates/left.tmpl @@ -0,0 +1,28 @@ + + diff --git a/src/templates/parent.tmpl b/src/templates/parent.tmpl new file mode 100644 index 0000000..dcf9211 --- /dev/null +++ b/src/templates/parent.tmpl @@ -0,0 +1,13 @@ +{% block header %} +This is the default content +{% endblock %} + +
+ {% block left %}{% endblock %} +
+ +
+ {% block right %} + This is more content + {% endblock %} +
diff --git a/src/templates/son.tmpl b/src/templates/son.tmpl new file mode 100644 index 0000000..9b16c70 --- /dev/null +++ b/src/templates/son.tmpl @@ -0,0 +1,9 @@ +{% extends "parent.html" %} + +{% block left %} +This is the left side! +{% endblock %} + +{% block right %} +This is the right side! +{% endblock %} -- cgit v1.2.3