En bref
Une fiche de sciences et de maths de deux pages sur le cycle de l’eau, faite dix fois. Les questions sont les mêmes ; les numéros, les cases, les lignes d’écriture et la division ressemblent à ceux des manuels de chaque pays.
Ce que vous allez composer
La fiche 7 d’un cours de sciences et de mathématiques de CM1, Le voyage de l’eau, en dix éditions. Les questions sont les mêmes dans toutes les langues : choisir une réponse, cocher vrai ou faux, compléter un texte à trous avec une liste de mots, relier des mots à leur définition, entourer un mot, partager l’eau d’une citerne, expliquer pourquoi il faut l’économiser. Chaque édition les imprime comme le font ses écoles. Les fiches espagnole et catalane mettent le numéro dans un disque, font cocher V ou F et posent la division avec le diviseur dans un L à droite du dividende. La française met ses numéros dans des carrés et utilise des cases à cocher, des pointillés pour les trous et une réglure Seyès pour la réponse. L’allemande écrit R et F, Lückentext et 864 : 4 = sur une ligne, avec un point pour la multiplication. La brésilienne demande V ou F entre parenthèses. L’anglaise divise sous le crochet ⟌. La chinoise numérote ses parties 一、二、, place ( ) après chaque énoncé avec A. B. C. sur une ligne, demande √ ou × et finit par 看拼音,写词语 dans des cases 田字格. La japonaise propose ア イ ウ et ○ ×, et l’arabe se lit de droite à gauche avec أ ب ج et صح ou خطأ.
Cette recette répond à
- Comment composer la même fiche comme les manuels de chaque pays composent leurs exercices ?
- Comment composer la division posée comme l'écrivent les écoles de chaque pays ?
- Comment composer des questions d'examen chinois : des parenthèses ( ) après l'énoncé et les options A. B. C. D. sur une ligne ?
La réponse courte
// The Markdown of every edition has the same seven exercises. What changes is this table:
// how the number prints, how options are labelled and answered, how true/false reads, where
// a blank is written, the paper of the open answer and the layout of long division.
const disc = { shape: 'disc' };
const square = { shape: 'square' };
const bare = { shape: 'none', suffix: '.' };
const TRADITIONS = {
es: { number: disc, options: { marker: 'none' }, trueFalse: { look: 'boxes' },
blank: { look: 'line' }, area: { kind: 'lines' }, arithmetic: { division: 'potence' } },
fr: { number: square, options: { marker: 'box' }, trueFalse: { look: 'boxes' },
blank: { look: 'dots' }, area: { kind: 'seyes', spacing: mm(8) },
arithmetic: { division: 'potence' } },
de: { number: square, options: { marker: 'box' }, trueFalse: { look: 'boxes' },
blank: { look: 'line' }, area: { kind: 'lines' }, arithmetic: { division: 'inline' } },
it: { number: { shape: 'rounded' }, options: { marker: 'box' }, trueFalse: { look: 'boxes' },
blank: { look: 'dots' }, area: { kind: 'lines' }, arithmetic: { division: 'potence' } },
pt: { number: bare, options: { marker: 'none' }, trueFalse: { look: 'bracket' },
blank: { look: 'line' }, area: { kind: 'lines' }, arithmetic: { division: 'potence' } },
en: { number: bare, options: { marker: 'none' }, trueFalse: { look: 'boxes' },
blank: { look: 'line' }, area: { kind: 'lines' }, arithmetic: { division: 'bracket' } },
// 一、二、 sections; ( ) after the stem and A. B. C. in a row; √ × in a bracket; 田字格.
zh: { number: { shape: 'none', format: 'simp-chinese-informal', suffix: '、' },
options: { labels: 'alpha-upper', suffix: '.', layout: 'row', bracket: true },
trueFalse: { look: 'bracket' }, blank: { look: 'line' },
area: { kind: 'tianzige', spacing: mm(13), lines: 1 }, arithmetic: { division: 'bracket' } },
// ア イ ウ in a row with ( ), ○ × in a bracket, the number in a square.
ja: { number: square, options: { labels: 'katakana', suffix: '', layout: 'row', bracket: true },
trueFalse: { look: 'bracket' }, blank: { look: 'line' }, area: { kind: 'lines' },
arithmetic: { division: 'bracket' } },
ar: { number: disc, options: { marker: 'none', prefix: '(', suffix: ')' },
trueFalse: { look: 'boxes' },
blank: { look: 'dots' }, area: { kind: 'lines' }, arithmetic: { division: 'bracket' } },
};
TRADITIONS.ca = TRADITIONS.es; // Catalan schools set exercises as Spanish ones do
Ingrédients
- Fonctionnalités
- Styles d'exerciceOpérations poséesChoix et vrai ou fauxExercicesTextes à trous et banques de motsRelier et classerQuestions ouvertes et zones d'écritureOuvertures composéesAttributs de titrePalette de couleurs sémantiquePolices chinoises, japonaises et coréennesPolices arabesLivres reliés à droiteTexte de droite à gaucheCésure et langue du documentPages sur un canvasExport PDF
- Utilise aussi
- CorrigésStyles de paragraphePolices intégrées au PDF
- Typographie
- Nunito, Baloo 2, Noto Serif SC, Noto Sans SC, Klee One, Noto Sans JP, Noto Naskh Arabic, Baloo Bhaijaan 2 (SIL OFL 1.1)
- Ressources
- Aucune : chaque image est dessinée en code
Préparation
#1 · Mettre chaque tradition dans un tableau
// The Markdown of every edition has the same seven exercises. What changes is this table:
// how the number prints, how options are labelled and answered, how true/false reads, where
// a blank is written, the paper of the open answer and the layout of long division.
const disc = { shape: 'disc' };
const square = { shape: 'square' };
const bare = { shape: 'none', suffix: '.' };
const TRADITIONS = {
es: { number: disc, options: { marker: 'none' }, trueFalse: { look: 'boxes' },
blank: { look: 'line' }, area: { kind: 'lines' }, arithmetic: { division: 'potence' } },
fr: { number: square, options: { marker: 'box' }, trueFalse: { look: 'boxes' },
blank: { look: 'dots' }, area: { kind: 'seyes', spacing: mm(8) },
arithmetic: { division: 'potence' } },
de: { number: square, options: { marker: 'box' }, trueFalse: { look: 'boxes' },
blank: { look: 'line' }, area: { kind: 'lines' }, arithmetic: { division: 'inline' } },
it: { number: { shape: 'rounded' }, options: { marker: 'box' }, trueFalse: { look: 'boxes' },
blank: { look: 'dots' }, area: { kind: 'lines' }, arithmetic: { division: 'potence' } },
pt: { number: bare, options: { marker: 'none' }, trueFalse: { look: 'bracket' },
blank: { look: 'line' }, area: { kind: 'lines' }, arithmetic: { division: 'potence' } },
en: { number: bare, options: { marker: 'none' }, trueFalse: { look: 'boxes' },
blank: { look: 'line' }, area: { kind: 'lines' }, arithmetic: { division: 'bracket' } },
// 一、二、 sections; ( ) after the stem and A. B. C. in a row; √ × in a bracket; 田字格.
zh: { number: { shape: 'none', format: 'simp-chinese-informal', suffix: '、' },
options: { labels: 'alpha-upper', suffix: '.', layout: 'row', bracket: true },
trueFalse: { look: 'bracket' }, blank: { look: 'line' },
area: { kind: 'tianzige', spacing: mm(13), lines: 1 }, arithmetic: { division: 'bracket' } },
// ア イ ウ in a row with ( ), ○ × in a bracket, the number in a square.
ja: { number: square, options: { labels: 'katakana', suffix: '', layout: 'row', bracket: true },
trueFalse: { look: 'bracket' }, blank: { look: 'line' }, area: { kind: 'lines' },
arithmetic: { division: 'bracket' } },
ar: { number: disc, options: { marker: 'none', prefix: '(', suffix: ')' },
trueFalse: { look: 'boxes' },
blank: { look: 'dots' }, area: { kind: 'lines' }, arithmetic: { division: 'bracket' } },
};
TRADITIONS.ca = TRADITIONS.es; // Catalan schools set exercises as Spanish ones do
Toutes les éditions ont le même Markdown : sept blocs :::exercise dont les réponses sont dans le texte (- [x], [[vapeur]], - Évaporation -> L'eau devient vapeur, - 864 : 4). Ce qui change d’un pays à l’autre, c’est la forme, et elle vit dans ce tableau et nulle part ailleurs : la forme et les chiffres du numéro, les lettres des options et le geste de l’élève (cocher une case ou entourer une lettre), l’aspect du vrai ou faux, celui des trous, la zone d’écriture et la disposition de la division. Le catalan reprend telle quelle la ligne de l’espagnol.
#2 · Poser la tradition sur le style de la maison
const T = TRADITIONS[LANG];
const ficha = {
id: 'ficha', ...T,
number: { background: col('accent'), color: T.number.shape === 'none' ? col('accent')
: col('paper'), fontFamily: LABEL, fontWeight: 700, ...T.number },
// Chinese and Japanese sheets set the instructions in the gothic (黑体, ゴシック).
instruction: { bold: true, color: col('ink'), ...(LANG === 'zh' || LANG === 'ja'
? { fontFamily: LABEL } : {}) },
blank: { color: col('ink'), weight: pt(0.7), ...T.blank },
match: { look: 'dots', gap: em(5), color: col('accent') },
bank: { order: 'alpha' },
area: { color: col('rule'), spacing: mm(9), weight: pt(0.6), ...T.area },
grid: { cell: mm(8.5), fontFamily: TEXT, rule: col('rule'), color: col('ink') },
marginTop: mm(7), marginBottom: mm(1), itemSpacing: em(0.4),
};
Un seul style d’exercice, ficha, porte ce que les dix fiches ont en commun (le bleu des numéros, les filets gris, l’espace entre les exercices), et la ligne de l’édition se pose par-dessus. Ce que la ligne ne précise pas vient de la langue : T F, V F, R F, √ ×, ○ × et صح خطأ sont des mots du moteur lui-même, comme a) b) c), A. B. C., ア イ ウ et أ ب ج, si bien qu’aucune édition ne les écrit.
#3 · Donner à chaque écriture ses polices
const FACES = {
zh: { text: 'Noto Serif SC', label: 'Noto Sans SC' },
ja: { text: 'Klee One', label: 'Noto Sans JP' },
ar: { text: 'Noto Naskh Arabic', label: 'Baloo Bhaijaan 2' },
}[LANG] ?? { text: 'Nunito', label: 'Baloo 2' };
const [TEXT, LABEL] = [FACES.text, FACES.label];
Les éditions en alphabet latin partagent Nunito et Baloo 2. La fiche chinoise compose le texte en Song et les consignes en Hei ; la japonaise compose le texte en Klee One, une police de manuel scolaire, et les consignes dans une gothique ; l’arabe utilise Noto Naskh Arabic. La graisse la plus forte de Klee One est 600, donc l’édition japonaise règle son gras à 600 (boldFontWeight) : un 700 serait dessiné par le navigateur et ferait échouer la capture.
#4 · Mettre en tête de la fiche des lignes pour le nom
const at = (to, edge, x = 0, y = 0, size) => ({ anchor: { to, edge },
offset: { x: mm(x), y: mm(y) }, ...(size && { size }) });
const field = (id, attr, x, width) => [
{ kind: 'text', id, content: `{attr.${attr}}`, fontFamily: LABEL, fontSize: pt(10),
fontWeight: 700, color: col('muted'), align: 'left', placement: at('container', 'top-left',
x, 28) },
{ kind: 'rule', id: `${id}-line`, direction: 'horizontal', thickness: pt(0.75),
color: col('rule'), placement: at('container', 'top-left', x + 16, 33, { width: mm(width) }) },
];
const head = { enabled: true, minHeight: mm(38), slot: { elements: [
{ kind: 'box', id: 'band', style: { backgroundColor: col('accent'), borderRadius: mm(3) },
placement: at('container', 'top-left', 0, 0, { width: 'fill', height: mm(21) }) },
{ kind: 'text', id: 'kicker', content: '{title} · {subtitle}', fontFamily: LABEL,
fontSize: pt(8.5), fontWeight: 700, color: col('tint'), align: 'left',
placement: at('container', 'top-left', 6, 3.5) },
{ kind: 'text', id: 'title', content: '{titleText}', fontFamily: LABEL, fontSize: pt(22),
fontWeight: 700, color: col('paper'), align: 'left', lineHeight: 1.1,
placement: at('container', 'top-left', 6, 9.5) },
...field('name', 'nombre', 0, 96), ...field('date', 'fecha', 120, 40),
] } };
Le titre de niveau 1 dessine le bandeau, le cours tiré du frontmatter et le titre, ainsi que deux champs sur une ligne dont les mots viennent des attributs du titre (nombre="Prénom" fecha="Date"). La fiche allemande dit donc Datum et la japonaise 名前 sans une seule chaîne dans le code.
La recette complète
// ═══ Postext Cookbook · Nº 169 · One worksheet in ten school traditions ═════════
// https://postext.dev/en/cookbook/school-traditions-worksheet
// Code: MIT · Text: original (CC BY 4.0) · Pictures: none
// Fonts: Nunito, Baloo 2, Klee One, Noto Naskh Arabic and others (SIL OFL) · Needs postext ≥ 1.59.0
import {
buildDocument, withLoadedFonts, renderPageToCanvas,
} from 'https://esm.sh/postext';
import { renderToPdf, decompressWoff2 } from 'https://esm.sh/postext-pdf';
const LANG = 'fr'; // @lang: the language of the worksheet (en es ca fr de it pt zh ja ar)
const RECIPE = 'school-traditions-worksheet';
// ─── 1 · Design ─────────────────────────────────────────────────────────────
// #region palette: a blue-black ink, one blue accent, a pale tint, grey rules
const palette = {
ink: '#1d2633', accent: '#2a5d9f', tint: '#e8f0fa', rule: '#a9b6c6', muted: '#5d6878',
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.accent, model: 'hex' } },
];
// #endregion
// #region faces: Latin editions share two faces; Chinese, Japanese and Arabic their own
const FACES = {
zh: { text: 'Noto Serif SC', label: 'Noto Sans SC' },
ja: { text: 'Klee One', label: 'Noto Sans JP' },
ar: { text: 'Noto Naskh Arabic', label: 'Baloo Bhaijaan 2' },
}[LANG] ?? { text: 'Nunito', label: 'Baloo 2' };
const [TEXT, LABEL] = [FACES.text, FACES.label];
// #endregion
// #region answer: the form of the exercises, as each country's school books set them
// The Markdown of every edition has the same seven exercises. What changes is this table:
// how the number prints, how options are labelled and answered, how true/false reads, where
// a blank is written, the paper of the open answer and the layout of long division.
const disc = { shape: 'disc' };
const square = { shape: 'square' };
const bare = { shape: 'none', suffix: '.' };
const TRADITIONS = {
es: { number: disc, options: { marker: 'none' }, trueFalse: { look: 'boxes' },
blank: { look: 'line' }, area: { kind: 'lines' }, arithmetic: { division: 'potence' } },
fr: { number: square, options: { marker: 'box' }, trueFalse: { look: 'boxes' },
blank: { look: 'dots' }, area: { kind: 'seyes', spacing: mm(8) },
arithmetic: { division: 'potence' } },
de: { number: square, options: { marker: 'box' }, trueFalse: { look: 'boxes' },
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
#Imprimer l’exemplaire du maître
Chaque réponse va à sa place en magenta : les parenthèses, les cases, les trous et le quotient.
exerciseStyles: [ficha],
+ exercises: { edition: 'teacher' },#Regrouper les réponses en bas de la fiche
placement: 'after' place le corrigé de chaque exercice sous celui-ci ; 'inverted' le retourne tête en bas, comme dans les pages de jeux.
+ exercises: { solutions: { placement: 'inverted', layout: 'key' } },Erreurs fréquentes
- Une police sans graisse 700 donne aux numéros des énoncés un gras synthétique. Donnez à une telle police de texte un
boldFontWeightavec une graisse qu’elle possède. - Le ○ des consignes japonaises et le √ des consignes chinoises n’existent que dans les polices CJK : placez-les dans une phrase du texte CJK, pas dans une étiquette latine.
Crédits
- Recette
- Ignacio Ferro
- Texte
- Texte original, CC BY 4.0
- Polices
- Nunito (SIL OFL 1.1) · Baloo 2 (SIL OFL 1.1) · Noto Serif SC (SIL OFL 1.1) · Noto Sans SC (SIL OFL 1.1) · Klee One (SIL OFL 1.1) · Noto Sans JP (SIL OFL 1.1) · Noto Naskh Arabic (SIL OFL 1.1) · Baloo Bhaijaan 2 (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)


