Prohlížeč zdrojového kódu
docs/specs/example-content.md
80# Spec: Rich Example Content
- Status: draft
- Created: 2026-03-12
- Related code:
app/examples/,app/services/example_entry.rb,app/views/examples/show.html.erb
Overview
Each example has a rich content file (example.md) that defines the detail page layout. The Markdown file is the single source of truth for how the example's detail page is structured — authors write free-form Czech prose and embed the source code and scenario forms at the desired positions using placeholder tags. This lets each example tell its own story with the code and interactive elements woven in naturally.
Behaviour
Content file
- Every example directory must include an
example.mdfile. example.mddrives the detail page layout entirely on the detail page.- The
descriptionfield inexample.ymlremains — it is used on the index page (example cards) but not on the detail page. ExampleEntryexposes the raw Markdown content (read from disk on each request, same pattern as source code).
Placeholder tags
The Markdown content supports these placeholder tags, written on their own line:
<!-- source -->— replaced with the syntax-highlighted source code block. Raises an error if the example has nosource_file.<!-- scenario:INDEX -->— replaced with the scenario form and result frame for the scenario at position INDEX (0-based), e.g.<!-- scenario:0 -->.<!-- scenarios -->— replaced with all scenario forms in order (equivalent to listing each one individually). Cannot be combined with individual<!-- scenario:N -->tags in the same file.
Rendering
- The Markdown is rendered to HTML using the existing Redcarpet pipeline.
- After Markdown rendering, placeholder tags (which survive as HTML comments) are replaced with the corresponding rendered partials.
- If a placeholder references a scenario index that doesn't exist, it is silently removed.
- The title and tags are still rendered from
example.ymlabove the content, same as today. - Code blocks in example content (both fenced Markdown blocks and the
<!-- source -->placeholder) are vertically constrained to 80% of the viewport height. When content exceeds this height, the block scrolls vertically. This prevents tall code blocks from dominating the page layout. - Two consecutive fenced code blocks separated by a
<!-- compare -->or<!-- compare:LabelA:LabelB -->tag are rendered side by side in a 50/50 split. When labels are provided (colon-delimited), each pane displays its label above the block. Both panes' scroll positions are linked — scrolling either pane horizontally or vertically moves the other to match.
Migration
- All existing examples get an
example.mdfile reproducing the current detail page layout (description text, then source placeholder, then scenarios placeholder).
Implementation Notes
ExampleEntry#content_markdownreadsexample.mdfrom@base_pathon each request (same pattern assource_code).HighlightHelper#render_example_contentrenders the Markdown viarender_markdown, then replaces placeholder HTML comments viagsubwith rendered partials and highlighted code. The result is wrapped inrawto mark it as HTML-safe for output. The<!-- source -->gsub raisesArgumentErrorwhenexample.source_codeisnil.HighlightHelper#render_scenario_blockrenders theexamples/scenario_blockpartial for each scenario._scenario_block.html.erbwas extracted from the oldshow.html.erb— wraps scenario name, description, form, and Turbo Frame result tag.show.html.erbwrapsrender_example_content(@example)in<div class="example-content">— this scopes code block height limiting to example pages only, leaving the source browser unaffected.compare_scroll_controller.js(Stimulus) — on connect, collects bothpreelements within the.code-comparewrapper and syncsscrollTop/scrollLefton each scroll event. Auto-registered viaeagerLoadControllersFrom._code.scss—.code-compareis a flex container withgap: 1rem; each.code-compare__paneisflex: 1; min-width: 0(prevents flex blowout on wide code);.code-compare__labelis small muted text. The<!-- compare -->post-processing is agsubstep insiderender_example_content._code.scssscopes the height constraint to.example-content .code-block: the outer.code-blockis set tooverflow: hidden(overriding its baseoverflow-x: auto) and the innerprebecomes the 2D scroll container (max-height: 80vh; overflow: auto). This ensures both horizontal and vertical scrollbars are simultaneously visible at the edges of thepreelement, rather than the horizontal bar being hidden below the vertical overflow clip.
Tests
spec/services/example_entry_spec.rb—content_markdownreads from diskspec/helpers/highlight_helper_spec.rb— Markdown rendering, source placeholder replacement, invalid scenario index removal, compare block rendering (unlabelled and labelled)spec/requests/examples_spec.rb— integration: detail page renders syntax-highlighted code and scenario forms
See Also
- Examples System — defines example metadata, registry, and the current detail page layout that this spec replaces.
- Examples Runner — scenario forms and execution, embedded via placeholder tags.
- Markdown Code Block Syntax Highlighting — fenced code blocks in
example.mdfiles are highlighted via the Markdown renderer.
Change Log
- 2026-03-12: Initial prospective spec.
- 2026-03-17: Added behaviour: code blocks in example content are height-limited to 80vh with vertical scroll.
- 2026-03-17: Added side-by-side code comparison via
<!-- compare -->tag with linked scrolling. - 2026-03-23:
<!-- source -->silently removed when example has nosource_file.