summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorache <ache@ache.one>2024-08-10 06:47:41 +0200
committerache <ache@ache.one>2024-08-10 06:47:41 +0200
commitdb6f518520f82288884bc2049e41b45ec41e9c57 (patch)
tree77e321d48f2f9fb61b4b85af4ebd5dd569fbc00a
parentUpdate smol-toml (diff)
Support for notes
-rw-r--r--src/build/index.mjs48
-rw-r--r--src/build/loadMD.mjs5
-rwxr-xr-xsrc/css/_contenu.scss316
-rw-r--r--src/js/love.js2
-rw-r--r--src/templates/tag.tmpl13
5 files changed, 287 insertions, 97 deletions
diff --git a/src/build/index.mjs b/src/build/index.mjs
index cb918b7..6a05fae 100644
--- a/src/build/index.mjs
+++ b/src/build/index.mjs
@@ -33,48 +33,58 @@ const svg = loadSVG();
let links = [];
+const listNotes = fs
+ .readdirSync("notes")
+ .filter((name) => name.endsWith(".md"));
+const notesAll = loadMD(listNotes, "notes"); // lang is determined from the note
+
for (const lang in i18n) {
const tagsArticle = new Map();
const filter = process.argv.slice(2);
- const listArticle =
+ const listArticles =
filter.length > 0
? i18n[lang].articles.filter((article) => filter.includes(article.name))
: i18n[lang].articles;
- const articles = loadMD(listArticle, "articles", lang);
+ const articles = loadMD(listArticles, "articles", lang);
+
+ // Same for notes
+ const notes = notesAll.filter((note) => note.metaData.lang == lang);
- for (const article of articles) {
+ for (const post of [...articles, ...notes]) {
const context = {
svg,
- page_title: `${article.title} - ache`,
+ page_title: `${post.title} - ache`,
title: i18n[lang].title,
intro: i18n[lang].intro,
lang,
- canonical: `${baseUrl}${article.url.slice(1)}`,
- content: article.content,
+ canonical: `${baseUrl}${post.url.slice(1)}`,
+ content: post.content,
title: i18n[lang].title,
- metaData: article.metaData,
- alt_lang: addDescription(article.metaData.alt_lang),
- description: article.intro,
+ metaData: post.metaData,
+ alt_lang: addDescription(post.metaData.alt_lang),
+ description: post.intro,
like_title: i18n[lang].like_title,
like_text: i18n[lang].like_text,
};
const output = mustache.render(articleTmpl, context, partials);
- console.log(`Create : ${article.title}`);
- fs.writeFileSync(`articles/${article.name}.html`, minifyHTML(output));
+ console.log(`Create : ${post.title}`);
+ const type = post.metaData?.type || "article";
+ fs.writeFileSync(`${type}s/${post.name}.html`, minifyHTML(output));
links.push({
url: context.canonical,
changefreq: "yearly",
priority: 0.6,
- img: [{ url: article.imageUrl }],
+ img: [{ url: post?.imageUrl }],
});
- for (const tag of article.metaData.tags) {
+ for (const tag of post.metaData.tags) {
+ // Insert the tag, if it already exists add it, otherwise create a object for it.
if (tagsArticle.has(tag)) {
- tagsArticle.get(tag).push(article);
+ tagsArticle.get(tag).push(post);
} else {
- tagsArticle.set(tag, [article]);
+ tagsArticle.set(tag, [post]);
}
}
}
@@ -87,9 +97,12 @@ for (const lang in i18n) {
fs.mkdirSync(`${lang}/tag`, { recursive: true });
}
- for (const [tag, articles] of tagsArticle.entries()) {
+ for (const [tag, material] of tagsArticle.entries()) {
console.log(`Create tag page : ${lang}/${tag}.html`);
- articles.sort(cmpArticles);
+ material.sort(cmpArticles);
+
+ const articles = material.filter((item) => item.metaData.type != "note");
+ const notes = material.filter((item) => item.metaData.type == "note");
const context = {
svg,
@@ -99,6 +112,7 @@ for (const lang in i18n) {
lang,
tag,
articles,
+ notes,
description: `${i18n[lang]["tag_desc"]} ${tag}.`,
};
diff --git a/src/build/loadMD.mjs b/src/build/loadMD.mjs
index a1eab3b..8153d37 100644
--- a/src/build/loadMD.mjs
+++ b/src/build/loadMD.mjs
@@ -20,6 +20,8 @@ const loadMD = (listFile, suffix, lang) => {
const metaData = toml.parse(tomlStringValue);
const newHTML = mdToHtmlRaw(mdRaw);
+ const langR = lang || metaData.lang;
+
const htmlContent = newHTML;
const htmlRender = toString(htmlContent);
@@ -51,7 +53,8 @@ const loadMD = (listFile, suffix, lang) => {
.toLowerCase(),
); // Maybe encodeURI
- const readMore = h("a", i18n[lang]["read_more"]);
+ console.log(langR);
+ const readMore = h("a", i18n[langR]["read_more"]);
readMore.properties.href = `/${suffix}/${file.slice(0, -3)}`;
const pubYear = getArticleYear({ metaData });
diff --git a/src/css/_contenu.scss b/src/css/_contenu.scss
index ee809ca..c05bbfa 100755
--- a/src/css/_contenu.scss
+++ b/src/css/_contenu.scss
@@ -12,17 +12,24 @@ article {
text-align: right;
line-height: 1.65;
}
+
ul {
line-height: 1.6;
}
- h1, h2, h3 {
+ h1,
+ h2,
+ h3 {
font-family: Palatino Linotype, Bookman Old Style, Fira Code, get a font bro, Times;
}
- h1, h2, h3, h4 {
+ h1,
+ h2,
+ h3,
+ h4 {
margin: 2.5rem 0 1rem 0;
}
+
p {
margin: 0.5rem 0;
}
@@ -32,14 +39,17 @@ article {
line-height: 3rem;
margin: 0.5rem 0;
}
+
h2 {
font-size: 1.6rem;
line-height: 3rem;
}
+
h3 {
font-size: 1.3rem;
line-height: 3rem;
}
+
h4 {
font-size: 1.1rem;
line-height: 3rem;
@@ -53,32 +63,38 @@ article {
&:link {
color: inherit;
}
+
&:visited {
color: inherit;
}
- &:hover, &:focus {
+
+ &:hover,
+ &:focus {
text-decoration: underline;
}
}
- > p:first-of-type {
- > img {
- height: 150px;
- width: 150px;
- float: right;
- position: relative;
- top: -25px;
- }
- > img:not([src$="-inv.svg"]) {
- filter: revert;
- }
- > picture {
- height: 150px;
- width: 150px;
- float: right;
- position: relative;
- top: -25px;
- }
+ >p:first-of-type {
+ >img {
+ height: 150px;
+ width: 150px;
+ float: right;
+ position: relative;
+ top: -25px;
+ }
+
+ >img:not([src$="-inv.svg"]) {
+ filter: revert;
+ }
+
+ >picture {
+ height: 150px;
+ width: 150px;
+ float: right;
+ position: relative;
+ top: -25px;
+ }
+
@media #{$gt-gsm} {
margin-top: 2.5% 0;
}
@@ -108,18 +124,24 @@ article {
transition: margin-left 0.5s ease-out 0.25s;
}
}
+
li.task-list-item {
- list-style-type: "- ";
- input[type='checkbox'] {
- width: 20px;
- height: 20px;
- }
+ list-style-type: "- ";
+
+ input[type='checkbox'] {
+ width: 20px;
+ height: 20px;
+ }
}
+
li p {
display: inline;
}
- #sommaire + ol, #table-of-contents + ol {
+
+ #sommaire+ol,
+ #table-of-contents+ol {
line-height: 1.6rem;
+
@media #{$gt-gsm} {
line-height: 1.4em;
}
@@ -127,16 +149,20 @@ article {
li {
list-style-type: upper-roman;
}
+
li li {
list-style-type: lower-roman;
}
}
+
.footnotes {
font-size: 0.8em;
+
li {
padding-bottom: 15px;
list-style-type: decimal;
}
+
ol p {
display: inline;
}
@@ -144,14 +170,26 @@ article {
@mixin lightMode {
color: #504d4d;
}
+
@mixin darkMode {
color: #E0DDDD;
}
- @media (prefers-color-scheme: dark) { @include darkMode; }
- @media (prefers-color-scheme: light) { @include lightMode; }
- &.light{ @include lightMode; }
- &.dark { @include darkMode; }
+ @media (prefers-color-scheme: dark) {
+ @include darkMode;
+ }
+
+ @media (prefers-color-scheme: light) {
+ @include lightMode;
+ }
+
+ &.light {
+ @include lightMode;
+ }
+
+ &.dark {
+ @include darkMode;
+ }
}
@@ -164,8 +202,13 @@ article {
h1 h2 h3 {
line-height: initial;
}
- h1, h2, h3, h4, h5 {
- text-indent: -10px;
+
+ h1,
+ h2,
+ h3,
+ h4,
+ h5 {
+ text-indent: -10px;
}
@media #{$gsm} {
@@ -173,34 +216,45 @@ article {
padding: 50px 5px;
width: calc(100% - 10px);
font-size: 1rem;
+
code {
font-size: 0.9rem;
}
}
+
@media #{$big-laptop} {
pre code {
width: 110%;
margin: 0 -10%;
}
}
+
@mixin lightMode {
.pubDate {
color: #606060;
}
+
blockquote {
color: #504d4d;
}
- h4, h5, h6 {
+ h4,
+ h5,
+ h6 {
color: black;
}
+
img {
filter: none;
}
+
color: initial;
- > p:first-of-type {
- > img[src$=".jpg"], > img[src$=".png"], > img[src$=".avif"] {
+ >p:first-of-type {
+
+ >img[src$=".jpg"],
+ >img[src$=".png"],
+ >img[src$=".avif"] {
filter: none;
}
}
@@ -210,30 +264,55 @@ article {
.pubDate {
color: #606060;
}
+
blockquote {
color: #E0DDDD;
}
- h4, h5, h6 {
+ h4,
+ h5,
+ h6 {
color: #EFEFEF;
}
+
img:not(.no-dark) {
filter: invert(1);
}
+
color: #EFEFEF;
- > p:first-of-type {
- > img[src$=".jpg"], > img[src$=".png"], > img[src$=".avif"] {
+ >p:first-of-type {
+
+ >img[src$=".jpg"],
+ >img[src$=".png"],
+ >img[src$=".avif"] {
filter: invert(0);
}
}
}
- @media (prefers-color-scheme: dark) { @include darkMode; }
- @media (prefers-color-scheme: light) { @include lightMode; }
- &.light{ @include lightMode; }
- &.dark { @include darkMode; }
- iframe, img, div, video, svg, image {
+ @media (prefers-color-scheme: dark) {
+ @include darkMode;
+ }
+
+ @media (prefers-color-scheme: light) {
+ @include lightMode;
+ }
+
+ &.light {
+ @include lightMode;
+ }
+
+ &.dark {
+ @include darkMode;
+ }
+
+ iframe,
+ img,
+ div,
+ video,
+ svg,
+ image {
border: none;
margin: 0 auto;
@@ -258,17 +337,19 @@ article {
// Theme style
border: 1px solid gray;
- box-shadow: 1px 0 1px 0 #eee,0 2px 0 2px #ccc,0 2px 0 3px #444;
+ box-shadow: 1px 0 1px 0 #eee, 0 2px 0 2px #ccc, 0 2px 0 3px #444;
}
.marge {
- display: block;
+ display: block;
}
+
.marge {
@media #{$tab} {
display: none;
}
}
+
.sidenotes {
margin: 10px 10px 0 10%;
text-align: justify;
@@ -279,6 +360,7 @@ article {
@mixin lightMode {
color: #333333;
+
sup {
color: black;
}
@@ -286,21 +368,36 @@ article {
@mixin darkMode {
color: #eee;
+
sup {
color: white;
}
}
- @media (prefers-color-scheme: dark) { @include darkMode; }
- @media (prefers-color-scheme: light) { @include lightMode; }
- &.light{ @include lightMode; }
- &.dark { @include darkMode; }
+
+ @media (prefers-color-scheme: dark) {
+ @include darkMode;
+ }
+
+ @media (prefers-color-scheme: light) {
+ @include lightMode;
+ }
+
+ &.light {
+ @include lightMode;
+ }
+
+ &.dark {
+ @include darkMode;
+ }
transition: width 0.25s ease-out 0.25s;
position: relative;
max-width: 475px;
+
p {
margin: 0;
}
+
.sidenote {
position: absolute;
font-style: oblique;
@@ -316,9 +413,11 @@ section.likes {
@mixin lightMode {
.likesBox {
background-color: #CDE3EC;
+
.likesNotes {
color: #555;
}
+
.icon {
.nbLikes {
color: #00324D;
@@ -326,12 +425,15 @@ section.likes {
}
}
}
+
@mixin darkMode {
.likesBox {
background-color: #3C3C7C;
+
.likesNotes {
color: #CCC;
}
+
.icon {
.nbLikes {
color: #F0D5AD;
@@ -339,10 +441,22 @@ section.likes {
}
}
}
- @media (prefers-color-scheme: dark) { @include darkMode; }
- @media (prefers-color-scheme: light) { @include lightMode; }
- &.light{ @include lightMode; }
- &.dark { @include darkMode; }
+
+ @media (prefers-color-scheme: dark) {
+ @include darkMode;
+ }
+
+ @media (prefers-color-scheme: light) {
+ @include lightMode;
+ }
+
+ &.light {
+ @include lightMode;
+ }
+
+ &.dark {
+ @include darkMode;
+ }
.likesBox {
padding: 20px;
@@ -354,11 +468,14 @@ section.likes {
font: monospace;
font-weight: 800;
}
+
.likesText {
font-size: 0.8em;
}
+
.likesNotes {
font-size: 0.8em;
+
&.err {
color: red;
}
@@ -368,12 +485,14 @@ section.likes {
.layout {
display: flex;
align-items: center;
+
.icon {
fill: transparent;
stroke: pink;
stroke-width: 20;
cursor: pointer;
position: relative;
+
svg {
overflow: visible;
width: 10rem;
@@ -388,6 +507,7 @@ section.likes {
.hear-main {
z-index: 2;
}
+
.heart-background {
position: absolute;
left: 0;
@@ -395,15 +515,17 @@ section.likes {
z-index: 1;
stroke: none;
}
+
.heart-main path.anim {
animation: stroke-animation 1.5s ease-in-out forwards;
}
- .heart-main ~ .heart-background path.anim-click {
+ .heart-main~.heart-background path.anim-click {
animation: fade-animation 0.35s ease-in-out forwards;
}
+
.nbLikes {
- font-family: Source Sans Pro,Segoe UI,Trebuchet MS,Helvetica,Helvetica Neue,Arial,sans-serif;
+ font-family: Source Sans Pro, Segoe UI, Trebuchet MS, Helvetica, Helvetica Neue, Arial, sans-serif;
text-align: center;
position: relative;
top: -10px;
@@ -417,13 +539,16 @@ section.likes {
fill: transparent;
transform: scale(1);
}
+
30% {
fill: pink;
transform: scale(1.25);
}
+
50% {
transform: scale(1);
}
+
100% {
stroke-dashoffset: 0;
fill: pink;
@@ -435,14 +560,17 @@ section.likes {
fill: transparent;
transform: scale(1);
}
+
13% {
fill: lightpink;
transform: scale(1.2);
opacity: 1;
}
+
66% {
opacity: 0.8;
}
+
100% {
transform: scale(2);
opacity: 0;
@@ -450,16 +578,24 @@ section.likes {
}
}
}
+
.alt-lang {
a {
padding-right: 20px;
}
+
font-size: 1.15rem;
text-transform: lowercase;
font-weight: bolder;
position: relative;
top: -3px;
- font-family: Source Sans Pro,Segoe UI,Trebuchet MS,Helvetica,Helvetica Neue,Arial,sans-serif;
+ font-family: Source Sans Pro,
+ Segoe UI,
+ Trebuchet MS,
+ Helvetica,
+ Helvetica Neue,
+ Arial,
+ sans-serif;
}
.tags {
@@ -480,34 +616,47 @@ section.likes {
background-color: #DDD;
color: #333;
}
+
@mixin darkMode {
background-color: #444;
color: #eee;
}
- @media (prefers-color-scheme: dark) { @include darkMode; }
- @media (prefers-color-scheme: light) { @include lightMode; }
- &.light{ @include lightMode; }
- &.dark { @include darkMode; }
+ @media (prefers-color-scheme: dark) {
+ @include darkMode;
+ }
+
+ @media (prefers-color-scheme: light) {
+ @include lightMode;
+ }
+
+ &.light {
+ @include lightMode;
+ }
+
+ &.dark {
+ @include darkMode;
+ }
}
}
/* Used only on tag's pages */
-.articleList {
- list-style-type: none;
- font-size: 1.2em;
- text-indent: -65px;
+.articleList,
+.notesList {
+ list-style-type: none;
+ font-size: 1.2em;
+ text-indent: -65px;
- font-family: palatino, Times, serif;
+ font-family: palatino, Times, serif;
- position: relative;
- top: -3px;
- left: -60px;
+ position: relative;
+ top: -3px;
+ left: -60px;
- .pubYear {
- color: #777;
- margin: 0 10px;
- }
+ .pubYear {
+ color: #777;
+ margin: 0 10px;
+ }
}
@@ -525,15 +674,27 @@ section.likes {
background-color: #DDD;
color: #333;
}
+
@mixin darkMode {
background-color: #444;
color: #eee;
}
- @media (prefers-color-scheme: dark) { @include darkMode; }
- @media (prefers-color-scheme: light) { @include lightMode; }
- &.light{ @include lightMode; }
- &.dark { @include darkMode; }
+ @media (prefers-color-scheme: dark) {
+ @include darkMode;
+ }
+
+ @media (prefers-color-scheme: light) {
+ @include lightMode;
+ }
+
+ &.light {
+ @include lightMode;
+ }
+
+ &.dark {
+ @include darkMode;
+ }
}
@@ -554,4 +715,3 @@ video::cue(.back) {
hr {
margin: 2.5rem 0;
}
-
diff --git a/src/js/love.js b/src/js/love.js
index 59ecccc..b1f8b3b 100644
--- a/src/js/love.js
+++ b/src/js/love.js
@@ -18,7 +18,7 @@ window.addEventListener("DOMContentLoaded", () => {
return `${window.location.origin}/like/${currentArticleName}`;
}
- const isAnArticle = articles.length === 1; // The front page have multiple articles.
+ const isAnArticle = window.location.pathname.startsWith("/articles");
if (isAnArticle) {
const article = articles[0];
diff --git a/src/templates/tag.tmpl b/src/templates/tag.tmpl
index f73365d..710fb0f 100644
--- a/src/templates/tag.tmpl
+++ b/src/templates/tag.tmpl
@@ -16,6 +16,19 @@
</li>
{{/ articles}}
</ul>
+ {{#notes.length}}
+ <ul class="notesList">
+ {{# notes}}
+ <h2>Notes</h2>
+ <li><a href="{{ url }}"><span class="pubYear">{{ pubYear }}</span>{{ title }}</a>  
+ {{# metaData.tags }}
+ <a href="/{{ lang }}/tag/{{{ . }}}" class="inline-tag">{{{ . }}}</a>
+ {{/ metaData.tags }}
+ </li>
+ {{/ notes}}
+ </ul>
+ {{/notes.length}}
+
</article>
<div class="sidenotes"></div>
</div>