Aller au contenu principal
Recette numéro 172

Recettes · Chapitre 12 · Manuels scolaires

Un cahier japonais aux corrigés imprimés à l’envers

Deux pages d’une série de cahiers d’exercices japonais, le calcul à l’horizontale et les kanji en colonnes, chaque exercice suivi de son corrigé à l’envers.

Sur cette page
Sortie
Canvas · PDF
Postext
Testé avec Postext 1.59.0
Nécessite ≥ 1.59.0 · postext-pdf ≥ 1.59.0
Licence
Mis à jour le 24 oct. 2026
Code MIT · Texte CC BY 4.0
  • Exemple en langue étrangère : pas encore d’édition française
  • Format 182 × 257 mm
  • 1 colonne
  • Klee One 12/22
  • Zen Maru Gothic
  • 4 pages
  • Niveau
  • Postext 1.59.0
  • Mis en page en 105 ms
  • 137 lignes de code

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

script.js · lignes 35–55dans le code complet
// `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

Typographie
Klee One, Zen Maru Gothic (SIL OFL 1.1)
Ressources
  • kitsune-600.jpg
  • tanuki-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

script.js · lignes 59–76dans le code complet
// 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

script.js · lignes 271–279dans le code complet
// 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

Sandbox
// ═══ 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: 600 garde chaque passage en gras dans une graisse qui existe, numéros des questions et des exercices compris.

Crédits

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)
Sandbox