Saltar al contenido principal
Receta número 174

Recetario · Capítulo 12 · Libros de texto

Una página de pasatiempos con las soluciones del revés

La página de pasatiempos de una revista infantil: crucigrama, sopa de letras, adivinanza, historia que ordenar y más, en tarjetas con las soluciones del revé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 × 280 mm
  • 2 columnas, medianil de 7 mm
  • Nunito 10,5/15
  • Baloo 2
  • Fredoka
  • 2 páginas
  • Nivel
  • Postext 1.59.0
  • Compuesto en 85 ms
  • 129 líneas de código

En pocas palabras

La página de pasatiempos de una revista infantil sobre el mar. Cada pasatiempo va en su tarjeta, con las soluciones impresas del revés debajo, para que los lectores giren la revista y las comprueben.

Lo que vas a componer

La página de pasatiempos de ¡Chapuzón!, una revista infantil sobre el mar, en dos páginas de tamaño A4 a dos columnas. Una pintura del arrecife llena la parte de arriba de la primera página, con el título sobre el agua despejada. Debajo, cada pasatiempo va en una tarjeta crema con su número en coral: un crucigrama hecho con seis animales marinos y sus pistas, una sopa de letras que esconde ocho palabras en horizontal, en vertical, en diagonal y del revés, una adivinanza con tres opciones que rodear, la vida de una tortuga que ordenar, un dato revuelto y crías de animales que unir con su nombre. Bajo cada pasatiempo, dentro de su tarjeta, las soluciones van del revés en letra gris pequeña, como las han escondido siempre las revistas de pasatiempos.

Esta receta responde a

  • ¿Cómo hago una sopa de letras o un crucigrama a partir de una lista de palabras?
  • ¿Cómo imprimo las soluciones boca abajo al pie de un ejercicio?

La respuesta corta

script.js · líneas 33–59en el código completo
// placement 'inverted' sets each puzzle's key after it in a box turned 180°, inside the
// puzzle's card, so a page break never parts a puzzle from its answers. The key is made
// from the puzzle: the crossword's words by number, the ringed option, the right order.
const puzzle = {
  id: 'puzzle',
  box: 'card', // the card each puzzle sits on (a calloutStyles id)
  number: { shape: 'disc', fontFamily: DISPLAY, background: col('coral') },
  instruction: { fontFamily: TEXT, bold: false },
  options: { marker: 'circle', labels: 'none' }, // a ring to colour in, no letters
  grid: { fontFamily: LABEL, rule: col('sea'), cell: em(1.45) },
  match: { color: col('sea') },
  area: { kind: 'lines', color: col('sea') },
  answers: { color: col('coral'), fontFamily: LABEL },
  solutions: { placement: 'inverted', box: 'turned' },
  marginTop: mm(0), marginBottom: mm(0),
};
const card = { id: 'card', title: '', background: col('card'), borderRadius: mm(4),
  padding: { top: mm(3.5), right: mm(4), bottom: mm(3), left: mm(4) },
  titleStyle: { fontFamily: DISPLAY, fontSize: pt(15), fontWeight: 700, color: col('ink') },
  body: { fontFamily: TEXT, fontSize: pt(10.5), lineHeight: pt(15), color: col('ink'),
    firstLineIndent: pt(0) },
  marginTop: mm(0), marginBottom: mm(5), keepTogether: true };
const turned = { id: 'turned', title: '', backgroundEnabled: false, border: { enabled: false },
  padding: { top: pt(0), right: pt(0), bottom: pt(0), left: pt(0) },
  body: { fontFamily: LABEL, fontSize: pt(8.5), lineHeight: pt(11), color: col('muted'),
    firstLineIndent: pt(0) },
  marginTop: mm(2), marginBottom: mm(0) };

Ingredientes

Tipografía
Baloo 2, Nunito, Fredoka (SIL OFL 1.1)
Recursos
  • hatchling-600.jpg
  • reef-1600x792.jpg
  • Un arrecife de coral con una tortuga marina sonriente, un pulpo, un pez payaso, un pez globo y un caballito de mar bajo los rayos del sol. (Generated With Diffusion Models, original)
  • Una cría de tortuga marina sale del huevo en la arena. (Generated With Diffusion Models, original)

Elaboración

#1 · Cada pasatiempo en su tarjeta, con las soluciones giradas

El código está en la respuesta corta. El box del estilo de ejercicio nombra un estilo de recuadro, así que cada pasatiempo va en una tarjeta, con su número en un círculo y su título como primera línea del enunciado. placement: 'inverted' pone las soluciones tras cada pasatiempo en un recuadro girado 180°, dentro de la tarjeta, así que nunca caen en páginas distintas; las cuadrículas y la línea de escritura quedan dentro del relleno de la tarjeta.

#2 · Deja que el motor construya las cuadrículas

El Markdown solo lleva las palabras: - PULPO: Ocho brazos y tres corazones para el crucigrama y - CONCHA para la sopa de letras. El motor coloca el crucigrama con cada palabra cruzada con otra y numera los comienzos en orden de lectura, y esconde las palabras de la sopa en las direcciones que pide la apertura (directions="across down diagonal backwards"), rellenando el resto con letras de las mismas palabras. Las dos usan una semilla, así que la cuadrícula es la misma en cada composición y en cada salida, y la edición inglesa construye la suya con sus propias palabras.

#3 · Un arrecife a lo ancho de las dos columnas

