Saltar al contenido principal
Receta número 169

Recetario · Capítulo 12 · Libros de texto

Una ficha en diez tradiciones escolares

Las mismas siete vallas :::exercise en diez idiomas, cada edición impresa con un estilo de ejercicio que sigue los libros escolares de su país.

En esta página
Salida
Canvas · PDF
Postext
Probada con Postext 1.59.0
Requiere ≥ 1.59.0 · postext-pdf ≥ 1.59.0
Licencia
Actualizada el 24 oct 2026
Código MIT · Texto CC BY 4.0
  • Formato 210 × 297 mm
  • 1 columna
  • Nunito 12/18
  • Baloo 2
  • 2 páginas
  • Nivel
  • Postext 1.59.0
  • Compuesto en 98 ms
  • 154 líneas de código

En pocas palabras

Una ficha de Ciencias y Matemáticas de dos páginas sobre el ciclo del agua, hecha diez veces. Las preguntas son las mismas; los números, las casillas, los renglones y la división se ven como los imprimen los libros de cada país.

Lo que vas a componer

La ficha 7 de un curso de Ciencias y Matemáticas de 4.º de Primaria, El agua, de viaje, en diez ediciones. Las preguntas son las mismas en todos los idiomas: elegir una respuesta, marcar verdadero o falso, completar con un banco de palabras, unir palabras con su significado, rodear una palabra, repartir el agua de un depósito y explicar por qué ahorrarla. Cada edición las imprime como lo hacen sus escuelas. Las fichas española y catalana ponen el número en un círculo, marcan V o F y dividen con el divisor en una caja a la derecha del dividendo. La francesa usa cuadrados, cases à cocher, huecos de puntos y papel Seyès para la respuesta. La alemana escribe R y F, Lückentext y 864 : 4 = en una línea, con la multiplicación en punto. La brasileña pide V o F entre paréntesis. La inglesa divide bajo la casita ⟌. La china numera sus secciones 一、二、, pone ( ) tras cada enunciado con A. B. C. en fila, pide √ o × y termina con 看拼音,写词语 en cuadros 田字格. La japonesa ofrece ア イ ウ y ○ ×, y la árabe va de derecha a izquierda con أ ب ج y صح o خطأ.

Esta receta responde a

  • ¿Cómo compongo la misma ficha tal como los libros escolares de cada país componen sus ejercicios?
  • ¿Cómo compongo la división larga tal como la escriben las escuelas de cada país?
  • ¿Cómo compongo preguntas de examen chino: un paréntesis ( ) tras el enunciado y las opciones A. B. C. D. en una fila?

La respuesta corta

script.js · líneas 36–69en el código completo
// 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

Ingredientes

Tipografía
Nunito, Baloo 2, Noto Serif SC, Noto Sans SC, Klee One, Noto Sans JP, Noto Naskh Arabic, Baloo Bhaijaan 2 (SIL OFL 1.1)
Recursos
Ninguno: todas las imágenes se dibujan en código

Elaboración

#1 · Pon cada tradición en una tabla

script.js · líneas 36–69en el código completo
// 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

Todas las ediciones tienen el mismo Markdown: siete vallas :::exercise con las respuestas en el texto (- [x], [[vapor]], - Evaporación -> El agua se convierte en vapor, - 864 : 4). Lo que cambia de un país a otro es la forma, así que vive en esta tabla y en ningún otro sitio: la figura y las cifras del número, las letras de las opciones y si el alumno marca una casilla o rodea una letra, el aspecto del verdadero o falso, el de los huecos, la zona de escritura y la colocación de la división. El catalán toma la fila del español tal cual.

#2 · Pon la tradición sobre el estilo de la casa

script.js · líneas 73–87en el código completo
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 solo estilo de ejercicio, ficha, lleva lo que comparten las diez fichas (el azul de los números, los filetes grises, el aire entre ejercicios), y la fila de la edición se extiende sobre él. Lo que la fila no dice viene del idioma: T F, V F, R F, √ ×, ○ × y صح خطأ son palabras del propio motor, igual que a) b) c), A. B. C., ア イ ウ y أ ب ج, así que ninguna edición las escribe.

#3 · Da a cada escritura sus fuentes

script.js · líneas 27–32en el código completo
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];

Las ediciones latinas comparten Nunito y Baloo 2. La ficha china compone el texto en Song y los enunciados en Hei; la japonesa, el texto en Klee One, una letra de libro de texto, y los enunciados en una gótica; la árabe usa Noto Naskh Arabic. El corte más grueso de Klee One es el 600, así que la edición japonesa pone su negrita a 600 (boldFontWeight): un 700 lo dibujaría el navegador y la captura fallaría.

#4 · Encabeza la ficha con renglones para el nombre

script.js · líneas 91–110en el código completo
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),
] } };

El título de nivel 1 dibuja la banda, el curso tomado del frontmatter y el título, y dos campos con renglón cuyas palabras salen de los atributos del título (nombre="Nombre" fecha="Fecha"), así que la ficha alemana dice Datum y la japonesa 名前 sin una cadena en el código.

La receta completa

Sandbox
// ═══ 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 = 'es'; // @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' },

El script.js compuesto funciona tal cual: pégalo como script de módulo en cualquier página o abre la receta en CodePen. Carpeta de la receta en GitHub ↗ (se abre en una nueva pestaña)

Variantes

#Imprime la copia del profesor

Cada respuesta va a su sitio en magenta: los paréntesis, las casillas, los huecos y el cociente.

   exerciseStyles: [ficha],
+  exercises: { edition: 'teacher' },

#Reúne las soluciones al pie de la ficha

placement: 'after' pone la clave de cada ejercicio debajo de él; 'inverted' la gira boca abajo, como en las páginas de pasatiempos.

+  exercises: { solutions: { placement: 'inverted', layout: 'key' } },

Errores frecuentes

  • Una fuente sin corte 700 hace sintética la negrita de los números de los enunciados. Da a esa fuente de texto un boldFontWeight con un peso que tenga.
  • El ○ de los enunciados japoneses y el √ de los chinos solo están en las fuentes CJK: ponlos en una frase del texto CJK, no en un rótulo latino.

Créditos

Texto
Texto original, CC BY 4.0
Fuentes
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)
SandboxPDF