Update version, add some story writer fixes.

This commit is contained in:
K. Hodges 2026-05-24 02:35:58 -07:00
parent 3f8532197f
commit 429269ea31
5 changed files with 78 additions and 55 deletions

View File

@ -1,3 +1,5 @@
# descriptions for logs are slightly off for the status thing. "Starting ollama HTTP model invocation" implies that it's stuck starting when it's not. # descriptions for logs are slightly off for the status thing. "Starting ollama HTTP model invocation" implies that it's stuck starting when it's not.
# We've stopped updating the version. # We've stopped updating the version, i need to add a script to do that so i dont forget.
# in the utils/ story compiler, the html version has various bugs including writing \newpage in plaintext.

View File

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
PACKAGE_VERSION = "0.2.5" PACKAGE_VERSION = "0.3.0"
RELEASE_CHANNEL = "alpha" RELEASE_CHANNEL = "alpha"
hotdog_version = "chicago" hotdog_version = "chicago"
topping_version = "onions" topping_version = "onions"

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "nightshift" name = "nightshift"
version = "0.1.0" version = "0.3.0"
description = "Auditable local-first AI coding pipelines." description = "Auditable local-first AI coding pipelines."
readme = "README.md" readme = "README.md"
requires-python = ">=3.11" requires-python = ">=3.11"

View File

@ -82,7 +82,7 @@ pip install markdown reportlab
# Quick Start # Quick Start
```powershell ```powershell
python compile_story.py --root . python compile.py --root .
``` ```
Outputs: Outputs:

View File

@ -286,7 +286,7 @@ def assemble_markdown(opts: BuildOptions) -> str:
# Optional cover reference for markdown/html. # Optional cover reference for markdown/html.
cover_path = story_dir / "cover.png" cover_path = story_dir / "cover.png"
if cover_path.exists(): if cover_path.exists():
parts.append("![Cover](../cover.png)") parts.append("![Cover](cover.png)")
parts.append(r"\newpage") parts.append(r"\newpage")
# TITLE.md wins over metadata title page. # TITLE.md wins over metadata title page.
@ -439,39 +439,40 @@ def markdown_to_html(md: str, metadata: Metadata) -> str:
# ---------------------------- # ----------------------------
def write_pdf(md: str, output_path: Path, metadata: Metadata, pdf_style: str) -> None: def write_pdf(md: str, output_path: Path, metadata: Metadata, pdf_style: str) -> None:
try: from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.lib.enums import TA_CENTER, TA_LEFT from reportlab.lib.pagesizes import A5, LETTER
from reportlab.lib.pagesizes import A5, LETTER from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet from reportlab.lib.units import inch
from reportlab.lib.units import inch from reportlab.platypus import (
from reportlab.platypus import ( SimpleDocTemplate,
SimpleDocTemplate, Paragraph,
Paragraph, Spacer,
Spacer, PageBreak,
PageBreak, Image,
) )
except ImportError as exc:
raise RuntimeError("Missing dependency: pip install reportlab") from exc story_dir = output_path.parent.parent
cover_path = story_dir / "cover.png"
if pdf_style == "paperback": if pdf_style == "paperback":
pagesize = A5 pagesize = A5
margins = dict( margins = {
leftMargin=0.65 * inch, "leftMargin": 0.65 * inch,
rightMargin=0.65 * inch, "rightMargin": 0.65 * inch,
topMargin=0.7 * inch, "topMargin": 0.7 * inch,
bottomMargin=0.7 * inch, "bottomMargin": 0.7 * inch,
) }
body_size = 10.5 body_size = 10.5
leading = 15 leading = 15
elif pdf_style == "manuscript": elif pdf_style == "manuscript":
pagesize = LETTER pagesize = LETTER
margins = dict( margins = {
leftMargin=1 * inch, "leftMargin": 1 * inch,
rightMargin=1 * inch, "rightMargin": 1 * inch,
topMargin=1 * inch, "topMargin": 1 * inch,
bottomMargin=1 * inch, "bottomMargin": 1 * inch,
) }
body_size = 12 body_size = 12
leading = 24 leading = 24
@ -534,64 +535,84 @@ def write_pdf(md: str, output_path: Path, metadata: Metadata, pdf_style: str) ->
story = [] story = []
paragraphs = md.splitlines() if cover_path.exists():
buffer: list[str] = [] printable_w = pagesize[0] - margins["leftMargin"] - margins["rightMargin"] - 8
printable_h = pagesize[1] - margins["topMargin"] - margins["bottomMargin"] - 8
def flush_paragraph(): img = Image(str(cover_path))
nonlocal buffer scale = min(
printable_w / img.imageWidth,
printable_h / img.imageHeight,
1.0,
)
img.drawWidth = img.imageWidth * scale
img.drawHeight = img.imageHeight * scale
story.append(img)
story.append(PageBreak())
def add_page_number(canvas, doc):
canvas.saveState()
canvas.setFont("Times-Roman", 9)
canvas.drawCentredString(pagesize[0] / 2, 0.35 * inch, str(doc.page))
canvas.restoreState()
def flush_paragraph(buffer):
text = " ".join(x.strip() for x in buffer).strip() text = " ".join(x.strip() for x in buffer).strip()
buffer = [] if text:
story.append(Paragraph(html.escape(text), body))
return []
if not text: buffer = []
return
safe = html.escape(text) for line in md.splitlines():
story.append(Paragraph(safe, body))
for line in paragraphs:
stripped = line.strip() stripped = line.strip()
if stripped.startswith("!["):
buffer = flush_paragraph(buffer)
continue
if stripped == r"\newpage": if stripped == r"\newpage":
flush_paragraph() buffer = flush_paragraph(buffer)
story.append(PageBreak()) story.append(PageBreak())
continue continue
if not stripped: if not stripped:
flush_paragraph() buffer = flush_paragraph(buffer)
story.append(Spacer(1, 6)) story.append(Spacer(1, 6))
continue continue
if stripped.startswith("# "): if stripped.startswith("# "):
flush_paragraph() buffer = flush_paragraph(buffer)
story.append(Paragraph(html.escape(stripped[2:].strip()), h1)) story.append(Paragraph(html.escape(stripped[2:].strip()), h1))
continue continue
if stripped.startswith("## "): if stripped.startswith("## "):
flush_paragraph() buffer = flush_paragraph(buffer)
story.append(Paragraph(html.escape(stripped[3:].strip()), h2)) story.append(Paragraph(html.escape(stripped[3:].strip()), h2))
continue continue
if stripped.startswith("### "): if stripped.startswith("### "):
flush_paragraph() buffer = flush_paragraph(buffer)
story.append(Paragraph(html.escape(stripped[4:].strip()), h3)) story.append(Paragraph(html.escape(stripped[4:].strip()), h3))
continue continue
# crude markdown list support
if re.match(r"^[-*]\s+", stripped): if re.match(r"^[-*]\s+", stripped):
flush_paragraph() buffer = flush_paragraph(buffer)
item = re.sub(r"^[-*]\s+", "", stripped) item = re.sub(r"^[-*]\s+", "", stripped)
story.append(Paragraph(html.escape(item), body)) story.append(Paragraph(html.escape(item), body))
continue continue
# skip images in ReportLab for now
if stripped.startswith("!["):
flush_paragraph()
continue
buffer.append(stripped) buffer.append(stripped)
flush_paragraph() buffer = flush_paragraph(buffer)
doc.build(story)
doc.build(
story,
onFirstPage=add_page_number,
onLaterPages=add_page_number,
)
# ---------------------------- # ----------------------------