Code Blocks
2025, 15 DecCode is everywhere in technical writing. Here's how it looks when published with Draft42.
Basic Code Blocks
Drop in a code block with a language identifier and syntax highlighting just works:
pub struct TokenStream<'a> {
tokens: &'a [Token],
position: usize,
}
impl<'a> TokenStream<'a> {
pub fn peek(&self) -> Option<&Token> {
self.tokens.get(self.position)
}
pub fn advance(&mut self) -> Option<Token> {
let token = self.tokens.get(self.position).cloned();
self.position += 1;
token
}
}File Labels
You can label your code with the file attribute to add a filename in the header—useful when showing code from a specific file:
pub fn expect(&mut self, kind: TokenKind) -> Result<Token> {
match self.advance() {
Some(token) if token.kind == kind => Ok(token),
Some(token) => Err(ParseError::unexpected_token(token, kind)),
None => Err(ParseError::unexpected_eof()),
}
}Line Highlighting
You can highlight specific lines in the code to draw attention to specific areas. Here, lines 8-11 show the core loop logic:
pub fn separated_list<T>(
parser: &mut Parser,
separator: TokenKind,
element: impl Fn(&mut Parser) -> Result<T>,
) -> Result<Vec<T>> {
let mut items = vec![element(parser)?];
while parser.stream.peek().map(|t| t.kind) == Some(separator) {
parser.stream.advance();
items.push(element(parser)?);
}
Ok(items)
}Captions
The caption attribute adds a description below the code block:
impl Parser {
fn synchronize(&mut self) {
while let Some(token) = self.stream.peek() {
match token.kind {
TokenKind::Semicolon => {
self.stream.advance();
return;
}
TokenKind::Fn | TokenKind::Let => return,
_ => self.stream.advance(),
}
}
}
}Multiple Languages
Syntax highlighting works across languages:
async function fetchData(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
return response.json();
}def process_items(items):
return [
item.upper()
for item in items
if item.startswith('_')
]type user = {
id: int,
name: string,
email: option<string>,
}
let display = user =>
switch user.email {
| Some(email) => `${user.name} <${email}>`
| None => user.name
}interface User {
id: number;
name: string;
email?: string;
}
type Result<T> =
| { success: true; data: T }
| { success: false; error: string };Inline Code
Use backticks for inline code like TokenKind::LParen or Result<T> within text.
Combining Everything
All attributes work together. Here the highlighted lines show the expect calls that enforce the delimiters:
pub fn delimited<T>(
parser: &mut Parser,
open: TokenKind,
inner: impl Fn(&mut Parser) -> Result<T>,
close: TokenKind,
) -> Result<T> {
parser.stream.expect(open)?;
let result = inner(parser)?;
parser.stream.expect(close)?;
Ok(result)
}That's it for code blocks. Syntax highlighting, file labels, line highlights, and captions—use them to make your code samples clear and nice looking.