UI Test Article

One article that exercises every note component, used to check typography, spacing, math, code and plots in light, dark and mobile layouts.

This opening paragraph mixes bold, italic, underline, strikethrough, inline code, a link-free sentence and inline math such as eiπ+1=0e^{i\pi} + 1 = 0. It also cites a source [1] and a second one [2], and runs long enough to wrap across several lines so the line height and measure can be judged.

Text hierarchy

A second-level section starts with a heading and an accent bar. Paragraphs under it should feel comfortable, with a clear gap between blocks and a stronger gap before each new section.

A third-level heading

Third-level headings sit closer to their text than second-level ones, and they should read as a clear step down in importance.

  • A short bullet.
  • A longer bullet that wraps onto a second line so the hanging indent and the gap between items can be checked at every viewport width.
  • A bullet with inline math ∑k=1nk=n(n+1)2\sum_{k=1}^{n} k = \tfrac{n(n+1)}{2} and code.

Long-form reading

Real articles are read for minutes at a time, so the page has to hold up over many paragraphs, not just a few lines. The measure, meaning the number of characters per line, should stay comfortable on a wide monitor, the leading should keep the eye from slipping to the wrong line, and the gap between paragraphs should be big enough to show where a thought ends without turning the page into a stack of disconnected blocks.

Why the measure matters

A line that is too long forces the reader's eye to travel a long way back to the start of the next line, and it is easy to lose the place or re-read the same line. A line that is too short breaks the sentence into fragments and makes the eye jump constantly. Somewhere between sixty and eighty characters is the usual advice, and a layout that fills about three quarters of a wide screen with body text at seventeen pixels lands close to the upper end of that range. That is a deliberate trade: the page keeps the generous whitespace of a narrow column while leaving room for wide figures, plots and tables to breathe.

Consider how a serial manipulator is described in a textbook. The authors introduce the joint variables, then the link parameters, then the forward kinematic map that composes one homogeneous transform per joint. Each step is a paragraph or two of prose, followed by an equation, followed by a worked example. The prose carries the intuition, the equation carries the precision, and the example ties the two together. If the typography fights any of those three, the reader stops trusting the page and starts skimming.

Paragraphs that build on each other

Good technical writing rarely stops at a single idea. It states a claim, explains why the claim is plausible, shows where it breaks, and then refines it. The Jacobian is a good example. At first it is just a matrix of partial derivatives that maps joint velocities to end-effector velocities. A little later it becomes a tool for detecting singularities, because the determinant of the square case vanishes exactly where the arm loses the ability to move in some direction. Later still it becomes the backbone of resolved-rate control, where the pseudo-inverse turns a desired Cartesian velocity into joint commands that minimise the norm of the joint motion.

None of those steps is hard on its own. The difficulty is keeping the whole chain in mind while reading, which is why the visual hierarchy matters: the second-level headings mark the large moves in the argument, the third-level headings mark the sub-arguments, and the body text between them should look the same everywhere so that the eye can settle into a rhythm and stop thinking about the typography at all.

Lists inside long text

When an argument has parallel parts, a list reads faster than a sentence with several commas and an and near the end. The properties we want from the reading experience are:

  • A stable measure, so line length never surprises the reader on a very wide or very narrow window.
  • A consistent vertical rhythm, with the same gap between every pair of paragraphs and a larger gap before each new section.
  • Clear heading levels, so the structure of the article is visible at a glance and in the table of contents.
  • Equations, code and figures that sit in the flow of the text without shouting over it, each with the same caption style and the same spacing above and below.
  • Colours that keep enough contrast in both light and dark mode, including for secondary text such as captions, dates and footnote markers.

Each of those items is easy to get roughly right and hard to get exactly right, and the differences only show up once the page is long enough to scroll for a while. That is the reason this test article has so much text in it: a short sample hides the problems that a real article exposes.

Reading on different screens

