Skip to content
Merged
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
32 changes: 21 additions & 11 deletions scripts/build_book.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import click
import check_code_snippets
import argparse
import sys

# Constants
OUTPUT_DIR = "output"
Expand Down Expand Up @@ -33,31 +34,40 @@ def remove_and_create_dir(directory_path):
os.makedirs(directory_path)


import sys


def run_command(command: str) -> None:
"""Run a shell command and stream output safely."""
"""Run a shell command, stream output live, and raise on failure.

Fixes UnicodeDecodeError by decoding with a tolerant error handler.
"""
click.secho(f"Running command: {command}", fg="green")

# Use the console's encoding if available; otherwise fall back to utf-8.
encoding = sys.stdout.encoding or "utf-8"

# Merge stderr into stdout so we stream everything and avoid stderr buffering issues.
process = subprocess.Popen(
command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, # merge streams so ordering is correct
stderr=subprocess.STDOUT,
text=True,
encoding="utf-8",
errors="replace", # <-- key fix
bufsize=1, # line-buffered
encoding=encoding,
errors="replace", # or "backslashreplace" if you want to see the bytes escaped
bufsize=1, # line-buffered (best effort)
universal_newlines=True,
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameters text=True (line 53) and universal_newlines=True (line 57) are redundant. Both parameters do the same thing - they enable text mode for subprocess output. In Python 3.7+, text is the preferred parameter name, while universal_newlines is the legacy alias. Only one should be specified to avoid confusion and redundancy.

Suggested change
universal_newlines=True,

Copilot uses AI. Check for mistakes.
)

assert process.stdout is not None
for line in process.stdout:
print(line.rstrip("\n"))
process.stdout.close()
try:
for line in process.stdout:
# Avoid .strip() eating meaningful whitespace; just drop the trailing newline.
print(line.rstrip("\n"))
finally:
process.stdout.close()

return_code = process.wait()
if return_code != 0:
click.secho(f"Command failed with exit code {return_code}: {command}", fg="red")
raise RuntimeError(f"Command failed: {command}")


Expand Down
7 changes: 7 additions & 0 deletions src/main.tex
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
\documentclass[letterpaper,11pt]{article}

\usepackage[top=1in, bottom=1in, left=1in, right=1in]{geometry}
\geometry{
headheight=14pt
}
\usepackage{microtype}
\usepackage{subfiles}
\usepackage[T1]{fontenc}
\usepackage[sfdefault]{cabin}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{graphicx}
\usepackage{float}
\usepackage{xurl}
\usepackage[hidelinks]{hyperref}
\usepackage{etoolbox}
\apptocmd{\bibsetup}{\sloppy}{}{}
\usepackage{xcolor}
\usepackage{titlesec}
\usepackage{listings}
Expand Down
Loading