En bref
Un cahier d’école japonais : opérations, cases, choix et vrai ou faux sur une page, kanji et lectures de haut en bas sur une autre. Sous chaque exercice, le corrigé est imprimé à l’envers ; l’enfant retourne le cahier pour vérifier.
Ce que vous allez composer
Deux pages d’une série de cahiers d’exercices de CE2, au format B5. La page de calcul se lit à l’horizontale : une bande bleu pâle avec la pastille de la matière, le titre et un tanuki en mascotte, une ligne pour le nom et une case pour la note, puis des ひっ算 (opérations posées) avec une case pour chaque chiffre du résultat, des cases à remplir après six calculs, des choix ア イ ウ sur une ligne, des affirmations ○× avec une parenthèse en fin de ligne et deux problèmes avec des lignes pour poser le calcul. La page de kanji est composée comme on imprime un cahier de 国語, de haut en bas et de droite à gauche : des lectures avec une case pour le kanji, des mots soulignés dont la lecture va entre parenthèses, des choix à entourer et un sens à trouver. Sous chaque exercice, le corrigé est imprimé à l’envers en petits caractères gris. L’enfant voit où il se trouve, ne peut pas le lire d’un coup d’œil et retourne le cahier pour vérifier.
Cette recette répond à
- Comment imprimer les réponses à l'envers au pied d'un exercice ?
- Comment composer une page d'exercices japonaise en colonnes verticales avec la même maquette que la page horizontale ?
- Comment composer la division posée comme l'écrivent les écoles de chaque pays ?
La réponse courte
// `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 };
Ingrédients
- Fonctionnalités
- CorrigésStyles d'exerciceTexte verticalExercicesOpérations poséesTextes à trous et banques de motsChoix et vrai ou fauxQuestions ouvertes et zones d'écritureKana, kanji et rōmajiPolices chinoises, japonaises et coréennesTraits latéraux (bōsen)Livres reliés à droitePastilles dans le texteTrois colonnes ou plusOuvertures composéesAttributs de titreImages dans les maquettes de pageAncrer les éléments de maquettePalette de couleurs sémantiqueExport PDF
- Utilise aussi
- Colonnes dans un encadré ou dans le texteEncadrés qui se coupent ou restent entiersCoupure des lignes en chinoisÉquilibrage des colonnesStyles de paragraphePolices intégrées au PDFFigures et tableaux comme ressources
- Typographie
- Klee One, Zen Maru Gothic (SIL OFL 1.1)
- Ressources
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)
Préparation
#1 · Retourner le corrigé de chaque exercice
Le code est dans la réponse courte plus haut. placement: 'inverted' place le corrigé après chaque exercice dans un encadré tourné de 180°, et cet encadré se loge dans celui de l’exercice : un saut de page ne sépare donc jamais les deux. Le corrigé est tiré de l’exercice : les opérations avec leur résultat, le katakana de la bonne réponse, ○ et ×, les mots des trous. Le style d’encadré du corrigé, kotae, se contente de composer le texte en petit et en gris.
#2 · Une bande pour une page horizontale et une page verticale
// 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) } } },
] } };
Sur une page verticale, une maquette de titre se pose le long de sa colonne : x descend la page et y va vers la gauche. La bande ancrée en top-left sur toute la largeur se tient en haut de la page de calcul et le long du bord droit de la page de kanji ; la mascotte ancrée en top-right se place au bout de la bande sur les deux pages. Rien dans la maquette ne nomme une direction.
#3 · Deux cahiers pour un seul texte
// 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 configuration est une fonction : chaque composition reçoit son propre objet, et seul writingMode change entre les deux. Composé à la verticale, le cahier de 国語 se relie à droite de lui-même ; showBook place chaque cahier de son côté du dos. Le texte est composé en Klee One, un caractère de manuel scolaire, et les étiquettes en Zen Maru Gothic ; les deux chargent leur ponctuation verticale pour les parenthèses de la page de kanji.
La recette complète
// ═══ 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' },
Le script.js composé s’exécute tel quel : collez-le dans le script de module de n’importe quelle page, ou ouvrez la recette sur CodePen. Dossier de la recette sur GitHub ↗ (s’ouvre dans un nouvel onglet)
Variantes
#Regrouper les corrigés à la fin
Un cahier vendu avec un livret de corrigés garde les réponses hors des pages : chapterEnd les liste après le dernier exercice.
- solutions: { placement: 'inverted', box: 'kotae' },
+ solutions: { placement: 'chapterEnd', box: 'kotae' },#Composer une page de jeux
La page de jeux retourne ses solutions de la même façon, sur des cartes en deux colonnes.
Erreurs fréquentes
Erreur fréquente
Les polices chinoises se chargent par tranches, avec le bloc cjk
Fontsource sert une famille chinoise, japonaise ou coréenne sous la forme d’une centaine de fichiers par graisse, chacun couvrant une plage de caractères. loadFonts ne récupère que le fichier latin : à l’écran, les caractères han viennent d’une police système et sont mal mesurés, et fontsourceProvider remet ce fichier latin au PDF, qui les imprime en cases vides. Listez le bloc cjk du kit, appelez loadCjkFonts(FONTS, markdown) après loadFonts (une fois par voix, avec le texte qu’elle compose, quand le livre utilise plusieurs polices CJK) et donnez à renderToPdf fontProvider: cjkPdfProvider : les deux prennent les fichiers qui contiennent les caractères du texte. Polices chinoises, japonaises et coréennes →
Erreur fréquente
Balisez un texte japonais 'ja', jamais zh-Hans ni LANG
Les éditions d’une recette sont en et es, mais un exemple japonais est en japonais dans les deux : `locale: LANG` le baliserait en anglais ou en espagnol, et une balise chinoise le composerait selon les règles chinoises (ponctuation Kaiming, petits kana libres de commencer une ligne, 图 pour 図, formes de glyphes chinoises dans le PDF). Depuis postext 1.30, la balise est aussi la langue dans laquelle le texte est mis en forme (mesuré, peint et incorporé) : toute balise autre que 'ja' donne d’autres formes de glyphes que les japonaises (les chinoises sous une balise chinoise) et d’autres coupures de ligne. Écrivez 'ja' : elle choisit la région Japon (coupure des lignes et ponctuation JLReq, points d’emphase sésame, espacement des furigana, étiquettes 図 et 表) et désactive la césure. Le lint fait échouer un texte contenant des kana sous une balise zh ou ko. Coupure des lignes en japonais (kinsoku) →
- Une lecture ne peut pas encore se placer au-dessus d’un blanc : un ruby dans
[[…]]fait partie de la réponse cachée. L’exercice 漢字の書き取り met chaque lecture sur sa propre ligne et la case juste après, trois par rangée dans un groupe:::columns; sur la page verticale, la lecture se tient à côté de la case, comme des furigana. - Klee One n’existe qu’en 400 et 600 :
boldFontWeight: 600garde chaque passage en gras dans une graisse qui existe, numéros des questions et des exercices compris.
Crédits
- Recette
- Ignacio Ferro
- Texte
- Texte original, CC BY 4.0
- Images
- 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
- Polices
- Klee One (SIL OFL 1.1) · Zen Maru Gothic (SIL OFL 1.1)
Modifier ce texte ↗ (s’ouvre dans un nouvel onglet)Dossier de la recette sur GitHub ↗ (s’ouvre dans un nouvel onglet)


