Saltar al contenido principal
Receta número 170

Recetario · Capítulo 12 · Libros de texto

Cuentas en columna como las escribe cada país

Una ficha de cálculo cuyas cuentas son líneas - 864 : 4 del Markdown, cifra a cifra en casillas, con la división como la hacen las escuelas de cada país.

En esta página
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
  • Fira Sans 12/18
  • Lexend
  • 4 páginas
  • Nivel
  • Postext 1.59.0
  • Compuesto en 62 ms
  • 118 líneas de código

En pocas palabras

Una página de cuentas para niños de nueve años en español, inglés, francés y alemán. Cada país escribe la división a su manera y la ficha lo sigue; un interruptor muestra la copia del profesor con todas las respuestas.

Lo que vas a componer

La unidad 3 de un cuaderno de cálculo de 4.º de Primaria, Las cuatro operaciones, en cuatro ediciones. Una fila de cálculo mental en tres columnas; sumas, restas y multiplicaciones escritas con una cifra por casilla y una fila de casillas para el resultado; divisiones y un problema en cuadrícula. En la división se separan las ediciones: la española y la francesa ponen el divisor en una caja a la derecha del dividendo y el cociente debajo; la inglesa lo deja fuera del signo ⟌, la «casita», con el cociente encima; la alemana escribe 864 : 4 = en una línea con sitio debajo para los pasos, y sus productos con un punto. La coma o el punto decimal del cálculo mental sigue también al idioma. Un interruptor sobre las páginas convierte la ficha del alumno en la copia del profesor, con cada respuesta en naranja en su casilla.

Esta receta responde a

  • ¿Cómo compongo la división larga tal como la escriben las escuelas de cada país?
  • ¿Cómo saco la edición del profesor, con las respuestas impresas en su sitio, del mismo libro del alumno?

La respuesta corta

script.js · líneas 26–42en el código completo
// `- 864 : 4` in the Markdown is one operation; the style sets it digit by digit in squares
// of 7.2 mm, a cell for each figure of the answer. Long division follows the country: the
// divisor in an L right of the dividend in Spain and France (potence), `864 : 4 =` on one
// line in Germany, the bracket ⟌ in English-speaking schools.
const calculo = {
  id: 'calculo',
  number: { shape: 'disc', background: col('accent'), fontFamily: LABEL, fontWeight: 700 },
  instruction: { bold: true, color: col('ink') },
  grid: { cell: mm(9), fontFamily: TEXT, fontSize: pt(15), rule: col('rule'),
    color: col('ink') },
  arithmetic: { columns: 4,
    division: t({ es: 'potence', fr: 'potence', de: 'inline', en: 'bracket' }) },
  blank: { look: 'box', width: em(3.2), color: col('rule'), weight: pt(0.8) },
  area: { kind: 'grid', spacing: mm(5), color: col('rule'), weight: pt(0.4) },
  answers: { color: col('accent'), fontFamily: LABEL }, // the teacher's copy, in the accent
  marginTop: mm(7), marginBottom: mm(2), itemSpacing: em(0.5),
};

Ingredientes

Tipografía
Fira Sans, Lexend (SIL OFL 1.1)
Recursos
Ninguno: todas las imágenes se dibujan en código

Elaboración

#1 · Escribe las cuentas como líneas del Markdown

script.js · líneas 26–42en el código completo
// `- 864 : 4` in the Markdown is one operation; the style sets it digit by digit in squares
// of 7.2 mm, a cell for each figure of the answer. Long division follows the country: the
// divisor in an L right of the dividend in Spain and France (potence), `864 : 4 =` on one
// line in Germany, the bracket ⟌ in English-speaking schools.
const calculo = {
  id: 'calculo',
  number: { shape: 'disc', background: col('accent'), fontFamily: LABEL, fontWeight: 700 },
  instruction: { bold: true, color: col('ink') },
  grid: { cell: mm(9), fontFamily: TEXT, fontSize: pt(15), rule: col('rule'),
    color: col('ink') },
  arithmetic: { columns: 4,
    division: t({ es: 'potence', fr: 'potence', de: 'inline', en: 'bracket' }) },
  blank: { look: 'box', width: em(3.2), color: col('rule'), weight: pt(0.8) },
  area: { kind: 'grid', spacing: mm(5), color: col('rule'), weight: pt(0.4) },
  answers: { color: col('accent'), fontFamily: LABEL }, // the teacher's copy, in the accent
  marginTop: mm(7), marginBottom: mm(2), itemSpacing: em(0.5),
};

