This document is consumed by the /lx-llm-job-tick subagent whenever a
job's prompt references "editorial guidelines" (e.g. "rewrite following
editorial guidelines", "apply editorial guidelines", "clean up per the
guidelines"). The subagent must enforce every rule below before
writing the new revision.
These guidelines are about structure and notation, not voice or content — the subagent should not rewrite the author's ideas, only normalize the form so the article looks idiomatic on the LX renderer.
Every article body must be broken into sections under clear headers.
- The first text block of the article may be an intro paragraph (no preceding header).
- Every subsequent logical section gets a heading.
- Long sections may be subdivided with sub-headings.
A header MUST be a heading node. Nothing else is a header.
Bold text is not a header. Italic text is not a header. Underlined
text is not a header. A short paragraph in capitals is not a header.
A paragraph followed by an empty paragraph is not a header. The only
thing that is a header is a heading node with tag: "h2" / "h3"
/ etc.
This rule is non-negotiable: when you encounter prose that looks
header-shaped (a short stand-alone line introducing the section
below it, especially one rendered bold/italic/underlined or in
ALL CAPS), convert it into a heading node and strip the
formatting. Do not preserve the bold/italic/underline — the
heading node IS the styling.
- Heading children must be plain
textnodes withformat: 0. No bold (1), no italic (2), no underline (8), no strikethrough (4), no combinations thereof. The renderer styles headings already; manual formatting fights the stylesheet and produces double-emphasis. - Do NOT promote a regular paragraph with bold/italic/underline
text to a "fake header" by leaving it as a paragraph. Convert
it to a real
headingnode and drop the formatting flags. - Conversely, do NOT use a
headingnode for emphasis inside body text. Headers are for section boundaries only. - Pick a single top level for body headings (
h2is the conventional start —h1is reserved for the article title) and nest consistently (h2→h3→h4, never skipping). - No trailing colons, no leading numbering ("1. Introduction"). The renderer can number sections later if needed.
Use list + listitem nodes. Never simulate lists with text.
- Anti-pattern: a paragraph whose text starts with
"• ","- ","* ","1. "— that's a manual bullet. Convert to a reallist. - Anti-pattern: consecutive paragraphs separated by empty paragraphs
to fake spacing between list items. Remove the empty paragraphs and
use a proper
list. listType: "bullet"for unordered,"number"for ordered.- A single
listitemmay contain inlinetext,math, andlinknodes — but block content (paragraphs, headings) does not belong inside alistitem.
All mathematical notation must live in math nodes. No math as plain
text.
- Anti-pattern: a paragraph text node containing
"x^2 + y^2 = z^2". Convert to an inlinemathnode withlatex: "x^2 + y^2 = z^2". - Anti-pattern: a paragraph text node containing
"alpha","≈","π","≥". Replace with inline math (\alpha,\approx,\pi,\geq) when the surrounding context is mathematical. - Inline math uses
inline: true; display math usesinline: false. - Multi-line equations and aligned blocks should be display math
(
inline: false), each its ownmathnode.
Only display formulas may carry a number, and the number must live
inside the LaTeX via \tag{N}. No plain-text numbering anywhere.
- Correct (display):
\tag{1} E = mc^2orE = mc^2 \tag{1}. - Correct (display, no number): just the equation, no
\tag. - Anti-pattern: an inline math node followed by a paragraph text
"(1)". Remove the(1)paragraph; if a number is needed, move it into the math node's LaTeX as\tag{1}and promote the math to display. - Anti-pattern: a
\tag{}on an inline equation. Inline math is never numbered.
Every link node must have a real, working-looking URL.
- Anti-pattern:
url: "",url: "#",url: "TBD",url: "todo". Either supply a correct URL or unwrap the link (replace thelinknode with its children). - Anti-pattern: markdown link syntax leaking into text nodes —
[text](http://...)appearing inside a paragraph's text. Convert to a properlinknode. - Anti-pattern: legacy
/vis_resource.php?...URLs that have lost theirid=parameter, or any URL that's visibly malformed (http:/example, missing scheme, embedded whitespace). - Do NOT invent URLs the author didn't supply. If a link looks broken and you cannot recover the intended target, unwrap it and leave a plain text reference.
Strip migration and encoding artifacts.
- HTML entities in text nodes:
&,<,>, ,"— replace with the decoded character (&,<,>,,"). - Mojibake:
è→è,é→é,’→',“/â€→"/". Watch for anyÃorâ€sequence in Italian text. - Unicode replacement character
�(U+FFFD): this is a hard decode failure — bytes that couldn't be mapped to a real character. Never leave it in published text. If you can infer the intended character from context (typically an accented letter in Italian —è,é,à,ò,ù,ì, or a typographic quote'/"), restore it. If the original character cannot be recovered, delete the�rather than keeping a broken glyph. - Migration sentinels:
__EYCENTER__::is a centered-block marker that should have been consumed during conversion; if it survives into the published JSON, strip the prefix and wrap the affected block appropriately. - Zero-width and exotic whitespace:
(zero-width space),(BOM), trailing\ron text node strings — all removed. - Stray markdown markers in plain text:
**bold**,_italic_,~~strike~~appearing literally. Apply viatext.formatflags (1 = bold, 2 = italic, 4 = strikethrough, OR-combined) and remove the markers.
Inside math nodes, physical units must be formatted as
\,\text{…} (thin space + non-italic text).
- Correct:
v = 5\,\text{m/s},F = 10\,\text{N},T = 273.15\,\text{K}. - Anti-pattern:
v = 5 m/sinside LaTeX — the unit renders in math italics and the spacing is wrong. - Anti-pattern: the unit pulled out of the math node as paragraph
text (
"v = 5"math node then" m/s"paragraph text). The unit belongs inside the same math node. - Compound units use
\text{...}once around the whole compound:\,\text{kg·m/s^2}or\,\text{N·m}— not nested\text{}blocks.
Source code, terminal commands, configuration snippets, and any other
verbatim machine-readable text must live in a code block node. Never
in a regular paragraph, never as a text node styled with a
fixed-width font, never as 4-space-indented prose.
- Use
ey-code(preferred — supports the line-numbers gutter) orcode(standard Lexical fallback). Both take alanguagefield andCodeHighlightNodechildren. - Always set
languagewhen the language is identifiable. Common values:"javascript","typescript","python","php","c","cpp","bash"(use for shell snippets, not"shell"),"sql","json","yaml","html","css","matlab","vhdl","verilog","java","kotlin","go","rust". Pick the closest match. - If the language is unknown or the content is genuinely plain text
(raw transcript, opaque hex dump), leave
languageas""rather than guessing — wrong-language highlighting is worse than none. - Anti-pattern: a
paragraphwhose text starts with```pythonand ends with```. Convert to a real code block; the fences must be stripped (the node IS the fence). - Anti-pattern: indented paragraphs (4-space indent) used as makeshift code blocks. Convert to a real code block.
- Anti-pattern: code split across multiple paragraphs (one paragraph per line). Merge into a single code block with proper newlines inside the highlight children.
- Inline code fragments (a single function name, variable, flag) stay
inline — use the
textnode'sformatflag16(= code) rather than wrapping a one-token line in a code block.
When applying these guidelines, walk the tree once and check each
block against rules 1–3, 7, and 9; then walk all math nodes for
rules 4, 5, 8; then walk all link nodes for rule 6. Preserve every
custom node (fidocad, ey-image, ey-blockquote, ey-youtube,
riquadro, etc.) byte-for-byte — these guidelines are about
prose/math/list/heading/code hygiene, not custom blocks.