Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 39 additions & 39 deletions Examples/Document Configuration/report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ _style:
Customizing your document configuration and styling:
- >
There are `three` categories of document configuration
- 1: The document template
2: Text styles
3: Table styles

- _ol:
- The document template
- Text styles
- Table styles

- >
These three categories are set at three different levels of priority
- 1: The internal defaults (lowest priority)
2: Project config
3: Document internal config (highest priority)
- _ol:
- The internal defaults (lowest priority)
- Project config
- Document internal config (highest priority)

- >
Each level of priority in the configuration heirarchy effectively inherits the configuration of the level of priority above it.
Expand All @@ -27,10 +29,11 @@ Customizing your document configuration and styling:
- The document template (_doc):
- >
The template controls settings such as
- - Page size
- Margins
- PDF background file path
- And whether or not you have a separate set of the above settings applying to the first page of your document or not.
- _ul:
- Page size
- Margins
- PDF background file path
- And whether or not you have a separate set of the above settings applying to the first page of your document or not.

- >
Currently, the document template is internally configured to only use a single content frame. This limitation would only affect you if you wanted to do something like a two-column layout (where text flows into the second column on the same page once the first one is full).
Expand All @@ -39,39 +42,36 @@ Customizing your document configuration and styling:
- >
With text styles, you can control the body text
- Text styling attributes:
- Font family
- Text color
- Size
- Line spacing ratio
- Bullet style:
- Bullet color
- Bullet symbol heirarchy
- Bullet indentation

_ul:
- Font family
- Text color
- Size
- Line spacing ratio
- "Bullet style:"
- - Bullet color
- Bullet symbol heirarchy
- Bullet indentation

- >
You can also control the text heading styles separately from the body text by adjusting their

- - Font family
- Text color
- Typographic ratio (in musical intervals, e.g. "minor second" or "major third")

- _ul:
- Font family
- Text color
- Typographic ratio (in musical intervals, e.g. "minor second" or "major third")
- Table styles (_tablestyle):
- >
You can control how your tables are displayed by modifying the table style. With the _tablestyle key, you can control
- Table header
- background (color)
- gridlines (above, below, between)
- text
- font
- size
- color
- Table rows
- even (rows, background color)
- odd (rows, background color)
- gridlines (above, below, between)
- text
- font
- size
- color
- _ul:
- "Table header:"
- - background (color)
- gridlines (above, below, between)
- "text: font, size, color"
- "Table rows:"
- - even (rows, background color)
- odd (rows, background color)
- gridlines (above, below, between)
- "text: font, size, color"



Expand Down
15 changes: 7 additions & 8 deletions Examples/Document variables/report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@ Document Variables (_vars):
representation is shown (i.e. the result of str(var)).

This document has five variables defined, a, b, c, d, e.
- _spacer: 0 # The use of a "0-spacer" is a hack to prevent the paragraph above being interpreted as a bullet point.

- - a = {{a}}
- b = {{b}}
- c = {{c}}
- d = {{d}}
- e = {{e.key2}}
- f = {{f}}
- _ul:
- a = {{a}}
- b = {{b}}
- c = {{c}}
- d = {{d}}
- e = {{e.key2}}
- f = {{f}}
- Passing Python Objects: >
It is also possible to pass variable data as Python objects to blocks (see "YMPrint blocks") using the $var syntax (similar to bash).

Expand Down
5 changes: 3 additions & 2 deletions Examples/PDF Backgrounds/report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Custom styling with PDF backgrounds:
Form fields are _automatically_ populated when a document variable name exactly matches the PDF form field name.

If you want to avoid this behaviour:
- Make sure that none of your variable names match your field names (i.e. using a special naming convention for your form field names to prevent accidental clashes)
- Do not use form fields
_ul:
- Make sure that none of your variable names match your field names (i.e. using a special naming convention for your form field names to prevent accidental clashes)
- Do not use form fields
Example: The form fields below have been populated from the document vars
25 changes: 13 additions & 12 deletions Examples/Simple example/report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@ Report title:

- Standard content types:
- Bullets:
- Bullet 1
- Bullet 2
- Bullet 3
- - Bullet 4
- Bullet 5
- Bullet 6
_ul:
- Bullet 1
- Bullet 2
- Bullet 3
- - Bullet 4
- Bullet 5
- Bullet 6
- Ordered list:
1: First Item
2: Second item
3:
12: Fourth item,
6: Fifth item,
10: Sixth Item
_ol:
- First item
- Second item
- - Nested first
- Nested second
- Nested third
- Tables:
- Item Number: 12.01
Description: There is a problem here. This report documents it.
Expand Down
26 changes: 13 additions & 13 deletions Examples/YMPrint blocks/report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ Using Blocks:
scale_ratio: 0.3
- Admonitions:
- "The following admonitions blocks are available:"
-
- _info
- _warning
- _danger
- _tip
- _note
- _ul:
- _info
- _warning
- _danger
- _tip
- _note
- They are rendered below