Un :::exercise{type="arithmetic"} lleva una operación por elemento de lista, - 864 : 4, con los signos que escribe su país (:, ÷, ×, ·). El motor calcula el resultado, el cociente y el resto, y el estilo decide cómo se dibuja la cuenta: casillas de 7,2 mm y arithmetic.division elegida por edición con t(). La fila de cálculo mental es un ejercicio de huecos corriente cuya lista va en un grupo :::columns{count=3}, cada [[70]] una casilla del mismo ancho que las demás.

#2 · Encabeza la ficha

script.js · líneas 46–67en 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(9.5),
    fontWeight: 600, color: col('muted'), align: 'left',
    placement: at('container', 'top-left', x, 26) },
  { kind: 'rule', id: `${id}-line`, direction: 'horizontal', thickness: pt(0.75),
    color: col('rule'), placement: at('container', 'top-left', x + 17, 31, { width: mm(width) }) },
];
const head = { enabled: true, minHeight: mm(36), slot: { elements: [
  { kind: 'box', id: 'band', style: { backgroundColor: col('accent'), borderRadius: mm(3) },
    placement: at('container', 'top-left', 0, 0, { width: 'fill', height: mm(19) }) },
  { kind: 'text', id: 'unit', content: '{attr.unidad}', fontFamily: LABEL, fontSize: pt(9),
    fontWeight: 700, color: col('accent'), align: 'center', verticalAlign: 'middle',
    textTransform: 'uppercase', letterSpacing: pt(1.2), lineHeight: 1.1,
    box: { backgroundColor: col('paper'), borderRadius: mm(3.5) },
    placement: at('container', 'top-left', 5, 5, { width: mm(26), height: mm(9) }) },
  { kind: 'text', id: 'title', content: '{titleText}', fontFamily: LABEL, fontSize: pt(21),
    fontWeight: 700, color: col('paper'), align: 'left', lineHeight: 1.1,
    placement: at('container', 'top-left', 37, 5.2) },
  ...field('name', 'nombre', 0, 100), ...field('date', 'fecha', 124, 38),
] } };

El título de nivel 1 de la unidad dibuja la banda naranja, la pastilla y el título, y los campos de nombre y fecha a partir de sus atributos (nombre="Nombre" fecha="Fecha"), así que cada edición los rotula en su idioma.

#3 · Cambia entre la ficha del alumno y la copia del profesor

script.js · líneas 180–194en el código completo
const form = document.getElementById('controls');
const labels = t({ es: ['Alumno', 'Profesor'], en: ['Pupil', 'Teacher'],
  fr: ['Élève', 'Enseignant'], de: ['Schüler', 'Lehrkraft'] });
form.querySelectorAll('label span').forEach((span, k) => { span.textContent = labels[k]; });
function render() {
  // The same config, edited in place: the next build sees the edition the form asks for.
  config.exercises.edition = form.elements.edition.value;
  const doc = buildDocument({ markdown }, config); // the faces are loaded by now
  showPages(doc, { title });
  document.querySelectorAll('#pt-actions a, [data-postext-pdf]').forEach((old) => old.remove());
  offerPdf(() => renderToPdf(doc, { fontProvider: fontsourceProvider }),
    `${RECIPE}-${LANG}-${config.exercises.edition}.pdf`);
}
form.addEventListener('change', render);
render();

