codeannex 0.3.2__tar.gz → 0.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {codeannex-0.3.2 → codeannex-0.3.4}/PKG-INFO +1 -1
  2. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/core/pdf_builder.py +28 -24
  3. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex.egg-info/PKG-INFO +1 -1
  4. {codeannex-0.3.2 → codeannex-0.3.4}/pyproject.toml +1 -1
  5. {codeannex-0.3.2 → codeannex-0.3.4}/LICENSE +0 -0
  6. {codeannex-0.3.2 → codeannex-0.3.4}/README.md +0 -0
  7. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/__init__.py +0 -0
  8. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/__main__.py +0 -0
  9. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/core/__init__.py +0 -0
  10. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/core/config.py +0 -0
  11. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/interface/__init__.py +0 -0
  12. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/interface/cli.py +0 -0
  13. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/io/__init__.py +0 -0
  14. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/io/file_utils.py +0 -0
  15. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/io/git_utils.py +0 -0
  16. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/renderer/__init__.py +0 -0
  17. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/renderer/fonts.py +0 -0
  18. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/renderer/highlight.py +0 -0
  19. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex/renderer/text_utils.py +0 -0
  20. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex.egg-info/SOURCES.txt +0 -0
  21. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex.egg-info/dependency_links.txt +0 -0
  22. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex.egg-info/entry_points.txt +0 -0
  23. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex.egg-info/requires.txt +0 -0
  24. {codeannex-0.3.2 → codeannex-0.3.4}/codeannex.egg-info/top_level.txt +0 -0
  25. {codeannex-0.3.2 → codeannex-0.3.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeannex
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: Generates a professional PDF source code annex with Smart Index, Images and Emoji support.
5
5
  License: MIT
6
6
  Project-URL: Repository, https://github.com/tanhleno/codeannex
@@ -133,7 +133,17 @@ class ModernAnnexPDF:
133
133
  curr_y = self.config.page_height * 0.45
134
134
 
135
135
  if project_name:
136
- self._dctf(mid_x, curr_y, f"{self.config.repo_label}{project_name}", self.config.normal_font, 14, text_color)
136
+ display_repo = f"{self.config.repo_label}{project_name}"
137
+ name_w = self._gsw(display_repo, self.config.normal_font, 14)
138
+ start_x = mid_x - name_w / 2
139
+
140
+ # Draw the name (blue if it has a link)
141
+ final_color = colors.HexColor(self.config.primary_color) if self.config.repo_url else text_color
142
+ self._dtf(start_x, curr_y, display_repo, self.config.normal_font, 14, final_color)
143
+
144
+ if self.config.repo_url:
145
+ self.c.linkURL(self.config.repo_url, (start_x, curr_y - 2, start_x + name_w, curr_y + 12), relative=0, thickness=0, border=None)
146
+
137
147
  curr_y -= 8*mm
138
148
 
139
149
  # 4. Technical Metadata (Branch | Commit)
@@ -147,13 +157,6 @@ class ModernAnnexPDF:
147
157
  tech_str = " | ".join(tech_items)
148
158
  self._dctf(mid_x, curr_y, tech_str, self.config.normal_font, 10, colors.HexColor("#6c7086"))
149
159
  curr_y -= 12*mm
150
-
151
- if self.config.repo_url:
152
- url = self.config.repo_url
153
- url_w = self._gsw(url, self.config.normal_font, 11)
154
- start_x = mid_x - url_w / 2
155
- self._dtf(start_x, curr_y, url, self.config.normal_font, 11, colors.HexColor(self.config.primary_color))
156
- self.c.linkURL(url, (start_x, curr_y - 2, start_x + url_w, curr_y + 10), relative=0, thickness=0, border=None)
157
160
 
158
161
  def draw_summary_page(self, files: list):
159
162
  self.start_new_page()
@@ -163,7 +166,16 @@ class ModernAnnexPDF:
163
166
  title_font, 16, colors.HexColor(self.config.title_color))
164
167
  self.y -= 12*mm
165
168
  nested_tree: dict = {"_files": []}
169
+
170
+ # To avoid double entries for SVG (Image + Code)
171
+ processed_paths = set()
172
+ unique_files = []
166
173
  for fpath, ftype in files:
174
+ if fpath not in processed_paths:
175
+ unique_files.append((fpath, ftype))
176
+ processed_paths.add(fpath)
177
+
178
+ for fpath, ftype in unique_files:
167
179
  rel = fpath.relative_to(self.project_root)
168
180
  curr = nested_tree
169
181
  for part in rel.parts[:-1]: curr = curr.setdefault(part, {"_files": []})
@@ -174,10 +186,7 @@ class ModernAnnexPDF:
174
186
  def _draw_recursive_summary(self, node: dict, depth: int, path_parts: list, is_last_list: list):
175
187
  subdirs = sorted([k for k in node.keys() if k != "_files"], key=str.lower)
176
188
  files_in_node = node.get("_files", [])
177
-
178
- # Subdirectories first, then files (matches the new sort_files logic)
179
189
  all_entries = [(d, "dir") for d in subdirs] + [(f, "file") for f in files_in_node]
180
-
181
190
  indent_step, text_color = 5*mm, colors.HexColor(self.config.normal_text_color)
182
191
  for i, (item, type) in enumerate(all_entries):
183
192
  is_last = (i == len(all_entries) - 1)
@@ -204,9 +213,9 @@ class ModernAnnexPDF:
204
213
  self.y -= 6*mm
205
214
  if type == "dir": self._draw_recursive_summary(node[item], depth + 1, path_parts + [item], is_last_list + [is_last])
206
215
 
