translation pipeline: working.
This commit is contained in:
parent
3025b6d50a
commit
2ecb2ab1fd
129
css/style.css
129
css/style.css
|
|
@ -1,5 +1,134 @@
|
|||
:root {
|
||||
/* size variables */
|
||||
/* more pronounced, perfect fifth on narrow screens */
|
||||
/* @link https://utopia.fyi/type/calculator?c=360,16,1.5,1240,20,1.25,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12 */
|
||||
|
||||
--step--2: clamp(0.4444rem, 0.299rem + 0.6465vw, 0.8rem);
|
||||
--step--1: clamp(0.6667rem, 0.5303rem + 0.6061vw, 1rem);
|
||||
--step-0: clamp(1rem, 0.8977rem + 0.4545vw, 1.25rem);
|
||||
--step-1: clamp(1.5rem, 1.4744rem + 0.1136vw, 1.5625rem);
|
||||
--step-2: clamp(1.9531rem, 2.3714rem + -0.5398vw, 2.25rem);
|
||||
--step-3: clamp(2.4414rem, 3.7569rem + -1.6974vw, 3.375rem);
|
||||
--step-4: clamp(3.0518rem, 5.8851rem + -3.6559vw, 5.0625rem);
|
||||
--step-5: clamp(3.8147rem, 9.1397rem + -6.871vw, 7.5938rem);
|
||||
|
||||
/* @link https://utopia.fyi/space/calculator?c=360,18,1.2,1240,20,1.25,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12 */
|
||||
|
||||
--space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
|
||||
--space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
|
||||
--space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
|
||||
--space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
|
||||
--space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
|
||||
--space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
|
||||
--space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
|
||||
--space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
|
||||
--space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
|
||||
|
||||
/* One-up pairs */
|
||||
--space-3xs-2xs: clamp(0.3125rem, 0.1847rem + 0.5682vw, 0.625rem);
|
||||
--space-2xs-xs: clamp(0.5625rem, 0.4091rem + 0.6818vw, 0.9375rem);
|
||||
--space-xs-s: clamp(0.875rem, 0.7216rem + 0.6818vw, 1.25rem);
|
||||
--space-s-m: clamp(1.125rem, 0.8182rem + 1.3636vw, 1.875rem);
|
||||
--space-m-l: clamp(1.6875rem, 1.3551rem + 1.4773vw, 2.5rem);
|
||||
--space-l-xl: clamp(2.25rem, 1.6364rem + 2.7273vw, 3.75rem);
|
||||
--space-xl-2xl: clamp(3.375rem, 2.7102rem + 2.9545vw, 5rem);
|
||||
--space-2xl-3xl: clamp(4.5rem, 3.2727rem + 5.4545vw, 7.5rem);
|
||||
|
||||
/* Custom pairs */
|
||||
--space-s-l: clamp(1.125rem, 0.5625rem + 2.5vw, 2.5rem);
|
||||
|
||||
|
||||
/*COLORS*/
|
||||
--blue: #d7f0e1;
|
||||
--darkblue: #2c6a88;
|
||||
--oc-gray-3: #dee2e6;
|
||||
--oc-gray-5: #adb5bd;
|
||||
--oc-gray-6: #868e96;
|
||||
--oc-gray-7: #495057;
|
||||
--oc-gray-8: #343a40;
|
||||
--oc-cyan-6: #15aabf;
|
||||
--oc-cyan-9: #0b7285;
|
||||
--oc-blue-1: #d0ebff;
|
||||
--oc-blue-3: #74c0fc;
|
||||
--oc-blue-4: #4dabf7;
|
||||
--oc-blue-7: #1c7ed6;
|
||||
--oc-blue-9: #1864ab;
|
||||
--oc-grape-9: #862e9c;
|
||||
--oc-violet-4: #9775fa;
|
||||
--oc-violet-9: #5f3dc4;
|
||||
|
||||
}
|
||||
body {
|
||||
font-family: "sans-serif";
|
||||
margin: 0 auto;
|
||||
max-width: 66ch;
|
||||
}
|
||||
@layer translations {
|
||||
body > trl-selector:first-child {display: none;} /* was adding a grid row! */
|
||||
trl-selector {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: var(--space-3xs);
|
||||
flex-wrap: wrap;
|
||||
justify-content: end;
|
||||
justify-self: end;
|
||||
align-items: start;
|
||||
padding-inline: var(--space-3xs);
|
||||
margin-inline-end: var(--space-3xs);
|
||||
grid-column: grid-start/content-start;
|
||||
align-self: start;
|
||||
margin-top: var(--space-l);
|
||||
background-color: var(--oc-blue-1);
|
||||
max-width: max-content;
|
||||
border-radius: 3px;
|
||||
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
/* assumes labels follow their inputs immediately */
|
||||
input:checked + label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
}
|
||||
/* Do we use trl-selector ~ or [trl] descendants? */
|
||||
/* need one of these rules for each language.*/
|
||||
trl-selector:has(> input[value="nl"]:checked) {
|
||||
& ~ trl-alt:lang('nl') {
|
||||
display: block;
|
||||
}
|
||||
& ~ trl-alt:not(:lang('nl')) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
trl-selector:has( > input[value="en"]:checked) {
|
||||
& ~ trl-alt:lang('en') {
|
||||
display: block;
|
||||
}
|
||||
& ~ trl-alt:not(:lang('en')) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
body:has(> trl-selector input[value="nl"]:checked) {
|
||||
& [trl-ui]:lang('nl') {
|
||||
display: block;
|
||||
}
|
||||
& [trl-ui]:not(:lang('nl')) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
body:has(> trl-selector input[value="en"]:checked) {
|
||||
& [trl-ui]:lang('en') {
|
||||
display: block;
|
||||
}
|
||||
& [trl-ui]:not(:lang('en')) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,38 @@
|
|||
import {fromHtml} from 'hast-util-from-html';
|
||||
import {toHtml} from 'hast-util-to-html';
|
||||
import {visit} from 'unist-util-visit';
|
||||
import {JSDOM} from 'jsdom';
|
||||
/*
|
||||
* The idea: need to create another subdir `title/nl/index.html`
|
||||
*/
|
||||
|
||||
/*
|
||||
* addTranslationInterface adds the <trl-selector> with radio buttons and labels to each <trl-group>.
|
||||
* It sets the checked property on the indicated language.
|
||||
*/
|
||||
|
||||
/*
|
||||
* first, index.html is the original page, with the page language (from markdown frontmatter) active.
|
||||
* This allows switching between languages for each translated fragment in the page.
|
||||
* then, for each language in the frontmatter `trls`, another folder-with-index.html is generated,
|
||||
* with <trl-selector> added,
|
||||
* where the language corresponding to the given language is active.
|
||||
*
|
||||
* So note that page `trls: []` is independent of the languages of the `<trl-alt>`s in each `<trl-group>`.
|
||||
*/
|
||||
export default async (page) => {
|
||||
const html = await page.html;
|
||||
return {
|
||||
"index.html": page.html,
|
||||
"index.html": addTranslationInterface(html, page?.lang),
|
||||
...handleTranslations(html, page.trls)
|
||||
}
|
||||
}
|
||||
|
||||
//this is going to create a folder for each 'translation' specified in frontmatter.
|
||||
function handleTranslations(html, trls) {
|
||||
if (trls) {
|
||||
console.log(trls);
|
||||
const outputs = {};
|
||||
trls.forEach(trl => {
|
||||
outputs[trl] = {
|
||||
"index.html": reorderTranslations(html, trl)
|
||||
"index.html": addTranslationInterface(html, trl)
|
||||
}
|
||||
})
|
||||
return outputs;
|
||||
|
|
@ -27,11 +41,43 @@ function handleTranslations(html, trls) {
|
|||
}
|
||||
}
|
||||
|
||||
//reorders all '.translation-group's so the element with given lang is first, and 'open' is set appropriately.
|
||||
//also, handles latest/laatst. Is that a special case, or should that be translated in the page too?
|
||||
function reorderTranslations(body, lang){
|
||||
//handles both text and dom object as input
|
||||
const hast = fromHtml(body);
|
||||
//visit: trlselector>radio, and set active on current lang and inactive on other langs.
|
||||
return toHtml(hast);
|
||||
//"reorders" all `trl-group`s so the element with given lang is displayed.
|
||||
//EN is default language ...
|
||||
//also adds a (hidden by css) trl-selector at the top of `body`.
|
||||
//TODO: add a link to translated pages ...
|
||||
//that's complicated, because what about all the links in the page?
|
||||
function addTranslationInterface(body, activelang="en"){
|
||||
const dom = new JSDOM(body);
|
||||
const doc = dom.window.document;
|
||||
let seq = 1; //serial number for identifying translation group inputs and labels
|
||||
const trlGroups = Array.from(doc.querySelectorAll('trl-group'));
|
||||
trlGroups.forEach((trlGroup) => {
|
||||
//for each trlGroup.
|
||||
const trlAltElems = Array.from(trlGroup.querySelectorAll('trl-alt'));
|
||||
const langsInGroup = trlAltElems.map(t => t.getAttribute('lang'));
|
||||
const trlSel = doc.createElement('trl-selector');
|
||||
langsInGroup.forEach(lang => {
|
||||
console.log(lang);
|
||||
let grname = `trlg-${seq}`;
|
||||
let inputId = `${grname}-${lang}`;
|
||||
const input = doc.createElement('input');
|
||||
input.type = 'radio';
|
||||
input.setAttribute('id', inputId);
|
||||
input.setAttribute('name', grname);
|
||||
input.setAttribute('lang', lang);
|
||||
input.setAttribute('value', lang);
|
||||
if (lang === activelang) {
|
||||
input.setAttribute('checked', '');
|
||||
}
|
||||
const label = doc.createElement('label');
|
||||
label.setAttribute('for', inputId);
|
||||
label.textContent = lang;
|
||||
trlSel.append(input);
|
||||
trlSel.append(label);
|
||||
|
||||
})
|
||||
trlGroup.prepend(trlSel);
|
||||
seq ++; //increment id serial number
|
||||
})
|
||||
return dom.serialize();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,14 +64,9 @@
|
|||
Then, we can use that html and the trls property to add the translations.
|
||||
*/
|
||||
|
||||
//NOTE! two steps at once. Could separate the withTranslations part: add a html_LANG property to the document object, then later create the folder structure.
|
||||
pagesInFolders: Tree.map(renderedPages, pagesInFoldersWithTranslations.js)
|
||||
/*
|
||||
pagesInFolders: Tree.map(renderedPages, {
|
||||
value: (value) => {
|
||||
index.html: value
|
||||
}
|
||||
})
|
||||
*/
|
||||
|
||||
|
||||
//bug in 0.6.14?
|
||||
linksByFile: Tree.map(renderedPages,getLinkedFilesFromHtml.js)
|
||||
|
|
|
|||
Loading…
Reference in New Issue