script.js · líneas 63–82en el código completo
const BAND = 104; // mm from the top edge: the painting's height at the page's width
const opener = { enabled: true, minHeight: mm(BAND - 16 + 6), slot: { elements: [
  { kind: 'image', id: 'reef', resourceId: 'reef', decorative: true, reserve: false,
    placement: { anchor: { to: 'page', edge: 'top-left' },
      size: { width: mm(210), height: mm(BAND) } } },
  { kind: 'text', id: 'kicker', content: '{attr.kicker}', fontFamily: LABEL, fontSize: pt(11),
    fontWeight: 600, color: col('paper'), textTransform: 'uppercase', letterSpacing: pt(2),
    box: { backgroundColor: col('coral'), borderRadius: mm(2),
      padding: { top: mm(0.8), bottom: mm(0.8), left: mm(2.4), right: mm(2.2) } },
    placement: { anchor: { to: 'page', edge: 'top-left' }, offset: { x: mm(16), y: mm(14) } } },
  { kind: 'text', id: 'title', content: '{titleText}', fontFamily: DISPLAY, fontSize: pt(56),
    fontWeight: 800, lineHeight: 1, color: col('paper'),
    placement: { anchor: { to: '#kicker', edge: 'below' }, offset: { x: mm(0), y: mm(3) } } },
  { kind: 'text', id: 'sub', content: '{attr.sub}', fontFamily: TEXT, fontSize: pt(12),
    fontWeight: 700, color: col('paper'), overflow: 'wrap', align: 'left',
    box: { backgroundColor: col('ink'), borderRadius: mm(2),
      padding: { top: mm(1.5), bottom: mm(1.5), left: mm(3), right: mm(3) } },
    placement: { anchor: { to: '#title', edge: 'below' }, offset: { x: mm(0), y: mm(2) },
      size: { width: mm(110) } } },
] } };

La apertura ocupa las dos columnas (span: 'page'), así que los pasatiempos empiezan bajo la pintura en cada columna. La imagen está recortada a la proporción de la franja y anclada a la página, de modo que sangra por arriba y por los lados; la entradilla va en una caja oscura para que se lea sobre el agua.

La receta completa

Sandbox
// ═══ Postext Cookbook · Nº 174 · A puzzle page with the answers upside down ═══════
// https://postext.dev/en/cookbook/puzzle-page-upside-down-answers
// Code: MIT · Text: original (CC BY 4.0) · Pictures: generated with diffusion models
// Fonts: Baloo 2, Nunito, Fredoka (SIL OFL 1.1) · Needs postext ≥ 1.59.0
import {
  buildDocumentWithFonts, renderPageToCanvas, registerResourceImage,
} from 'https://esm.sh/postext';
import { renderToPdf, decompressWoff2 } from 'https://esm.sh/postext-pdf';

const LANG = 'es'; // @lang: the language of the sample document ('en' | 'es')
const RECIPE = 'puzzle-page-upside-down-answers';

// ─── 1 · Design ─────────────────────────────────────────────────────────────
// #region palette: reef colours: deep blue ink, coral, sea green, a sandy paper
const palette = {
  ink: '#16324a', // text: a deep sea blue
  coral: '#e8573f', // the accent: puzzle numbers, the title kicker
  sea: '#0f8b8d', // the second: crossword and word-search rules, the riddle's rings
  sun: '#ffc93c', // the turtle card's badge
  card: '#fff4e0', // the puzzle cards
  muted: '#5d7180', // answers, colophon, folio
  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.coral, model: 'hex' } },
];
// #endregion
const [DISPLAY, TEXT, LABEL] = ['Baloo 2', 'Nunito', 'Fredoka'];

// #region answer: every puzzle on a card, its answers turned upside down under it
// placement 'inverted' sets each puzzle's key after it in a box turned 180°, inside the
// puzzle's card, so a page break never parts a puzzle from its answers. The key is made
// from the puzzle: the crossword's words by number, the ringed option, the right order.
const puzzle = {
  id: 'puzzle',
  box: 'card', // the card each puzzle sits on (a calloutStyles id)
  number: { shape: 'disc', fontFamily: DISPLAY, background: col('coral') },
  instruction: { fontFamily: TEXT, bold: false },
  options: { marker: 'circle', labels: 'none' }, // a ring to colour in, no letters
  grid: { fontFamily: LABEL, rule: col('sea'), cell: em(1.45) },
  match: { color: col('sea') },
  area: { kind: 'lines', color: col('sea') },
  answers: { color: col('coral'), fontFamily: LABEL },
  solutions: { placement: 'inverted', box: 'turned' },
  marginTop: mm(0), marginBottom: mm(0),
};

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

#Oculta la lista de palabras

Una sopa de letras más difícil imprime solo la cuadrícula: añade hidden a la apertura.

-:::exercise{type=wordsearch size=9 directions="across down diagonal backwards"}
+:::exercise{type=wordsearch size=9 directions="across down diagonal backwards" hidden}

#Imprime las soluciones al final de la revista

chapterEnd reúne todas las soluciones al final en vez de girar cada una.

-  solutions: { placement: 'inverted', box: 'turned' },
+  solutions: { placement: 'chapterEnd' },

Errores frecuentes

  • Una palabra del crucigrama que no se cruza con ninguna otra se queda fuera y se avisa con exerciseWordUnplaced. Elige palabras que compartan letras o añade una que una dos grupos.
  • Una tarjeta de pasatiempo se mantiene entera, así que un crucigrama alto pasa a la columna siguiente si no cabe: revisa la edición española, de palabras más largas.

Créditos

Texto
Texto original, CC BY 4.0
Imágenes
  • Un arrecife de coral con una tortuga marina sonriente, un pulpo, un pez payaso, un pez globo y un caballito de mar bajo los rayos del sol. · Generated With Diffusion Models · original
  • Una cría de tortuga marina sale del huevo en la arena. · Generated With Diffusion Models · original
Fuentes
Baloo 2 (SIL OFL 1.1) · Nunito (SIL OFL 1.1) · Fredoka (SIL OFL 1.1)
Sandbox