issues/completed/10-041-malformed-boost-box-alignment.md
Issue 10-041: Malformed Boost Box Alignment and Formatting
Current Behavior
The [BOOST] box styling has misaligned box-drawing characters. Example from similar/different page output:
--- #3 fediverse_boost/6357 ---
◀─╔════════════════════════════════[BOOST]══════════════════════════════════─────╗
║ ┌────────────────────────────────────────────────────────────────────────────┐ ║
║ │ External post: https://tech.lgbt/users/paleblueyedot/statuses/115644789217659891 │ ║
║ └────────────────────────────────────────────────────────────────────────────┘ ║
╠─────────┐ ┌───────────╣
║ similar │ chronological │ different ║
╚═════════╧════════════════════════════════════════════════════════════╧══─────╝─▶
Issues observed:
- Right side not aligned: The
╗,║, and╝characters don't form a straight vertical line - Inner box overflow: Content line's
│ ║extends past the outer frame - Bottom border length:
══─────╝doesn't match the top border length - Nav separator misalignment:
┌───────────╣position doesn't match content box width - Long embedded boost content not wrapped: Embedded boosts with long content scroll off the right side of the page instead of wrapping to multiple lines
Long Content Overflow Example (embedded boost):
◀─╔════════════════════════════════[BOOST]══════════════════════════════════─────╗
║ ┌────────────────────────────────────────────────────────────────────────────┐ ║
║ │ Story idea: God somehow exists and made Man in His image: filled with nasty impulses and faulty cognitive heuristics. God checks back in with his progeny and is weirded out by how wildly civilization enabled us to diverge from Him. He gets out-thought and out-argued by average adjunct professors. He has the sort of omnipotence and omniscience that's more brute force than clear thinking, and gets mad at being left behind by His children. │ ║
║ └────────────────────────────────────────────────────────────────────────────┘ ║
The content line extends far beyond the 80-character box width, breaking the visual frame.
Intended Behavior
All box-drawing characters should align properly to form clean nested frames:
--- #3 fediverse_boost/6357 ---
◀─╔═════════════════════════════════════[BOOST]═════════════════════════════════─────────╗
║ ┌──────────────────────────────────────────────────────────────────────────────────┐ ║
║ │ External post: https://tech.lgbt/users/paleblueyedot/statuses/115644789217659891 │ ║
║ └──────────────────────────────────────────────────────────────────────────────────┘ ║
╠─────────┐ ┌───────────╣
║ similar │ chronological │ different ║
╚═════════╧════════════════════════════════════════════════════════════════╧═══════════╝─▶
Key requirements:
- Consistent line width: All lines should be the same total character width
- Vertical alignment: Right-side frame characters (
╗,║,╣,╝) must align vertically - Inner box fits: Content box must fit within outer frame without overflow
- Progress bar consistency: Top and bottom progress bars should use matching widths
Technical Analysis
Looking at src/flat-html-generator.lua:1815-2030:
Current width calculations (problematic):
- Top border:
BAR_WIDTH = 78characters for progress bar interior - Inner box:
INNER_WIDTH = 78with 76 dashes between corners - Content line:
CONTENT_WIDTH = 74characters for text ← too narrow, should be 80 - Nav separator:
60spaces between corners - Bottom border: Same
BAR_WIDTH = 78
Problems:
- Width mismatch: Different sections use inconsistent total widths
- Arrow placement:
◀─prefix and─▶suffix add 4 characters that may not be accounted for - Padding inconsistency: Space padding varies between frame layers
- Junction positions:
LEFT_JUNCTION_POS = 10,RIGHT_JUNCTION_POS = 71may not align with nav boxes
Suggested Implementation Steps
- Define master width constant: Establish single source of truth for box width
```lua
local BOOST_CONTENT_WIDTH = 80 -- Inner content area (standard terminal width)
-- Frame structure: ║ │ {content} │ ║
-- Left padding: ║(1) + space(1) + │(1) + space(1) = 4 chars
-- Right padding: space(1) + │(1) + space(1) + ║(1) = 4 chars
-- Total line width: 4 + 80 + 4 = 88 chars (plus ◀─ prefix on borders)
```
- Audit all formatting functions: Verify each returns exactly
BOOST_BOX_TOTAL_WIDTHcharacters
generate_boost_top_border()- verify total widthgenerate_boost_inner_box_top()- verify alignment with topgenerate_boost_content_line()- verify fits in inner boxgenerate_boost_inner_box_bottom()- verify matches inner_box_topgenerate_boost_nav_separator()- verify junction positionsgenerate_boost_nav_line()- verify box positionsgenerate_boost_bottom_border()- verify matches top_border
- Create visual test: Generate boost box in isolation to verify alignment
```lua
-- Test function to print boost box without HTML
local function test_boost_box_alignment()
print(generate_boost_top_border(0.5))
print(generate_boost_inner_box_top())
print(generate_boost_content_line("Test content here"))
print(generate_boost_inner_box_bottom())
print(generate_boost_nav_separator())
print(generate_boost_nav_line("similar", "different", "chronological"))
print(generate_boost_bottom_border(0.5))
end
```
- Fix width calculations: Adjust constants so all lines match
- Account for
◀─prefix (2 chars) and─▶suffix (2 chars) - Ensure inner content width leaves room for frame characters
- Handle long content: Content lines exceeding inner width need word wrapping
- Embedded boosts: Multi-line word wrapping with preserved indentation
- Split content at word boundaries to fit
BOOST_CONTENT_WIDTH(80 chars) - Each wrapped line gets its own
║ │ {content} │ ║frame - Use existing
wrap_preserving_indent()from text-formatter.lua (Issue 10-021) - External boost URLs: Break at logical points (path separators, query params)
- Keep full URL intact so users can visit the original post
- Example:
https://tech.lgbt/users/paleblueyedot/wraps to next line
/statuses/115644789217659891
- Coordinate with Issue 10-039 (make URLs clickable) - link href stays complete
- Inner box top/bottom borders appear once (not per-line)
- Replicate fixes to worker thread: Update worker functions to match
worker_boost_top_border()worker_boost_inner_top()worker_boost_inner_bottom()worker_boost_content_line()worker_boost_nav_separator()worker_boost_nav_line()worker_boost_bottom_border()
Related Files
src/flat-html-generator.lua:1811-2030- Main thread boost formatting functionssrc/flat-html-generator.lua:3388-3520- Worker thread boost formatting functionslibs/text-formatter.lua- Containswrap_preserving_indent()for word wrapping (Issue 10-021)- Issue 8-057 (original boost visual formatting implementation)
Test Cases
- Short content: "Hello world" - should be padded correctly
- Medium content: 40-character string - should center properly
- Long URL (external boost): 100+ character URL - should wrap at path separators (full URL preserved)
- Long text (embedded boost): 300+ character paragraph - should word-wrap to multiple content lines
- Progress bar: Test 0%, 50%, 100% progress positions
- Multi-paragraph embedded boost: Verify line breaks are preserved within wrapped content
Expected Long Content Rendering (embedded boost with 80-char content width):
◀─╔═══════════════════════════════════════════[BOOST]═══════════════════════════════════════════─────╗
║ ┌──────────────────────────────────────────────────────────────────────────────────────────────┐ ║
║ │ Story idea: God somehow exists and made Man in His image: filled with nasty impulses and │ ║
║ │ faulty cognitive heuristics. God checks back in with his progeny and is weirded out by how │ ║
║ │ wildly civilization enabled us to diverge from Him. He gets out-thought and out-argued by │ ║
║ │ average adjunct professors. He has the sort of omnipotence and omniscience that's more │ ║
║ │ brute force than clear thinking, and gets mad at being left behind by His children. │ ║
║ └──────────────────────────────────────────────────────────────────────────────────────────────┘ ║
╠───────────┐ ┌─────────────╣
║ similar │ chronological │ different ║
╚═══════════╧════════════════════════════════════════════════════════════════════════╧═════════════╝─▶
Note: Exact character counts in this example are illustrative. Implementation should derive all widths from BOOST_CONTENT_WIDTH = 80.
Dependencies
- This is a foundational fix that 10-040 (styling consistency) depends on
- Fix alignment BEFORE propagating boost styling to other page types
Priority: Medium - Visual quality issue
Phase: 10 - Developer Experience & Tooling
Implementation Notes (2026-03-25)
Issues fixed:
- Nav separator gap (main cause of misalignment):
- src/flat-html-generator.lua:1943-1948 - Changed gap from 60 to 58 spaces
- src/flat-html-generator.lua:3496-3503 - Worker thread: same fix
- Total width now matches other lines at 82 characters
- Long content wrapping (content overflow):
- src/flat-html-generator.lua:2206-2217 - Main thread: wrap embedded boost content to 74 chars using
text_formatter.wrap_preserving_indent() - src/flat-html-generator.lua:3665-3677 - Worker thread: same wrapping logic
- External post URLs kept intact (not wrapped) to preserve clickability
Width verification:
- Top border: ◀(1) + ─(1) + ╔(1) + bar(78) + ╗(1) = 82 ✓
- Inner box top/bottom: ║(1) + space(1) + ┌(1) + dashes(76) + ┐(1) + space(1) + ║(1) = 82 ✓
- Content line: ║(1) + space(1) + │(1) + space(1) + content(74) + space(1) + │(1) + space(1) + ║(1) = 82 ✓
- Nav separator: ╠(1) + dashes(9) + ┐(1) + spaces(58) + ┌(1) + dashes(11) + ╣(1) = 82 ✓ (FIXED)
- Bottom border: ╚(1) + bar(78) + ╝(1) + ─(1) + ▶(1) = 82 ✓
Status: Ready for testing. Regenerate HTML to verify boost boxes align properly and long content wraps within the frame.
Reference: Original Design
From /notes/boost post image style.png design reference (referenced in code comments):
- Red/Magenta:
◀─and─▶arrows,[BOOST]label - Blue/Navy:
╔═╗║╚═╝outer frame - Teal/Cyan:
┌─┐│└─┘inner content box - Yellow: Content text