En poques paraules
Un quadern escolar japonès: comptes, caselles i opcions en una pàgina, i kanji i lectures en una altra, de dalt a baix. Sota cada exercici hi ha les solucions del revés, perquè l’infant giri el quadern i les comprovi.
Què compondràs
Dues pàgines d’una sèrie d’exercicis de tercer en format B5. La de comptes va en horitzontal: una franja blau pàl·lid amb l’etiqueta de l’assignatura, el títol i un tanuki de mascota, una línia per al nom i una casella per a la nota, i després ひっ算 amb una casella per a cada xifra del resultat, caselles darrere de sis comptes, opcions ア イ ウ en fila, afirmacions ○× amb un parèntesi al final de la línia i dos problemes amb línies per escriure-hi les operacions. La de kanji es compon com s’imprimeix un quadern de 国語, de dalt a baix i de dreta a esquerra: lectures amb una casella per al kanji, paraules subratllades la lectura de les quals va entre parèntesis, opcions per encerclar i un significat per triar. Sota cada exercici, les solucions van del revés en lletra grisa petita. L’infant veu on són, no les llegeix d’una ullada i gira el quadern per comprovar-les.
Aquesta recepta respon a
- Com imprimeixo les solucions cap per avall al peu d'un exercici?
- Com componc una pàgina d'exercicis japonesa en columnes verticals amb el mateix disseny que l'horitzontal?
- Com componc la divisió llarga tal com l'escriuen les escoles de cada país?
La resposta curta
// `placement: 'inverted'` sets each exercise's key right after it in a box turned 180°: the
// pupil sees where the answers are without reading them, and turns the book to check. The
// key's words come from the exercise (the options' katakana, ○ and ×, the operations), so
// the Markdown holds nothing twice.
const drill = {
id: 'drill',
number: { shape: 'square', fontFamily: TEXT, fontWeight: 600, background: col('blue') },
instruction: { fontFamily: ROUND, bold: false },
options: { layout: 'row' }, // ア イ ウ side by side (the default labels in Japanese)
trueFalse: { look: 'bracket' }, // ( ) for ○ or ×
blank: { look: 'box', width: 'answer', color: col('rule') }, // □ to write in
area: { kind: 'lines', color: col('rule') },
grid: { rule: col('rule') },
solutions: { placement: 'inverted', box: 'kotae' },
marginTop: em(1.1), marginBottom: em(0.4),
};
const kotae = { id: 'kotae', title: '', backgroundEnabled: false, border: { enabled: false },
padding: { top: pt(0), right: pt(0), bottom: pt(0), left: pt(0) },
body: { fontFamily: ROUND, fontSize: pt(8), lineHeight: pt(12), color: col('muted'),
firstLineIndent: pt(0) },
marginTop: mm(1), marginBottom: mm(2), keepTogether: true };
Ingredients
- Funcions
- SolucionsEstils d'exerciciText verticalExercicisOperacions en columnaBuits i bancs de paraulesElecció i vertader o falsPreguntes obertes i zones d'escripturaKana, kanji i rōmajiFonts xineses, japoneses i coreanesLínies laterals (bōsen)Llibres enquadernats per la dretaChips en líniaTres o més columnesObertures dissenyadesAtributs de títolImatges als dissenys de pàginaAncoratge d'elements de dissenyPaleta de color semànticaExportació a PDF
- També fa servir
- Columnes en un requadre o al textRequadres que es parteixen o noTall de línies en xinèsEquilibri de columnesEstils de paràgrafFonts incrustades al PDFFigures i taules com a recursos
- Tipografia
- Klee One, Zen Maru Gothic (SIL OFL 1.1)
- Recursos
kitsune-600.jpgtanuki-600.jpg- A young tanuki in a yellow school hat holding a big pencil. (Generated With Diffusion Models, original)
- A fox cub in a red scarf reading a book. (Generated With Diffusion Models, original)
Elaboració
#1 · Gira les solucions de cada exercici
El codi és a la resposta curta. placement: 'inverted' posa les solucions després de cada exercici en un requadre girat 180°, i aquest requadre va dins del requadre del mateix exercici, així que un salt de pàgina no els separa mai. Les solucions surten de l’exercici: les operacions amb el resultat, el katakana de l’opció correcta, ○ i ×, les paraules dels buits. L’estil de requadre de les solucions, kotae, només posa la lletra petita i grisa.
#2 · Una franja per a la pàgina horitzontal i per a la vertical
// A heading design on a vertical page is laid along its column: x runs down the page and y
// to the left, so the same band stands at the right edge, from head to foot.
const BAND = 30; // mm: the band's depth (its height across, its width down)
const header = { enabled: true, minHeight: mm(BAND + 3), slot: { elements: [
{ kind: 'box', id: 'band', reserve: false, style: { backgroundColor: col('tint'),
borderRadius: mm(4) }, placement: { anchor: { to: 'container', edge: 'top-left' },
size: { width: 'fill', height: mm(BAND) } } },
{ kind: 'image', id: 'mascot', resourceId: '{attr.pic}', decorative: true, reserve: false,
placement: { anchor: { to: 'container', edge: 'top-right' }, offset: { x: mm(-4), y: mm(1) },
size: { width: mm(28), height: mm(28) } } },
{ kind: 'text', id: 'subject', content: '{attr.kicker}', fontFamily: ROUND, fontSize: pt(10),
fontWeight: 700, color: col('ink'), box: { backgroundColor: col('sun'), borderRadius: mm(3),
padding: { top: mm(0.6), bottom: mm(0.6), left: mm(2.4), right: mm(2.4) } },
placement: { anchor: { to: 'container', edge: 'top-left' }, offset: { x: mm(5), y: mm(5) } } },
{ kind: 'text', id: 'title', content: '{titleText}', fontFamily: ROUND, fontSize: pt(20),
fontWeight: 700, color: col('ink'),
placement: { anchor: { to: '#subject', edge: 'below' }, offset: { x: mm(0), y: mm(2.5) } } },
] } };
Un disseny de títol en una pàgina vertical es col·loca al llarg de la seva columna: la x baixa per la pàgina i la y avança cap a l’esquerra. La franja ancorada top-left amb tota l’amplada queda a dalt a la pàgina de comptes i al llarg de la vora dreta a la de kanji; la mascota ancorada top-right cau a l’extrem de la franja a totes dues. El disseny no anomena cap direcció.
#3 · Dos quaderns amb un sol text
// Two drill books of one series: arithmetic across, bound on the left; kanji in columns,
// bound on the right (vertical text binds there by itself).
const [sansu, kokugo] = markdown.split(/(?=^# 春のことば)/m);
const build = (text) => withLoadedFonts(() => buildDocument({ markdown: text, resources },
config()), { ...kitFonts(FONTS), text: markdown });
const across = await build(sansu);
// 国語 is set in columns, top to bottom, right to left: the same design, turned.
writingMode = 'vertical-rl';
const docs = [across, await build(kokugo)];
La configuració és una funció, així que cada composició rep el seu propi objecte, i entre l’una i l’altra només canvia writingMode. En vertical, el quadern de 国語 s’enquaderna per la dreta tot sol; showBook posa cada quadern al seu costat del llom. El text va en Klee One, una lletra de llibre de text, i les etiquetes en Zen Maru Gothic; totes dues carreguen la seva puntuació vertical per als parèntesis de la pàgina de kanji.
La recepta completa
// ═══ Postext Cookbook · Nº 172 · A Japanese drill with the answers upside down ═══
// https://postext.dev/en/cookbook/japanese-drill-upside-down-answers
// Code: MIT · Text: original (CC BY 4.0) · Pictures: generated with diffusion models
// Fonts: Klee One, Zen Maru Gothic (SIL OFL 1.1) · Needs postext ≥ 1.59.0
import {
buildDocument, withLoadedFonts, renderPageToCanvas, registerResourceImage,
loadVerticalAlternates,
} from 'https://esm.sh/postext';
import { renderToPdf, decompressWoff2 } from 'https://esm.sh/postext-pdf';
const LANG = 'ja'; // @lang: the language of the frame; the drill is Japanese in all
const RECIPE = 'japanese-drill-upside-down-answers';
// ─── 1 · Design ─────────────────────────────────────────────────────────────
// #region palette: a drill book's blue, a warm yellow and a pale sky for the band
const palette = {
ink: '#23272c', // text
blue: '#2a6cb0', // the accent: exercise numbers, the title band's rule, the score box
sun: '#f2c14e', // the subject badge
tint: '#eaf2fb', // the title band
rule: '#a8bfd8', // writing lines and boxes
muted: '#69717b', // folios, the name line, the upside-down answers
paper: '#ffffff',
};
const col = (id) => ({ hex: palette[id], model: 'hex', paletteId: id });
const colorPalette = [
...Object.entries(palette).map(([id, hex]) => ({ id, name: id, value: { hex, model: 'hex' } })),
{ id: 'main-color', name: 'accent (defaults)', value: { hex: palette.blue, model: 'hex' } },
];
// #endregion
// 教科書体 for the text a child copies from, a round gothic for the labels.
const [TEXT, ROUND] = ['Klee One', 'Zen Maru Gothic'];
// #region answer: the answers printed upside down under each exercise
// `placement: 'inverted'` sets each exercise's key right after it in a box turned 180°: the
// pupil sees where the answers are without reading them, and turns the book to check. The
// key's words come from the exercise (the options' katakana, ○ and ×, the operations), so
// the Markdown holds nothing twice.
const drill = {
id: 'drill',
number: { shape: 'square', fontFamily: TEXT, fontWeight: 600, background: col('blue') },
instruction: { fontFamily: ROUND, bold: false },
options: { layout: 'row' }, // ア イ ウ side by side (the default labels in Japanese)
trueFalse: { look: 'bracket' }, // ( ) for ○ or ×
blank: { look: 'box', width: 'answer', color: col('rule') }, // □ to write in
area: { kind: 'lines', color: col('rule') },
grid: { rule: col('rule') },
solutions: { placement: 'inverted', box: 'kotae' },
L'script.js compost funciona tal com és: enganxa'l com a script de mòdul en qualsevol pàgina o obre la recepta a CodePen. Carpeta de la recepta a GitHub ↗ (s'obre en una pestanya nova)
Variants
#Reuneix les solucions al final
Un quadern amb el solucionari a part deixa les solucions fora de les pàgines: chapterEnd les posa després de l’últim exercici.
- solutions: { placement: 'inverted', box: 'kotae' },
+ solutions: { placement: 'chapterEnd', box: 'kotae' },#Compon una pàgina de passatemps
La pàgina de passatemps gira les seves solucions de la mateixa manera, en targetes a dues columnes.
Errors freqüents
Error freqüent
Les fonts xineses es carreguen per fragments, amb el bloc cjk
Fontsource serveix una família xinesa, japonesa o coreana en un centenar de fitxers per pes, cadascun amb un interval de caràcters. loadFonts només baixa el fitxer latin, així que a la pantalla els caràcters xinesos surten d'una font del sistema i es mesuren malament, i fontsourceProvider lliura al PDF aquest fitxer latin, que els imprimeix com a caixes buides. Afegeix el bloc cjk del kit, crida loadCjkFonts(FONTS, markdown) després de loadFonts (una vegada per veu, amb el text que compon, si el llibre fa servir diverses fonts xineses) i passa a renderToPdf fontProvider: cjkPdfProvider: tots dos agafen els fitxers que contenen els caràcters del text. Fonts xineses, japoneses i coreanes →
Error freqüent
Etiqueta un text japonès 'ja', mai zh-Hans ni LANG
Les edicions d'una recepta són en i es, però una mostra japonesa és japonesa en totes dues: `locale: LANG` l'etiquetaria com a anglès o castellà, i una etiqueta xinesa la compondria amb les regles xineses (puntuació Kaiming, kana petit lliure de començar línia, 图 en lloc de 図, formes xineses dels caràcters al PDF). Des de postext 1.30 l'etiqueta és a més la llengua en què es compon el text (en què es mesura, es pinta i s'incrusta), de manera que qualsevol etiqueta que no sigui 'ja' dona altres formes de glif que les japoneses (les xineses, amb una etiqueta xinesa) i altres talls de línia. Escriu 'ja': tria la regió del Japó (tall i puntuació de la JLReq, punts de sèsam, repartiment dels furigana, etiquetes 図 i 表) i desactiva la partició de mots. El lint falla un text amb kana sota una etiqueta zh o ko. Tall de línies japonès (kinsoku) →
- Una lectura encara no pot anar sobre un buit: un ruby dins de
[[…]]forma part de la resposta amagada. L’exercici de 漢字の書き取り posa cada lectura en una línia pròpia i la casella darrere, tres per fila en un grup:::columns; a la pàgina vertical la lectura queda al costat de la casella, com el furigana. - Klee One només té els pesos 400 i 600:
boldFontWeight: 600deixa totes les negretes en un tall que existeix, també els números dels apartats i dels exercicis.
Crèdits
- Recepta
- Ignacio Ferro
- Text
- Text original, CC BY 4.0
- Imatges
- A young tanuki in a yellow school hat holding a big pencil. · Generated With Diffusion Models · original
- A fox cub in a red scarf reading a book. · Generated With Diffusion Models · original
- Fonts
- Klee One (SIL OFL 1.1) · Zen Maru Gothic (SIL OFL 1.1)
- Codi
- MIT, com Postext
Editar aquest text ↗ (s'obre en una pestanya nova)Carpeta de la recepta a GitHub ↗ (s'obre en una pestanya nova)