On a phone the same article is read in a single narrow column with small side gutters, in short sessions, often one-handed, often while moving. Wide equations and plots must scroll or shrink rather than push the page sideways. Tap targets such as bookmark and share must stay large enough to hit reliably, and nothing may sit on top of the text while the reader scrolls.

On a desktop monitor the article is read in a single sitting, usually with other windows nearby. The page can afford more whitespace, a sticky table of contents, and a small panel of reader actions that stays within reach without covering the text. Keeping that panel docked in the header at the top of the page and letting it float only once the header scrolls away keeps the first screen clean, while still keeping the actions available for the rest of the article.

Mathematics

Inline math should sit on the baseline of the sentence: the quadratic formula is x=−b±b2−4ac2ax = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}, and the Gaussian integral is ∫−∞∞e−x2,dx=π\int_{-\infty}^{\infty} e^{-x^2},dx = \sqrt{\pi}.

A short display equation:

v=J(q) q˙\mathbf{v} = J(\mathbf{q})\,\dot{\mathbf{q}}

A wide display equation that must scroll rather than overflow the page on a phone:

J(q)=[−l1s1−l2s12−l3s123−l2s12−l3s123−l3s123l1c1+l2c12+l3c123l2c12+l3c123l3c123111]J(\mathbf{q}) = \begin{bmatrix} -l_1 s_1 - l_2 s_{12} - l_3 s_{123} & -l_2 s_{12} - l_3 s_{123} & -l_3 s_{123} \\ l_1 c_1 + l_2 c_{12} + l_3 c_{123} & l_2 c_{12} + l_3 c_{123} & l_3 c_{123} \\ 1 & 1 & 1 \end{bmatrix}

An aligned derivation:

f(x)=(x+1)2=x2+2x+1f′(x)=2x+2\begin{aligned} f(x) &= (x+1)^2 \\ &= x^2 + 2x + 1 \\ f'(x) &= 2x + 2 \end{aligned}

Tables

Jointθ (variable)da (link length)α
1θ₁0l₁0
2θ₂0l₂0
Denavit–Hartenberg parameters for a 2-DOF planar arm

Diagrams and frames

l₁ l₂ θ₁ θ₂ p
2-DOF planar arm — joint angles θ₁, θ₂ measured from the previous link
T₀²
⎡

⎣
0.8253-0.564601.7464
0.56460.825300.9541
0010
0001
⎤

⎦

End-effector frame at θ₁ = 0.4 rad, θ₂ = 0.2 rad

Images

Heron of Alexandria

Code

import numpy as np

def jacobian(q: np.ndarray, l: np.ndarray) -> np.ndarray:
    """Geometric Jacobian for an n-DOF planar revolute arm."""
    n = len(q)
    J = np.zeros((3, n))
    cum = np.cumsum(q)
    for i in range(n):
        suffix_cos = sum(l[j] * np.cos(cum[j]) for j in range(i, n))
        suffix_sin = sum(l[j] * np.sin(cum[j]) for j in range(i, n))
        J[0, i] = -suffix_sin
        J[1, i] = suffix_cos
        J[2, i] = 1.0
    return J
Resolved-Rate Motion Control (Jacobian pseudo-inverse)
  1. 1Input: goal pose p_goal, current config q, damping λ
  2. 2repeat
  3. 3p ← forward_kinematics(q)
  4. 4e ← p_goal − p // task-space error
  5. 5J ← jacobian(q)
  6. 6J† ← Jᵀ · inv(J·Jᵀ + λ²·I) // damped pseudo-inverse
  7. 7q̇ ← J† · Kp · e // resolved-rate law
  8. 8q ← q + q̇ · Δt
  9. 9until ‖e‖ < ε

Plots

References

The footnotes below are linked from the opening paragraph.

References

  1. [1]Spong, M. W., Hutchinson, S., & Vidyasagar, M. Robot Modeling and Control. 2006.
  2. [2]Siciliano, B. et al. Robotics: Modelling, Planning and Control. 2009.