207
- def render_text_file(self, fpath: Path, label_suffix=""):
216
+ def render_text_file(self, fpath: Path):
208
217
  rel = fpath.relative_to(self.project_root).as_posix()
209
- display_name, bookmark_key = rel + label_suffix, _make_bookmark_key(rel)
218
+ display_name, bookmark_key = rel, _make_bookmark_key(rel)
210
219
  try: content = fpath.read_text(encoding="utf-8", errors="replace")
211
220
  except: return
212
221
  self._check_space(25*mm)
@@ -224,10 +233,8 @@ class ModernAnnexPDF:
224
233
  else:
225
234
  lexer = get_lexer_for_filename(str(fpath), stripnl=False)
226
235
  except ClassNotFound:
227
- if not self.is_simulation:
228
- print(f"ℹ️ Highlighting fallback: No lexer for '{fpath.name}'. Using plain text.")
236
+ if not self.is_simulation: print(f"ℹ️ Highlighting fallback: No lexer for '{fpath.name}'. Using plain text.")
229
237
  lexer = TextLexer(stripnl=False)
230
-
231
238
  self._render_tokens_to_lines(lexer.get_tokens(content or " "), display_name, bookmark_parts, total_parts)
232
239
  self.y -= 4*mm
233
240
 
@@ -289,20 +296,18 @@ class ModernAnnexPDF:
289
296
  if line_num is not None:
290
297
  num_str = str(line_num)
291
298
  num_char_w = pdfmetrics.stringWidth("0", self.mono_font, self.config.code_font_size)
292
- # Increase box size from 0.8 to 0.9 for better legibility
293
299
  box_hw = self.config.code_font_size * 0.9
294
300
  start_x = self.config.margin_left + GUTTER_W - 2.5*mm - len(num_str) * num_char_w
295
301
  for char in num_str:
296
- # Improved vertical centering
297
302
  self.c.drawImage(get_digit_sprites()[char], start_x + (num_char_w - box_hw) / 2.0, (self.y - self.config.code_font_size - 1.5) - box_hw * 0.1, width=box_hw, height=box_hw, mask="auto")
298
303
  start_x += num_char_w
299
304
  code_x = self.config.get_code_x() + 2*mm
300
305
  for chunk, color in v_line:
301
306
  code_x = draw_text_with_fallback(self.c, code_x, self.y - self.config.code_font_size - 1, chunk, self.mono_font, self.config.code_font_size, self.emoji_font, color, emoji_description=self.config.emoji_description)
302
307
 
303
- def render_image_file(self, fpath: Path, label_suffix=""):
308
+ def render_image_file(self, fpath: Path):
304
309
  rel = fpath.relative_to(self.project_root).as_posix()
305
- self._check_space(40*mm); self._register_bookmark(rel + label_suffix, _make_bookmark_key(rel)); self._draw_file_header(rel + label_suffix)
310
+ self._check_space(40*mm); self._register_bookmark(rel, _make_bookmark_key(rel)); self._draw_file_header(rel)
306
311
  self._draw_image(fpath)
307
312
 
308
313
  def _draw_image(self, fpath):
@@ -322,7 +327,7 @@ class ModernAnnexPDF:
322
327
  draw_y, block_bottom, block_w = self.y - draw_h - padding, self.y - draw_h - 2*padding, self.config.page_width - self.config.margin_left - self.config.margin_right
323
328
  if not self.is_simulation:
324
329
  self.c.setFillColor(colors.HexColor("#ffffff")); self.c.rect(self.config.margin_left, block_bottom, block_w, self.y - block_bottom, fill=1, stroke=0)
325
- self.c.setStrokeColor(colors.HexColor("#e6e9ef")); self.c.setLineWidth(0.5); self.c.rect(self.config.margin_left, block_bottom, block_w, self.y - block_bottom, fill=0, stroke=1)
330
+ self.c.setStrokeColor(colors.HexColor("#e6e9ef")); self.c.setLineWidth(1.0); self.c.rect(self.config.margin_left, block_bottom, block_w, self.y - block_bottom, fill=0, stroke=1)
326
331
  draw_x = self.config.margin_left + (block_w - draw_w) / 2
327
332
  if img is None and png_data: img = PilImage.open(io.BytesIO(png_data))
328
333
  if img: self.c.drawImage(ImageReader(img), draw_x, draw_y, draw_w, draw_h, preserveAspectRatio=True, mask="auto")
@@ -337,7 +342,6 @@ class ModernAnnexPDF:
337
342
  self.draw_cover(); self.draw_summary_page(files)
338
343
  for i, (fpath, ftype) in enumerate(files):
339
344
  if not self.is_simulation: print(f"\r\033[K[{i+1}/{len(files)}] Processing: {fpath.name}", end="")
340
- suffix = " (Code)" if ftype == "text" and fpath.suffix.lower() == ".svg" else ""
341
- if ftype == "text": self.render_text_file(fpath, label_suffix=suffix)
342
- elif ftype == "image": self.render_image_file(fpath, label_suffix=suffix)
345
+ if ftype == "text": self.render_text_file(fpath)
346
+ elif ftype == "image": self.render_image_file(fpath)
343
347
  if not self.is_simulation: print(); self.c.save()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeannex
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: Generates a professional PDF source code annex with Smart Index, Images and Emoji support.
5
5
  License: MIT
6
6
  Project-URL: Repository, https://github.com/tanhleno/codeannex
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "codeannex"
7
- version = "0.3.2"
7
+ version = "0.3.4"
8
8
  description = "Generates a professional PDF source code annex with Smart Index, Images and Emoji support."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
File without changes
File without changes
File without changes