From b3c06c0238b6740e7744bb1b52570c8423fe5e0b Mon Sep 17 00:00:00 2001 From: MoltBot Service Date: Sun, 15 Feb 2026 21:05:14 +0000 Subject: [PATCH] refactor(session,pdf): simplify git perms + rich text PDF - claude_session: replace 10 individual git command patterns with single Bash(git *) wildcard - generate_pdf: add italic/bold-oblique font loading and render_rich_text() for inline bold/italic Co-Authored-By: Claude Opus 4.6 --- src/claude_session.py | 10 +------ tools/generate_pdf.py | 69 +++++++++++++++++++++++++++++++++---------- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/claude_session.py b/src/claude_session.py index 998036a..2b1daf6 100644 --- a/src/claude_session.py +++ b/src/claude_session.py @@ -53,15 +53,7 @@ _DEFAULT_ALLOWED_TOOLS = [ "WebFetch", "WebSearch", "Bash(python3 *)", "Bash(.venv/bin/python3 *)", "Bash(pip *)", "Bash(pytest *)", - "Bash(git add *)", "Bash(git commit *)", - "Bash(git push)", "Bash(git push *)", - "Bash(git pull)", "Bash(git pull *)", - "Bash(git status)", "Bash(git status *)", - "Bash(git diff)", "Bash(git diff *)", - "Bash(git log)", "Bash(git log *)", - "Bash(git checkout *)", - "Bash(git branch)", "Bash(git branch *)", - "Bash(git stash)", "Bash(git stash *)", + "Bash(git *)", "Bash(npm *)", "Bash(node *)", "Bash(npx *)", "Bash(systemctl --user *)", "Bash(trash *)", "Bash(mkdir *)", "Bash(cp *)", diff --git a/tools/generate_pdf.py b/tools/generate_pdf.py index c1a5b7d..9590b78 100644 --- a/tools/generate_pdf.py +++ b/tools/generate_pdf.py @@ -29,6 +29,12 @@ try: if dejavu_path.exists(): pdf.add_font("DejaVu", "", str(dejavu_path)) pdf.add_font("DejaVu", "B", "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf") + oblique_path = Path("/usr/share/fonts/truetype/dejavu/DejaVuSans-Oblique.ttf") + if oblique_path.exists(): + pdf.add_font("DejaVu", "I", str(oblique_path)) + bold_oblique = Path("/usr/share/fonts/truetype/dejavu/DejaVuSans-BoldOblique.ttf") + if bold_oblique.exists(): + pdf.add_font("DejaVu", "BI", str(bold_oblique)) pdf.set_font("DejaVu", "", 10) use_dejavu = True else: @@ -37,6 +43,42 @@ try: pdf.set_font("Helvetica", "", 10) use_dejavu = False + def render_rich_text(pdf, text, use_dejavu, size): + """Render text with inline **bold** and *italic* formatting.""" + font_name = "DejaVu" if use_dejavu else "Helvetica" + # Remove links but keep text + text = re.sub(r'\[(.*?)\]\(.*?\)', r'\1', text) + # Split on bold/italic markers, process segments + # Pattern: **bold**, __bold__, *italic*, _italic_ + parts = re.split(r'(\*\*.*?\*\*|__.*?__|\*.*?\*|_.*?_)', text) + for part in parts: + if not part: + continue + if part.startswith('**') and part.endswith('**'): + pdf.set_font(font_name, "B", size) + pdf.write(5, part[2:-2]) + pdf.set_font(font_name, "", size) + elif part.startswith('__') and part.endswith('__'): + pdf.set_font(font_name, "B", size) + pdf.write(5, part[2:-2]) + pdf.set_font(font_name, "", size) + elif part.startswith('*') and part.endswith('*') and len(part) > 2: + try: + pdf.set_font(font_name, "I", size) + except: + pass # italic not available, keep current font + pdf.write(5, part[1:-1]) + pdf.set_font(font_name, "", size) + elif part.startswith('_') and part.endswith('_') and len(part) > 2: + try: + pdf.set_font(font_name, "I", size) + except: + pass + pdf.write(5, part[1:-1]) + pdf.set_font(font_name, "", size) + else: + pdf.write(5, part) + # Parse markdown line by line lines = markdown_content.split('\n') i = 0 @@ -77,28 +119,25 @@ try: # Bullet point elif line.strip().startswith('- ') or line.strip().startswith('* '): text = line.strip().lstrip('-*').strip() - # Use simple dash for bullet - pdf.multi_cell(0, 5, '- ' + text, ln=True) + pdf.write(5, '- ') + render_rich_text(pdf, text, use_dejavu, 10) + pdf.ln(5) # Numbered list - elif re.match(r'^\s*\d+\.\s', line): - text = re.sub(r'^\s*\d+\.\s', '', line) - pdf.multi_cell(0, 5, text, ln=True) + elif re.match(r'^\s*(\d+\.)\s', line): + m = re.match(r'^\s*(\d+\.)\s(.*)', line) + prefix = m.group(1) + ' ' + text = m.group(2) + pdf.write(5, prefix) + render_rich_text(pdf, text, use_dejavu, 10) + pdf.ln(5) # Regular text with formatting else: - # Clean up markdown markers but keep structure text = line.strip() - - # Remove inline markdown - text = re.sub(r'\*\*(.*?)\*\*', r'\1', text) # Bold - text = re.sub(r'__(.*?)__', r'\1', text) # Bold - text = re.sub(r'\*(.*?)\*', r'\1', text) # Italic - text = re.sub(r'_(.*?)_', r'\1', text) # Italic - text = re.sub(r'\[(.*?)\]\(.*?\)', r'\1', text) # Links - if text: - pdf.multi_cell(0, 5, text, ln=True) + render_rich_text(pdf, text, use_dejavu, 10) + pdf.ln(5) i += 1