exercises.edition: 'teacher' imprime cada respuesta en su sitio con el color de answers.color, aquí el de acento: las casillas del cálculo mental, las cifras de cada resultado, el cociente y el resto, la respuesta modelo del problema. El formulario sobre las páginas cambia la configuración en su sitio y vuelve a componer; las fuentes ya están cargadas, así que basta con buildDocument. La captura compone antes las dos fichas, de modo que las páginas publicadas muestran la del alumno y luego la del profesor.

La receta completa

Sandbox
// ═══ Postext Cookbook · Nº 170 · Column arithmetic as each country writes it ═══════
// https://postext.dev/en/cookbook/column-arithmetic-by-country
// Code: MIT · Text: original (CC BY 4.0) · Pictures: none
// Fonts: Fira Sans, Lexend (SIL OFL 1.1) · Needs postext ≥ 1.59.0
import { buildDocumentWithFonts, buildDocument, renderPageToCanvas } from 'https://esm.sh/postext';
import { renderToPdf, decompressWoff2 } from 'https://esm.sh/postext-pdf';

const LANG = 'es'; // @lang: the language of the worksheet ('es' | 'en' | 'fr' | 'de')
const RECIPE = 'column-arithmetic-by-country';

// ─── 1 · Design ─────────────────────────────────────────────────────────────
// #region palette: ink, one orange accent, a pale tint, the grey of squared paper
const palette = {
  ink: '#1f2328', accent: '#c4511c', tint: '#fbeee6', rule: '#b9c0c8', muted: '#5f6670',
  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
const [TEXT, LABEL] = ['Fira Sans', 'Lexend'];

// #region answer: operations in squares, long division as the edition's schools set it
// `- 864 : 4` in the Markdown is one operation; the style sets it digit by digit in squares
// of 7.2 mm, a cell for each figure of the answer. Long division follows the country: the
// divisor in an L right of the dividend in Spain and France (potence), `864 : 4 =` on one
// line in Germany, the bracket ⟌ in English-speaking schools.
const calculo = {
  id: 'calculo',
  number: { shape: 'disc', background: col('accent'), fontFamily: LABEL, fontWeight: 700 },
  instruction: { bold: true, color: col('ink') },
  grid: { cell: mm(9), fontFamily: TEXT, fontSize: pt(15), rule: col('rule'),
    color: col('ink') },
  arithmetic: { columns: 4,
    division: t({ es: 'potence', fr: 'potence', de: 'inline', en: 'bracket' }) },
  blank: { look: 'box', width: em(3.2), color: col('rule'), weight: pt(0.8) },
  area: { kind: 'grid', spacing: mm(5), color: col('rule'), weight: pt(0.4) },
  answers: { color: col('accent'), fontFamily: LABEL }, // the teacher's copy, in the accent
  marginTop: mm(7), marginBottom: mm(2), itemSpacing: em(0.5),
};
// #endregion

// #region head: the unit pill, the title and the lines for a name and a date
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) => [

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

#Pon las soluciones boca abajo al pie

Una costumbre de los cuadernos de pasatiempos: la clave de cada ejercicio, girada 180° debajo de él.

-  exercises: { edition: 'student' }, // the switch above the pages sets 'teacher'
+  exercises: { edition: 'student', solutions: { placement: 'inverted', layout: 'key' } },

#Divide con la casita en todas las ediciones

Las escuelas japonesas y chinas también usan la casita ⟌; un idioma que no aparece en la lista toma la suya propia.

-    division: t({ es: 'potence', fr: 'potence', de: 'inline', en: 'bracket' }) },
+    division: 'bracket' },

Errores frecuentes

  • Las operaciones son de números enteros: una cuenta con decimales como 12,5 + 3,75 no se lee y se imprime tal cual. Deja los decimales en los huecos del cálculo mental, donde la respuesta es texto.

Créditos

Texto
Texto original, CC BY 4.0
Fuentes
Fira Sans (SIL OFL 1.1) · Lexend (SIL OFL 1.1)
SandboxPDF