Line numbers and linkable lines
Every processed code block gets a line-number gutter and a stable id, GitHub style. Try it on the block below:
- click a line number to select that line,
- shift-click (or drag along the gutter) to select a range,
- click the link button (top right of the block) to copy the link — to the current line selection if you have one in that block, else to the whole block; the icon flashes a checkmark to confirm,
- click the copy button next to it to copy the code — likewise just the selected lines if you have a selection in that block, else the whole block,
- click anywhere outside the block to deselect.
The selection is reflected in the URL fragment (#c-1a2b3c4d-L3-L7), so a copied link takes a reader to exactly these lines. The link button is a real anchor, so the browser's usual affordances (right-click → Copy Link, middle-click → new tab) work too. Block ids are content-addressed: they only change when the code itself changes, not when the block moves around on the page.
struct Point{T <: Real} x::T y::Tendnorm2(p::Point) = p.x^2 + p.y^2function closest(points::AbstractVector{<:Point}, target::Point) _, i = findmin(p -> norm2(Point(p.x - target.x, p.y - target.y)), points) return points[i]endLine numbers live in the gutter's CSS, not in the text — selecting and copying code never picks up the digits, and horizontal scrolling keeps the gutter pinned.
REPL transcripts
Transcripts are numbered too (all lines count, including output), which makes REPL sessions linkable line by line:
julia> p = Point(3.0, 4.0)Point{Float64}(3.0, 4.0)julia> norm2(p)25.0Continued numbering
By default every block numbers from 1. A page can instead carry one running line counter across its code blocks — tutorial style — by placing an @codeblocks options block:
```@codeblocks
line_counter = :continue
```Like @meta, the setting applies from its position to the end of the page, or until another @codeblocks block flips it back to :restart (the default). All processed blocks participate — julia, julia-repl, and executed @repl blocks — and line permalinks use the displayed numbers, so a copied #…-L12 link keeps meaning the line the reader saw. The two blocks below share one counter:
grid = [Point(float(i), float(j)) for i in 1:3, j in 1:3]origin = Point(0.0, 0.0)nearest = closest(vec(grid), origin)r2 = norm2(nearest)A third mode, line_counter = :named, keeps one counter per named series: blocks that share a name — @example tutorial, @repl tutorial, jldoctest tutorial, or a plain fence with a second token like $```julia tutorial$ — continue each other (across block kinds and across unrelated blocks in between), while unnamed blocks restart. This pairs naturally with Documenter's named @example/@repl sandboxes, where same-named blocks already share one session:
total = 1 + 2An unnamed block between the two restarts at 1, but the series picks up where it left off:
total += 3Blocks inside docstrings are their own page: they always start at 1 and never advance any counter.
Configuration
All knobs are keyword arguments of CodeBlocks:
line_numbers = falsedisables the gutter (blocks are still highlighted and linked, and keep their id + permalink),repl_line_numbers = falsedisables the gutter forjulia-replblocks only,line_countersets the site-wide default line-counter mode (:restart,:continue, or:named) —@codeblocksblocks override it per page, positionally,min_linessets the minimum block length that gets a gutter — the default1numbers everything, including one-liners:
answer = add_numbers(40, 2)The signature header of a rendered docstring is deliberately not numbered — it is a header, not example code (its argument and return types do get reference links, though — see Reference links).