_info: Here is an "info" admonition
Expand Down Expand Up @@ -108,10 +108,10 @@ Using Blocks:
for k in [a, b, c]:
acc.append(k)
- "Now, the values of the variables a, b, and c can be included in the document:"
-
- a = {{py1.a}} (using py1.a)
- b = {{py1.b}} (using py1.b)
- c = {{py1.c}} (using py1.c)
- _ul:
- a = {{py1.a}} (using py1.a)
- b = {{py1.b}} (using py1.b)
- c = {{py1.c}} (using py1.c)
- _code:
source: |
yaml_data: is being shown
Expand All @@ -132,6 +132,6 @@ Using Blocks:
path: extra_vars.json
namespace: extra_vars
- "Here are the values of the vars contained within the 'extravars' namespace:"
-
- bn = {{extra_vars.bn}}
- dx = {{extra_vars.dx}}
- _ul:
- bn = {{extra_vars.bn}}
- dx = {{extra_vars.dx}}
100 changes: 100 additions & 0 deletions design/explicit-list-syntax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Design: Explicit list syntax (`_ul` / `_ol`)

Status: prototype
Branch: `features/explicit-list-syntax` (off `main`)

## Problem

A YAML list under a heading is structurally identical whether the author means
"several paragraphs" or "an unordered list". Today YMPrint guesses from the list's
*contents*:

- a **pure** list of strings → `convert_ul` → bullets
- a **mixed** list (strings + block/subsection dicts) → each string becomes a
paragraph

So the same `heading:\n - >prose` renders as a bullet or a paragraph depending on
what else is in the list. A single wrapped paragraph under a heading silently comes
out as a one-item bullet list (observed under "Alignment and named styles" in the
text-styles example).

The ambiguity is **structural** — YAML gives identical structure to both intents —
so no heuristic can resolve it. One of the two meanings must be made explicit.

## Decision

Make **bullets explicit** and let a bare list mean "a sequence of content items".

- A YAML list is always a *sequence of blocks*: strings become paragraphs, mappings
become subsections (heading + content), in order. It is never auto-bulleted.
- Unordered lists are written with the **`_ul`** block; ordered lists with **`_ol`**.
- The implicit detections (`check_for_nested_lists` → bullets, and the
dict-with-integer-keys → numbered list) are retired from dispatch. The check
functions remain (still unit-tested) but no longer drive `build_story`.

This yields a single rule with no guessing: *a list is content in order; bullets and
numbers are named constructs.*

### Rejected alternative

Making **paragraphs** explicit (`_p`) instead would avoid breaking existing bullet
lists, but it keeps the surprising default (bare list = bullets) and only adds an
escape hatch beside the ambiguity rather than removing it.

## Syntax

```yaml
Findings:
- The inspection covered three areas. # paragraph
- _ul: # unordered list
- The handrail is loose on the north stair.
- Two ceiling tiles are water-stained.
- - a nested sub-point # nested list → sub-bullets
- another sub-point
- Recommended actions: # subsection heading
_ol: # ordered list
- Re-secure the handrail.
- Replace the stained tiles.
```

- `_ul` value is a list; nested lists produce sub-bullets (unchanged `convert_ul`).
- `_ol` value is a list; numbering is automatic by position; nested lists produce
nested numbering. (`convert_ol` also still accepts a mapping for back-compat.)
- Both may be written as a list item (`- _ul: [...]`) or as the value of a heading
key (`heading:\n _ul: [...]`). Suffixes are allowed for uniqueness in a mapping
(`_ul_left`, `_ol_steps`), consistent with other block codes.

## Implementation

`_ul` / `_ol` are intercepted **directly in `build_story`**, not registered in the
block registry. Two reasons:

1. They are structural (they change how a list is interpreted), sitting naturally
beside the list-dispatch logic.
2. It keeps them **forward-compatible with scoped text styles**: `build_story` is
where a `current_style` parameter lives (on the `features/scoped-text-styles`
branch), so intercepting here lets `_ul`/`_ol` pass the active style into
`convert_ul`/`convert_ol`. Routing them through the generic block registry —
whose converters do not receive the active style — would make bullets ignore the
surrounding `_textstyle` scope. (On this `main`-based branch there is no
`current_style` yet; the interception point is chosen so the two features compose
cleanly when merged.)

| File | Change |
| --- | --- |
| `story_builder.py` | Intercept `_ul`/`_ol` (list-item and heading-value forms, with suffixes) → `convert_ul`/`convert_ol`. Replace the implicit bullet/ordered dispatch: a bare list/mapping now always recurses (strings → paragraphs, mappings → subsections). |
| `content_converters.py` | `convert_ol` accepts a **list** (positional numbering; nested lists nest) as well as a mapping (back-compat). |
| test data / examples | Migrate bare-list bullets and integer-keyed ordered lists to `_ul` / `_ol`. Genuine multi-paragraph lists (e.g. report 2 "third topic") are left as lists and now render as paragraphs — the intended fix. |

## Backward compatibility

This is a **breaking** content change (consistent with the pre-1.0 status and the
earlier multi-page-template change): existing documents that relied on bare lists for
bullets, or integer-keyed mappings for numbered lists, must adopt `_ul` / `_ol`.

## Open questions

- Should `_ol` support an explicit `start:` offset or custom markers (a/i/…)?
- Should list items be allowed to contain blocks (e.g. an image inside a bullet)?
- When merged with scoped text styles, thread `current_style` into the `_ul`/`_ol`
interception so bullets honour the active family.
Loading
Loading