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
// 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
- Funciones
- Sopas de letras y crucigramasSolucionesEstilos de ejercicioEjerciciosElección y verdadero o falsoUnir y clasificarOrdenarPreguntas abiertas y zonas de escrituraRecuadrosTres o más columnasAperturas diseñadasAtributos de títuloImágenes en los diseños de páginaFiguras y tablas como recursosPaleta de color semánticaExportación a PDF
- También usa
- Recuadros que se parten o noEquilibrado de columnasFiguras justo aquíBanda de capítulo a todo el anchoCabeceras según el tipo de páginaEstilos de párrafoFuentes incrustadas en el PDFTipos de recurso propios
- Tipografía
- Baloo 2, Nunito, Fredoka (SIL OFL 1.1)
- Recursos
hatchling-600.jpgreef-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
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
// ═══ 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
- Receta
- Ignacio Ferro
- 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)
- Código
- MIT, como Postext
Editar este texto ↗ (se abre en una nueva pestaña)Carpeta de la receta en GitHub ↗ (se abre en una nueva pestaña)


