summaryrefslogtreecommitdiff
path: root/src/build
diff options
context:
space:
mode:
authorache <ache@ache.one>2023-04-22 00:08:23 +0200
committerache <ache@ache.one>2023-04-22 00:08:23 +0200
commite089388ab53d8e015f0cc997b3cee0fb1d62bca6 (patch)
tree677567c50de3cfa03bcd383ac558a980d4412bc5 /src/build
parentReplace the mamooth (diff)
Support for multilang
Diffstat (limited to 'src/build')
-rw-r--r--src/build/article.mjs31
-rw-r--r--src/build/i18n.mjs56
-rw-r--r--src/build/index.mjs242
-rw-r--r--src/build/list-articles.mjs7
-rw-r--r--src/build/loadMD.mjs75
-rw-r--r--src/build/utils.mjs0
6 files changed, 249 insertions, 162 deletions
diff --git a/src/build/article.mjs b/src/build/article.mjs
new file mode 100644
index 0000000..1a7b09b
--- /dev/null
+++ b/src/build/article.mjs
@@ -0,0 +1,31 @@
+// Set of functions to handle articles
+
+function getArticleYear(article) {
+ if (article.metaData.pubDate.getFullYear) {
+ return article.metaData.pubDate.getFullYear();
+ }
+
+ if (article.metaData.pubDate.getUTCFullYear) {
+ return article.metaData.pubDate.getUTCFullYear();
+ }
+
+ return 0;
+}
+
+function getArticleDate(article) {
+ if (article.metaData.pubDate.getDate) {
+ return article.metaData.pubDate.getFullYear() * 100 + article.metaData.pubDate.getDate();
+ }
+
+ if (article.metaData.pubDate.getUTCDate) {
+ return article.metaData.pubDate.getUTCFullYear() * 100 + article.metaData.pubDate.getDate();
+ }
+
+ return 0;
+}
+
+function cmpArticles(a, b) {
+ return getArticleDate(b) - getArticleDate(a);
+}
+
+export {getArticleDate, getArticleYear, cmpArticles};
diff --git a/src/build/i18n.mjs b/src/build/i18n.mjs
new file mode 100644
index 0000000..f81f413
--- /dev/null
+++ b/src/build/i18n.mjs
@@ -0,0 +1,56 @@
+
+const i18n = {
+ fr: {
+ intro: {
+ 'description': 'Éternel étudiant en Math-Info.',
+ 'about': 'Autodidacte passionné,<br><span class="type_wrap"><span class="type">désormais ingénieur.</span></span>',
+ 'about_tags': 'GNU\Linux, C, C++, Python, Math, autohébergement, décentralisation, P2P, commun, ... <br> ',
+ },
+ title: {
+ 'main': 'ache: Blog personnel',
+ 'home': 'L\'accueil',
+ 'git': 'Dépôt git personnel',
+ 'mastodon': 'Mon mastodon',
+ },
+ articles: [
+ 'bizarreries-du-langage-c.md',
+ 'retour-sur-laoc-2021-semaine-1.md',
+ '2FA-discord-sur-pc.md',
+ 'duckduckgo-google-en-mieux.md',
+ ]
+ },
+ en: {
+ intro: {
+ 'description': 'Everlast CS student.',
+ 'about': 'Passionated self-taught,<br><span class="type_wrap"><span class="type">now engineer.</span></span>',
+ 'about_tags': 'GNU\Linux, C, C++, Python, Math, self-hosted, dececntralisation, P2P, ... <br>',
+ },
+ title: {
+ 'main': 'ache: Personnel blog',
+ 'home': 'Home',
+ 'git': 'Personnel git repository',
+ 'mastodon': 'Mastodon account',
+ },
+ articles: [
+ 'c-language-quirks.md',
+ ]
+ }
+}
+
+const lang_desc = {
+ fr: "Version Française",
+ en: "English version",
+}
+
+export function addDescription(alt_lang) {
+ if (alt_lang) {
+ alt_lang.forEach(e => {
+ e.description = lang_desc[e.lang]
+ });
+ }
+
+ return alt_lang;
+}
+
+
+export default i18n;
diff --git a/src/build/index.mjs b/src/build/index.mjs
index c2701d9..7a47c8e 100644
--- a/src/build/index.mjs
+++ b/src/build/index.mjs
@@ -1,106 +1,11 @@
import fs from 'node:fs';
import mustache from 'mustache';
-import {u} from 'unist-builder';
-import {h} from 'hastscript';
-import {select} from 'hast-util-select';
-import {toString as hastToString} from 'mdast-util-to-string';
-import cssesc from 'cssesc';
-import toml from '@ltd/j-toml';
-
-import {toHtmlRaw, toString, toMdRaw, mdToHtmlRaw} from './to-html.mjs';
import loadSVG from './load-svg.mjs';
-import listArticles from './list-articles.mjs';
import getRSS from './rss.mjs';
-
-function getArticleYear(article) {
- if (article.metaData.pubDate.getFullYear) {
- return article.metaData.pubDate.getFullYear();
- }
-
- if (article.metaData.pubDate.getUTCFullYear) {
- return article.metaData.pubDate.getUTCFullYear();
- }
-
- return 0;
-}
-
-function getArticleDate(article) {
- if (article.metaData.pubDate.getDate) {
- return article.metaData.pubDate.getFullYear() * 100 + article.metaData.pubDate.getDate();
- }
-
- if (article.metaData.pubDate.getUTCDate) {
- return article.metaData.pubDate.getUTCFullYear() * 100 + article.metaData.pubDate.getDate();
- }
-
- return 0;
-}
-
-function cmpArticles(a, b) {
- return getArticleDate(b) - getArticleDate(a);
-}
-
-const loadMD = (listFile, suffix) => {
- const listContent = [];
- for (const file of listFile) {
- console.log(`Working on ${file}`);
- const content = fs.readFileSync(`${suffix}/${file}`, 'utf8');
- const mdRaw = toMdRaw(content);
- const tomlStringValue = mdRaw.children[0].value;
- const metaData = toml.parse(tomlStringValue);
- const newHTML = mdToHtmlRaw(mdRaw);
-
- const htmlContent = newHTML;
- const htmlRender = toString(htmlContent);
-
- const titleHtml = select('h1', htmlContent);
- const intro = select('p', htmlContent);
- intro.children = intro.children.filter(child => child.tagName !== 'br');
-
- const logo = select('img', intro);
- logo.properties.src = `${suffix}/${logo.properties.src}`;
- logo.properties.height = '150';
- logo.properties.width = '150';
-
- const logoP = select('source', intro);
- if (logoP !== null) {
- logoP.properties.srcSet = `${suffix}/${logoP.properties.srcSet}`;
- }
-
- titleHtml.children[0].properties.href = `${suffix}/${file.slice(0, -3)}`;
-
- const title = hastToString(titleHtml);
- const domTitle = cssesc(title.replace(/\s+/g, '-').replace(/['"#@]/, '').toLowerCase()); // Maybe encodeURI
-
- const readMore = h('a', 'Lire la suite …');
-
- readMore.properties.href = `${suffix}/${file.slice(0, -3)}`;
- const pubYear = getArticleYear({metaData});
-
- if (metaData.pubDate) {
- try {
- metaData.pubDateISO = metaData.pubDate.toISOString();
- } catch (error) {
- console.error(`Error on file ${file} with pubDate (${metaData.pubDate}): ${error}`);
- }
- }
-
- listContent.push({
- name: file.slice(0, -3),
- content: htmlRender,
- intro: toString(u('root', [titleHtml, intro, readMore])),
- introDesc: hastToString(intro),
- imageUrl: logo.properties.src,
- metaData,
- pubYear,
- title,
- domTitle,
- url: `/${suffix}/${file.slice(0, -3)}`,
- });
- }
-
- return listContent;
-};
+import loadMD from './loadMD.mjs';
+import {cmpArticles} from './article.mjs';
+import i18n from './i18n.mjs';
+import {addDescription} from './i18n.mjs';
const leftPanelTmpl = fs.readFileSync('src/templates/left.tmpl', 'utf8');
const likesTmpl = fs.readFileSync('src/templates/likes.tmpl', 'utf8');
@@ -118,68 +23,95 @@ const partials = {
hid: hidTmpl,
};
+// Load global variables
const svg = loadSVG();
-const articles = loadMD(listArticles, 'articles');
-const tagsArticle = new Map();
-
-for (const article of articles) {
- const context = {
- svg,
- title: `${article.title} - ache`,
- canonical: `${baseUrl}${article.url.slice(1)}`,
- content: article.content,
- domTitle: article.domTitle,
- metaData: article.metaData,
- };
- const output = mustache.render(articleTmpl, context, partials);
- console.log(`Create : ${article.title}`);
- fs.writeFileSync(`articles/${article.name}.html`, output);
-
- for (const tag of article.metaData.tags) {
- if (tagsArticle.has(tag)) {
- tagsArticle.get(tag).push(article);
- } else {
- tagsArticle.set(tag, [article]);
+for (const lang in i18n) {
+ const tagsArticle = new Map();
+ const articles = loadMD(i18n[lang].articles, 'articles', lang);
+
+ for (const article of articles) {
+ const context = {
+ svg,
+ page_title: `${article.title} - ache`,
+ title: i18n[lang].title,
+ intro: i18n[lang].intro,
+ lang,
+ canonical: `${baseUrl}${article.url.slice(1)}`,
+ content: article.content,
+ title: i18n[lang].title,
+ metaData: article.metaData,
+ alt_lang: addDescription(article.metaData.alt_lang),
+ };
+ const output = mustache.render(articleTmpl, context, partials);
+
+ console.log(`Create : ${article.title}`);
+ fs.writeFileSync(`articles/${article.name}.html`, output);
+
+ for (const tag of article.metaData.tags) {
+ if (tagsArticle.has(tag)) {
+ tagsArticle.get(tag).push(article);
+ } else {
+ tagsArticle.set(tag, [article]);
+ }
}
}
-}
-
-try {
- fs.mkdirSync('tag');
-} catch {
- fs.rmSync('tag', {force: true, recursive: true});
- fs.mkdirSync('tag');
-}
-
-for (const [tag, articles] of tagsArticle.entries()) {
- console.log(`Create tag page : ${tag}.xml`);
- articles.sort(cmpArticles);
- const context = {
- svg,
- title: `ache - Tag: ${tag}`,
- tag,
- articles,
- };
+// Set of pages language dependant
- const output = mustache.render(tagTmpl, context, partials);
- fs.writeFileSync(`tag/${tag}.html`, output);
-}
-
-console.log('Create RSS Flux: rss.xml');
-const xmlFeed = getRSS(articles, baseUrl);
-fs.writeFileSync('rss.xml', xmlFeed);
+ try {
+ fs.mkdirSync(`${lang}/tag`, {recursive: true});
+ } catch {
+ fs.rmSync(`${lang}/tag`, {force: true, recursive: true});
+ fs.mkdirSync(`${lang}/tag`, {recursive: true});
+ }
-{
- const context = {
- title: 'ache: Blog personnel',
- canonical: baseUrl,
- svg,
- articles,
- };
+ for (const [tag, articles] of tagsArticle.entries()) {
+ console.log(`Create tag page : ${lang}/${tag}.html`);
+ articles.sort(cmpArticles);
+
+ const context = {
+ svg,
+ page_title: `ache - Tag: ${tag}`,
+ title: i18n[lang].title,
+ intro: i18n[lang].intro,
+ lang,
+ tag,
+ articles,
+ };
+
+ const output = mustache.render(tagTmpl, context, partials);
+ fs.writeFileSync(`${lang}/tag/${tag}.html`, output);
+ }
- console.log('Create : Home page');
- const output = mustache.render(indexTmpl, context, partials);
- fs.writeFileSync('index.html', output);
+ console.log(`Create RSS Flux: ${lang}/rss.xml`);
+ const xmlFeed = getRSS(articles, baseUrl);
+ fs.writeFileSync(`${lang}/rss.xml`, xmlFeed);
+
+ {
+ const alt_lang = {
+ fr: {
+ lang: 'en',
+ url: '/en/',
+ },
+ en: {
+ lang: 'fr',
+ url: '/fr/',
+ },
+ };
+ const context = {
+ page_title: i18n[lang].title.main,
+ title: i18n[lang].title,
+ intro: i18n[lang].intro,
+ lang,
+ canonical: baseUrl,
+ svg,
+ articles,
+ alt_lang: [alt_lang[lang]],
+ };
+
+ console.log(`Create : Home page ${lang}`);
+ const output = mustache.render(indexTmpl, context, partials);
+ fs.writeFileSync(`${lang}/index.html`, output);
+ }
}
diff --git a/src/build/list-articles.mjs b/src/build/list-articles.mjs
deleted file mode 100644
index d327573..0000000
--- a/src/build/list-articles.mjs
+++ /dev/null
@@ -1,7 +0,0 @@
-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/loadMD.mjs b/src/build/loadMD.mjs
new file mode 100644
index 0000000..6d513ef
--- /dev/null
+++ b/src/build/loadMD.mjs
@@ -0,0 +1,75 @@
+import fs from 'node:fs';
+import {u} from 'unist-builder';
+import {h} from 'hastscript';
+import {select} from 'hast-util-select';
+import {toString as hastToString} from 'mdast-util-to-string';
+import cssesc from 'cssesc';
+import toml from '@ltd/j-toml';
+
+import {toString, toMdRaw, mdToHtmlRaw} from './to-html.mjs';
+import {getArticleYear} from './article.mjs';
+import i18n from './i18n.mjs';
+
+const loadMD = (listFile, suffix, lang) => {
+ const listContent = [];
+ for (const file of listFile) {
+ console.log(`Working on ${file}`);
+ const content = fs.readFileSync(`${suffix}/${file}`, 'utf8');
+ const mdRaw = toMdRaw(content);
+ const tomlStringValue = mdRaw.children[0].value;
+ const metaData = toml.parse(tomlStringValue);
+ const newHTML = mdToHtmlRaw(mdRaw);
+
+ const htmlContent = newHTML;
+ const htmlRender = toString(htmlContent);
+
+ const titleHtml = select('h1', htmlContent);
+ const intro = select('p', htmlContent);
+ intro.children = intro.children.filter(child => child.tagName !== 'br');
+
+ const logo = select('img', intro);
+ logo.properties.src = `/${suffix}/${logo.properties.src}`;
+ logo.properties.height = '150';
+ logo.properties.width = '150';
+
+ const logoP = select('source', intro);
+ if (logoP !== null) {
+ logoP.properties.srcSet = `/${suffix}/${logoP.properties.srcSet}`;
+ }
+
+ titleHtml.children[0].properties.href = `/${suffix}/${file.slice(0, -3)}`;
+
+ const title = hastToString(titleHtml);
+ const domTitle = cssesc(title.replace(/\s+/g, '-').replace(/['"#@]/, '').toLowerCase()); // Maybe encodeURI
+
+ const readMore = h('a', i18n[lang]['read_more']);
+
+ readMore.properties.href = `/${suffix}/${file.slice(0, -3)}`;
+ const pubYear = getArticleYear({metaData});
+
+ if (metaData.pubDate) {
+ try {
+ metaData.pubDateISO = metaData.pubDate.toISOString();
+ } catch (error) {
+ console.error(`Error on file ${file} with pubDate (${metaData.pubDate}): ${error}`);
+ }
+ }
+
+ listContent.push({
+ name: file.slice(0, -3),
+ content: htmlRender,
+ intro: toString(u('root', [titleHtml, intro, readMore])),
+ introDesc: hastToString(intro),
+ imageUrl: logo.properties.src,
+ metaData,
+ pubYear,
+ title,
+ domTitle,
+ url: `/${suffix}/${file.slice(0, -3)}`,
+ });
+ }
+
+ return listContent;
+};
+
+export default loadMD;
diff --git a/src/build/utils.mjs b/src/build/utils.mjs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/build/utils.mjs