Em poucas palavras
A página de passatempos de uma revista infantil sobre o mar. Cada passatempo fica no seu cartão, com as respostas impressas de cabeça para baixo embaixo, e o leitor vira a revista para conferir.
O que você vai compor
A página de passatempos da Splash!, uma revista infantil sobre o mar, em duas páginas de tamanho A4 com duas colunas. Uma pintura do recife preenche o alto da primeira página, com o título sobre a água aberta. Embaixo, cada passatempo fica num cartão creme com um número coral: palavras cruzadas montadas com seis animais marinhos e suas dicas, um caça-palavras que esconde oito palavras na horizontal, na vertical, na diagonal e de trás para a frente, uma adivinha com três opções para circular, a vida de uma tartaruga para pôr em ordem, uma frase embaralhada para desvendar e filhotes de animais para ligar ao nome. Embaixo de cada passatempo, dentro do cartão, as respostas vêm de cabeça para baixo em letra cinza pequena, do jeito que as revistas de passatempos sempre as esconderam.
Esta receita responde a
- Como faço um caça-palavras ou palavras cruzadas a partir de uma lista de palavras?
- Como imprimo as respostas de cabeça para baixo no pé de um exercício?
A resposta curta
// 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
- Funcionalidades
- Caça-palavras e palavras cruzadasGabaritoEstilos de exercícioExercíciosEscolha e verdadeiro ou falsoLigar e classificarOrdenarPerguntas abertas e áreas de escritaBoxesTrês ou mais colunasAberturas desenhadasAtributos de títuloImagens nos designs de páginaFiguras e tabelas como recursosPaleta de cores semânticaExportação para PDF
- Também usa
- Boxes que se dividem ou ficam inteirosEquilíbrio de colunasFiguras exatamente aquiFaixa de capítulo em largura totalCabeços por tipo de páginaEstilos de parágrafoFontes incorporadas ao PDFTipos de recurso personalizados
- Tipografia
- Baloo 2, Nunito, Fredoka (SIL OFL 1.1)
- Materiais
hatchling-600.jpgreef-1600x792.jpg- A coral reef with a smiling sea turtle, an octopus, a clownfish, a pufferfish and a seahorse under sunbeams. (Generated With Diffusion Models, original)
- A baby sea turtle hatching from its egg on the sand. (Generated With Diffusion Models, original)
Preparo
#1 · Cada passatempo num cartão, com as respostas viradas
O código é a resposta curta logo acima. O box do estilo de exercício nomeia um estilo de boxe, então cada passatempo vai num cartão, com o número num círculo e o título como primeira linha do enunciado. placement: 'inverted' põe as respostas depois de cada passatempo num boxe girado 180°, dentro do cartão, então passatempo e respostas nunca caem em páginas diferentes; as grades e a linha de escrita ficam dentro do espaçamento interno do cartão.
#2 · Deixe o motor montar as grades
O Markdown traz só as palavras: - OCTOPUS: Eight arms and three hearts para as palavras cruzadas, - SHELL para o caça-palavras. O motor monta as palavras cruzadas com cada palavra cruzando outra e numera os inícios na ordem de leitura. No caça-palavras, esconde as palavras nas direções que a diretiva indica (directions="across down diagonal backwards") e preenche o resto com letras das mesmas palavras. As duas grades usam uma semente fixa, então saem iguais em cada composição e em cada saída, e a edição espanhola monta a sua grade com as suas próprias palavras.
#3 · Um recife na largura das duas colunas
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) } } },
] } };
A abertura ocupa as duas colunas (span: 'page'), então os passatempos começam embaixo da pintura em cada coluna. A imagem é recortada na proporção da faixa e ancorada à página, de modo que sangra no alto e nas laterais; a linha fina fica numa caixa escura para ser lida sobre a água.
A receita 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 = 'en'; // @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),
};
O script.js montado funciona como está: cole-o como script de módulo em qualquer página ou abra a receita no CodePen. Pasta da receita no GitHub ↗ (abre em uma nova aba)
Variações
#Esconda a lista de palavras
Um caça-palavras mais difícil imprime só a grade: acrescente hidden à diretiva.
-:::exercise{type=wordsearch size=9 directions="across down diagonal backwards"}
+:::exercise{type=wordsearch size=9 directions="across down diagonal backwards" hidden}#Imprima as respostas no fim da revista
chapterEnd reúne todas as respostas no fim em vez de virar cada uma.
- solutions: { placement: 'inverted', box: 'turned' },
+ solutions: { placement: 'chapterEnd' },Erros comuns
- Uma palavra das palavras cruzadas que não cruza com nenhuma outra fica de fora e gera o aviso
exerciseWordUnplaced. Escolha palavras que tenham letras em comum ou acrescente uma que ligue dois grupos. - O cartão de um passatempo fica inteiro, então palavras cruzadas altas passam para a coluna seguinte quando não cabem: confira a edição espanhola, de palavras mais longas.
Créditos
- Receita
- Ignacio Ferro
- Texto
- Texto original, CC BY 4.0
- Imagens
- A coral reef with a smiling sea turtle, an octopus, a clownfish, a pufferfish and a seahorse under sunbeams. · Generated With Diffusion Models · original
- A baby sea turtle hatching from its egg on the sand. · Generated With Diffusion Models · original
- Fontes
- Baloo 2 (SIL OFL 1.1) · Nunito (SIL OFL 1.1) · Fredoka (SIL OFL 1.1)
- Código
- MIT, como o Postext
Editar este texto ↗ (abre em uma nova aba)Pasta da receita no GitHub ↗ (abre em uma nova aba)


