|
14 | 14 | import click |
15 | 15 | from click_default_group import DefaultGroup |
16 | 16 | import httpx |
| 17 | +from jinja2 import Environment, PackageLoader |
17 | 18 | import markdown |
18 | 19 | import questionary |
19 | 20 |
|
| 21 | +# Set up Jinja2 environment |
| 22 | +_jinja_env = Environment( |
| 23 | + loader=PackageLoader("claude_code_publish", "templates"), |
| 24 | + autoescape=False, # We handle escaping manually in render functions |
| 25 | +) |
| 26 | + |
| 27 | + |
| 28 | +def get_template(name): |
| 29 | + """Get a Jinja2 template by name.""" |
| 30 | + return _jinja_env.get_template(name) |
| 31 | + |
| 32 | + |
20 | 33 | # Regex to match git commit output: [branch hash] message |
21 | 34 | COMMIT_PATTERN = re.compile(r"\[[\w\-/]+ ([a-f0-9]{7,})\] (.+?)(?:\n|$)") |
22 | 35 |
|
@@ -801,24 +814,15 @@ def generate_html(json_path, output_dir, github_repo=None): |
801 | 814 | messages_html.append(msg_html) |
802 | 815 | is_first = False |
803 | 816 | pagination_html = generate_pagination_html(page_num, total_pages) |
804 | | - page_content = f"""<!DOCTYPE html> |
805 | | -<html lang="en"> |
806 | | -<head> |
807 | | - <meta charset="UTF-8"> |
808 | | - <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
809 | | - <title>Claude Code transcript - page {page_num}</title> |
810 | | - <style>{CSS}</style> |
811 | | -</head> |
812 | | -<body> |
813 | | - <div class="container"> |
814 | | - <h1><a href="index.html" style="color: inherit; text-decoration: none;">Claude Code transcript</a> - page {page_num}/{total_pages}</h1> |
815 | | - {pagination_html} |
816 | | - {''.join(messages_html)} |
817 | | - {pagination_html} |
818 | | - </div> |
819 | | - <script>{JS}</script> |
820 | | -</body> |
821 | | -</html>""" |
| 817 | + page_template = get_template("page.html") |
| 818 | + page_content = page_template.render( |
| 819 | + css=CSS, |
| 820 | + js=JS, |
| 821 | + page_num=page_num, |
| 822 | + total_pages=total_pages, |
| 823 | + pagination_html=pagination_html, |
| 824 | + messages_html="".join(messages_html), |
| 825 | + ) |
822 | 826 | (output_dir / f"page-{page_num:03d}.html").write_text(page_content) |
823 | 827 | print(f"Generated page-{page_num:03d}.html") |
824 | 828 |
|
@@ -894,25 +898,18 @@ def generate_html(json_path, output_dir, github_repo=None): |
894 | 898 | index_items = [item[2] for item in timeline_items] |
895 | 899 |
|
896 | 900 | index_pagination = generate_index_pagination_html(total_pages) |
897 | | - index_content = f"""<!DOCTYPE html> |
898 | | -<html lang="en"> |
899 | | -<head> |
900 | | - <meta charset="UTF-8"> |
901 | | - <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
902 | | - <title>Claude Code transcript - Index</title> |
903 | | - <style>{CSS}</style> |
904 | | -</head> |
905 | | -<body> |
906 | | - <div class="container"> |
907 | | - <h1>Claude Code transcript</h1> |
908 | | - {index_pagination} |
909 | | - <p style="color: var(--text-muted); margin-bottom: 24px;">{prompt_num} prompts · {total_messages} messages · {total_tool_calls} tool calls · {total_commits} commits · {total_pages} pages</p> |
910 | | - {''.join(index_items)} |
911 | | - {index_pagination} |
912 | | - </div> |
913 | | - <script>{JS}</script> |
914 | | -</body> |
915 | | -</html>""" |
| 901 | + index_template = get_template("index.html") |
| 902 | + index_content = index_template.render( |
| 903 | + css=CSS, |
| 904 | + js=JS, |
| 905 | + pagination_html=index_pagination, |
| 906 | + prompt_num=prompt_num, |
| 907 | + total_messages=total_messages, |
| 908 | + total_tool_calls=total_tool_calls, |
| 909 | + total_commits=total_commits, |
| 910 | + total_pages=total_pages, |
| 911 | + index_items_html="".join(index_items), |
| 912 | + ) |
916 | 913 | index_path = output_dir / "index.html" |
917 | 914 | index_path.write_text(index_content) |
918 | 915 | print( |
@@ -1143,24 +1140,15 @@ def generate_html_from_session_data(session_data, output_dir, github_repo=None): |
1143 | 1140 | messages_html.append(msg_html) |
1144 | 1141 | is_first = False |
1145 | 1142 | pagination_html = generate_pagination_html(page_num, total_pages) |
1146 | | - page_content = f"""<!DOCTYPE html> |
1147 | | -<html lang="en"> |
1148 | | -<head> |
1149 | | - <meta charset="UTF-8"> |
1150 | | - <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
1151 | | - <title>Claude Code transcript - page {page_num}</title> |
1152 | | - <style>{CSS}</style> |
1153 | | -</head> |
1154 | | -<body> |
1155 | | - <div class="container"> |
1156 | | - <h1><a href="index.html" style="color: inherit; text-decoration: none;">Claude Code transcript</a> - page {page_num}/{total_pages}</h1> |
1157 | | - {pagination_html} |
1158 | | - {''.join(messages_html)} |
1159 | | - {pagination_html} |
1160 | | - </div> |
1161 | | - <script>{JS}</script> |
1162 | | -</body> |
1163 | | -</html>""" |
| 1143 | + page_template = get_template("page.html") |
| 1144 | + page_content = page_template.render( |
| 1145 | + css=CSS, |
| 1146 | + js=JS, |
| 1147 | + page_num=page_num, |
| 1148 | + total_pages=total_pages, |
| 1149 | + pagination_html=pagination_html, |
| 1150 | + messages_html="".join(messages_html), |
| 1151 | + ) |
1164 | 1152 | (output_dir / f"page-{page_num:03d}.html").write_text(page_content) |
1165 | 1153 | click.echo(f"Generated page-{page_num:03d}.html") |
1166 | 1154 |
|
@@ -1236,25 +1224,18 @@ def generate_html_from_session_data(session_data, output_dir, github_repo=None): |
1236 | 1224 | index_items = [item[2] for item in timeline_items] |
1237 | 1225 |
|
1238 | 1226 | index_pagination = generate_index_pagination_html(total_pages) |
1239 | | - index_content = f"""<!DOCTYPE html> |
1240 | | -<html lang="en"> |
1241 | | -<head> |
1242 | | - <meta charset="UTF-8"> |
1243 | | - <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
1244 | | - <title>Claude Code transcript - Index</title> |
1245 | | - <style>{CSS}</style> |
1246 | | -</head> |
1247 | | -<body> |
1248 | | - <div class="container"> |
1249 | | - <h1>Claude Code transcript</h1> |
1250 | | - {index_pagination} |
1251 | | - <p style="color: var(--text-muted); margin-bottom: 24px;">{prompt_num} prompts · {total_messages} messages · {total_tool_calls} tool calls · {total_commits} commits · {total_pages} pages</p> |
1252 | | - {''.join(index_items)} |
1253 | | - {index_pagination} |
1254 | | - </div> |
1255 | | - <script>{JS}</script> |
1256 | | -</body> |
1257 | | -</html>""" |
| 1227 | + index_template = get_template("index.html") |
| 1228 | + index_content = index_template.render( |
| 1229 | + css=CSS, |
| 1230 | + js=JS, |
| 1231 | + pagination_html=index_pagination, |
| 1232 | + prompt_num=prompt_num, |
| 1233 | + total_messages=total_messages, |
| 1234 | + total_tool_calls=total_tool_calls, |
| 1235 | + total_commits=total_commits, |
| 1236 | + total_pages=total_pages, |
| 1237 | + index_items_html="".join(index_items), |
| 1238 | + ) |
1258 | 1239 | index_path = output_dir / "index.html" |
1259 | 1240 | index_path.write_text(index_content) |
1260 | 1241 | click.echo( |
|
0 commit comments