Skip to content
Open
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
20 changes: 20 additions & 0 deletions code_formatter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from subprocess import check_output
from pathlib import Path
prev = ""

outputs = []

for width in range(40, 100):
print(f"Width: {width}")
output = check_output(["rustfmt", "input.rs", "--emit", "stdout", "-q", "--edition", "2024", "--style-edition", "2024", "--config", f"max_width={width},wrap_comments=true,comment_width={width}"])
out_str = output.decode()
if out_str != prev:
prev = out_str
outputs.append((width, out_str))

for (width, out_str) in outputs:
Path(f"out/{width}_output.rs").write_text(out_str)

from json import dumps

Path("out/out.json").write_text(dumps(outputs))
104 changes: 104 additions & 0 deletions content/posts/2025-04-12-responsive-code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
+++
title = "Responsive code formatting"
description = "TODO"
+++

The window currently fits <code id="code-width">X</code> characters.

<p>
<label>
<input type="checkbox" id="manual-width">
Manual width:
</label>
<input type="range" id="width-slider" min="30" max="100" value="50" disabled="true" style="vertical-align: middle">
<code id="code-width-manual">50</code>
</p>
<pre>
<code id="code-block" style="position: relative"><span id="code-block-inner"></span>
<div id="vLine" style="position: absolute; top: 0; bottom: 0; width: 3px; background-color: #11b; pointer-events: none; left: 100ch;"></div>
</code>
</pre>

<script>
const codeBlock = document.getElementById('code-block');
const codeBlockInner = document.getElementById('code-block-inner');
const codeWidth = document.getElementById('code-width');
const codeWidthManual = document.getElementById('code-width-manual');
const slider = document.getElementById('width-slider');
const checkbox = document.getElementById('manual-width');
const vLine = document.getElementById('vLine');

async function main() {
const contents = await fetch("/code-sample.json")
.then(response => response.json());

function updateContents(width) {
let out = "";
contents.forEach(function (item, idx) {
const txt_width = item[0];
const s = item[1];
if (txt_width < width) {
out = s;
}
});
codeBlockInner.textContent = out;
}

function update() {
let charsPerLine = slider.value;
let charsPerLineWindow = calculateCharsPerLine();
codeWidth.textContent = charsPerLineWindow;
if (!checkbox.checked) {
charsPerLine = charsPerLineWindow;
vLine.style.display = "none";
codeWidth.style.fontWeight = "bold";
codeWidthManual.style.fontWeight = "normal";
} else {
vLine.style.left = `${charsPerLine}ch`;
vLine.style.display = "block";
codeWidth.style.fontWeight = "normal";
codeWidthManual.style.fontWeight = "bold";
}
updateContents(charsPerLine);
}

const observer = new ResizeObserver(() => {
update();
});

observer.observe(codeBlock);

checkbox.addEventListener('change', () => {
slider.disabled = !checkbox.checked;
update();
});

slider.addEventListener('input', () => {
codeWidthManual.textContent = slider.value;
update();
});
}

function getCharWidth(element) {
// Create a span to measure width of a single character
const span = document.createElement('span');
span.textContent = 'M'; // A typical monospace character
span.style.visibility = 'hidden';
span.style.font = getComputedStyle(element).font;
document.body.appendChild(span);
const width = span.getBoundingClientRect().width;
document.body.removeChild(span);
return width;
}

function calculateCharsPerLine() {
const padding = 2 * 10;
const width = codeBlock.getBoundingClientRect().width - padding;
const charWidth = getCharWidth(codeBlock);
const charsPerLine = Math.floor(width / charWidth);
// console.log(`Width: ${width}px, Char width: ${charWidth}px, Fits: ${charsPerLine} chars`);
return charsPerLine;
}

main();
</script>
52 changes: 52 additions & 0 deletions input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/// std::io::Write
pub trait Write {
/// Writes a formatted string into this writer, returning any error encountered.
///
/// This method is primarily used to interface with the [`format_args!()`] macro, and it is rare that this should explicitly be called. The [`write!()`] macro should be favored to invoke this method instead.
///
/// This function internally uses the [`write_all`] method on this trait and hence will continuously write data so long as no errors are received. This also means that partial writes are not indicated in this signature.
///
/// [`write_all`]: Write::write_all
///
/// # Errors
///
/// This function will return any I/O error reported while formatting.
///
/// ...
#[stable(feature = "rust1", since = "1.0.0")]
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> {
// Create a shim which translates a Write to a fmt::Write and saves off I/O errors. instead of discarding them
struct Adapter<'a, T: ?Sized + 'a> {
inner: &'a mut T,
error: Result<()>,
}

impl<T: Write + ?Sized> fmt::Write for Adapter<'_, T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
match self.inner.write_all(s.as_bytes()) {
Ok(()) => Ok(()),
Err(e) => {
self.error = Err(e);
Err(fmt::Error)
}
}
}
}

let mut output = Adapter { inner: self, error: Ok(()) };
match fmt::write(&mut output, fmt) {
Ok(()) => Ok(()),
Err(..) => {
// check if the error came from the underlying `Write` or not
if output.error.is_err() {
output.error
} else {
// This shouldn't happen: the underlying stream did not error, but somehow the formatter still errored?
panic!(
"a formatting trait implementation returned an error when the underlying stream did not"
);
}
}
}
}
}
1 change: 1 addition & 0 deletions static/code-sample.json

Large diffs are not rendered by default.