pdflinkcheck 1.2.29__tar.gz → 1.3.8__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 (191) hide show
  1. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/LICENSE +3 -3
  2. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/PKG-INFO +19 -16
  3. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/README.md +14 -12
  4. {pdflinkcheck-1.2.29/src/pdflinkcheck/data → pdflinkcheck-1.3.8}/pyproject.toml +4 -3
  5. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/__init__.py +1 -1
  6. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/cli.py +111 -27
  7. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/LICENSE +3 -3
  8. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/README.md +14 -12
  9. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8/src/pdflinkcheck/data}/pyproject.toml +4 -3
  10. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/environment.py +14 -7
  11. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/gui.py +74 -18
  12. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/helpers.py +47 -1
  13. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/io.py +35 -6
  14. pdflinkcheck-1.2.29/src/pdflinkcheck/report.py → pdflinkcheck-1.3.8/src/pdflinkcheck/report copy.py +57 -32
  15. pdflinkcheck-1.3.8/src/pdflinkcheck/report.py +561 -0
  16. pdflinkcheck-1.3.8/src/pdflinkcheck/spreadsheet.py +271 -0
  17. pdflinkcheck-1.2.29/src/pdflinkcheck/stdlib_server_alt.py → pdflinkcheck-1.3.8/src/pdflinkcheck/stdlib_server.py +156 -115
  18. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/validate.py +11 -6
  19. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck.egg-info/PKG-INFO +19 -16
  20. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck.egg-info/SOURCES.txt +2 -1
  21. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck.egg-info/requires.txt +5 -4
  22. pdflinkcheck-1.2.29/src/pdflinkcheck/stdlib_server.py +0 -170
  23. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/LICENSE-AGPL3 +0 -0
  24. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/LICENSE-MIT +0 -0
  25. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/MANIFEST.in +0 -0
  26. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/setup.cfg +0 -0
  27. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/__main__.py +0 -0
  28. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/analysis_pdfium.py +0 -0
  29. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/analysis_pymupdf.py +0 -0
  30. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/analysis_pypdf.py +0 -0
  31. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/I Have Questions.md +0 -0
  32. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/icons/BoxArt-1080x1080.png +0 -0
  33. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/icons/Logo-150x150.png +0 -0
  34. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/icons/Logo-300x300.png +0 -0
  35. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/icons/Logo-71x71.png +0 -0
  36. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/icons/PosterArt-720x1080.png +0 -0
  37. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/icons/SmallLogo-44x44.png +0 -0
  38. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/icons/SplashScreen-620x300.png +0 -0
  39. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/icons/StoreLogo-50x50.png +0 -0
  40. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/icons/WideLogo-310x150.png +0 -0
  41. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/icons/red_pdf_512px.ico +0 -0
  42. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/border-accent-hover.png +0 -0
  43. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/border-accent.png +0 -0
  44. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/border-basic.png +0 -0
  45. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/border-hover.png +0 -0
  46. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/border-invalid.png +0 -0
  47. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/card.png +0 -0
  48. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/check-accent.png +0 -0
  49. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/check-basic.png +0 -0
  50. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/check-hover.png +0 -0
  51. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/check-tri-accent.png +0 -0
  52. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/check-tri-basic.png +0 -0
  53. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/check-tri-hover.png +0 -0
  54. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/check-unsel-accent.png +0 -0
  55. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/check-unsel-basic.png +0 -0
  56. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/check-unsel-hover.png +0 -0
  57. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/check-unsel-pressed.png +0 -0
  58. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/combo-button-basic.png +0 -0
  59. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/combo-button-focus.png +0 -0
  60. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/combo-button-hover.png +0 -0
  61. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/down.png +0 -0
  62. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/empty.png +0 -0
  63. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/hor-accent.png +0 -0
  64. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/hor-basic.png +0 -0
  65. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/hor-hover.png +0 -0
  66. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/notebook.png +0 -0
  67. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/off-accent.png +0 -0
  68. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/off-basic.png +0 -0
  69. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/off-hover.png +0 -0
  70. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/on-accent.png +0 -0
  71. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/on-basic.png +0 -0
  72. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/on-hover.png +0 -0
  73. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/radio-accent.png +0 -0
  74. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/radio-basic.png +0 -0
  75. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/radio-hover.png +0 -0
  76. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/radio-tri-accent.png +0 -0
  77. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/radio-tri-basic.png +0 -0
  78. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/radio-tri-hover.png +0 -0
  79. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/radio-unsel-accent.png +0 -0
  80. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/radio-unsel-basic.png +0 -0
  81. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/radio-unsel-hover.png +0 -0
  82. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/radio-unsel-pressed.png +0 -0
  83. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/rect-accent-hover.png +0 -0
  84. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/rect-accent.png +0 -0
  85. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/rect-basic.png +0 -0
  86. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/rect-hover.png +0 -0
  87. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/right.png +0 -0
  88. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/scale-hor.png +0 -0
  89. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/scale-vert.png +0 -0
  90. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/separator.png +0 -0
  91. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/sizegrip.png +0 -0
  92. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/spin-button-down-basic.png +0 -0
  93. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/spin-button-down-focus.png +0 -0
  94. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/spin-button-up.png +0 -0
  95. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/tab-accent.png +0 -0
  96. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/tab-basic.png +0 -0
  97. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/tab-hover.png +0 -0
  98. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/thumb-hor-accent.png +0 -0
  99. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/thumb-hor-basic.png +0 -0
  100. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/thumb-hor-hover.png +0 -0
  101. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/thumb-vert-accent.png +0 -0
  102. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/thumb-vert-basic.png +0 -0
  103. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/thumb-vert-hover.png +0 -0
  104. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/tree-basic.png +0 -0
  105. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/tree-pressed.png +0 -0
  106. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/up.png +0 -0
  107. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/vert-accent.png +0 -0
  108. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/vert-basic.png +0 -0
  109. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark/vert-hover.png +0 -0
  110. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-dark.tcl +0 -0
  111. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/border-accent-hover.png +0 -0
  112. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/border-accent.png +0 -0
  113. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/border-basic.png +0 -0
  114. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/border-hover.png +0 -0
  115. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/border-invalid.png +0 -0
  116. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/card.png +0 -0
  117. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/check-accent.png +0 -0
  118. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/check-basic.png +0 -0
  119. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/check-hover.png +0 -0
  120. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/check-tri-accent.png +0 -0
  121. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/check-tri-basic.png +0 -0
  122. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/check-tri-hover.png +0 -0
  123. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/check-unsel-accent.png +0 -0
  124. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/check-unsel-basic.png +0 -0
  125. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/check-unsel-hover.png +0 -0
  126. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/check-unsel-pressed.png +0 -0
  127. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/combo-button-basic.png +0 -0
  128. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/combo-button-focus.png +0 -0
  129. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/combo-button-hover.png +0 -0
  130. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/down-focus.png +0 -0
  131. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/down.png +0 -0
  132. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/empty.png +0 -0
  133. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/hor-accent.png +0 -0
  134. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/hor-basic.png +0 -0
  135. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/hor-hover.png +0 -0
  136. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/notebook.png +0 -0
  137. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/off-accent.png +0 -0
  138. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/off-basic.png +0 -0
  139. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/off-hover.png +0 -0
  140. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/on-accent.png +0 -0
  141. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/on-basic.png +0 -0
  142. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/on-hover.png +0 -0
  143. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/radio-accent.png +0 -0
  144. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/radio-basic.png +0 -0
  145. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/radio-hover.png +0 -0
  146. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/radio-tri-accent.png +0 -0
  147. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/radio-tri-basic.png +0 -0
  148. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/radio-tri-hover.png +0 -0
  149. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/radio-unsel-accent.png +0 -0
  150. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/radio-unsel-basic.png +0 -0
  151. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/radio-unsel-hover.png +0 -0
  152. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/radio-unsel-pressed.png +0 -0
  153. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/rect-accent-hover.png +0 -0
  154. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/rect-accent.png +0 -0
  155. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/rect-basic.png +0 -0
  156. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/rect-hover.png +0 -0
  157. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/right-focus.png +0 -0
  158. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/right.png +0 -0
  159. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/scale-hor.png +0 -0
  160. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/scale-vert.png +0 -0
  161. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/separator.png +0 -0
  162. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/sizegrip.png +0 -0
  163. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/spin-button-down-basic.png +0 -0
  164. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/spin-button-down-focus.png +0 -0
  165. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/spin-button-up.png +0 -0
  166. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/tab-accent.png +0 -0
  167. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/tab-basic.png +0 -0
  168. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/tab-hover.png +0 -0
  169. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/thumb-hor-accent.png +0 -0
  170. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/thumb-hor-basic.png +0 -0
  171. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/thumb-hor-hover.png +0 -0
  172. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/thumb-vert-accent.png +0 -0
  173. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/thumb-vert-basic.png +0 -0
  174. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/thumb-vert-hover.png +0 -0
  175. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/tree-basic.png +0 -0
  176. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/tree-pressed.png +0 -0
  177. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/up.png +0 -0
  178. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/vert-accent.png +0 -0
  179. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/vert-basic.png +0 -0
  180. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light/vert-hover.png +0 -0
  181. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/data/themes/forest/forest-light.tcl +0 -0
  182. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/datacopy.py +0 -0
  183. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/dev.py +0 -0
  184. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/security.py +0 -0
  185. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/splash.py +0 -0
  186. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/tk_utils.py +0 -0
  187. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/update_msix_version.py +0 -0
  188. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck/version_info.py +0 -0
  189. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck.egg-info/dependency_links.txt +0 -0
  190. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck.egg-info/entry_points.txt +0 -0
  191. {pdflinkcheck-1.2.29 → pdflinkcheck-1.3.8}/src/pdflinkcheck.egg-info/top_level.txt +0 -0
@@ -2,11 +2,11 @@ Some distributed binaries of this project include the PyMuPDF library, which is
2
2
  Any binary that incorporates PyMuPDF is therefore distributed under **AGPL3.0orlater**.
3
3
  Other binaries use only the `pypdf` library and do not include PyMuPDF; these binaries are distributed under the **MIT License**.
4
4
 
5
- For AGPLlicensed binaries, the complete corresponding source code must be made available to anyone who possesses a copy, upon request.
5
+ For AGPL-licensed binaries, the complete corresponding source code must be made available to anyone who possesses a copy, upon request.
6
6
  This obligation applies only to recipients of those binaries, and hosting the source code in GitHub Releases satisfies this requirement.
7
7
 
8
- A binary becomes AGPLlicensed only when built with the optional `"full"` dependency group (as defined in `pyproject.toml` under `[project.optional-dependencies]`) or when PyMuPDF is otherwise included in the build environment.
9
- The **source code of pdflinkcheck itself** remains licensed under the **MIT License**; only the distributed binary becomes AGPLlicensed when PyMuPDF is included.
8
+ A binary becomes AGPL-licensed only when built with the optional `"full"` dependency group (as defined in `pyproject.toml` under `[project.optional-dependencies]`) or when PyMuPDF is otherwise included in the build environment.
9
+ The **source code of pdflinkcheck itself** remains licensed under the **MIT License**. Only a distributed binary (or a publicly served web app) becomes AGPL-licensed when PyMuPDF is included.
10
10
 
11
11
  Source code for each released version is available in the `pdflinkcheckVERSION.tar.gz` files on the projects GitHub Releases page.
12
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pdflinkcheck
3
- Version: 1.2.29
3
+ Version: 1.3.8
4
4
  Summary: A purpose-built PDF link analysis and reporting tool with GUI and CLI.
5
5
  Author-email: George Clayton Bennett <george.bennett@memphistn.gov>
6
6
  Maintainer-email: George Clayton Bennett <george.bennett@memphistn.gov>
@@ -34,12 +34,13 @@ Description-Content-Type: text/markdown
34
34
  License-File: LICENSE
35
35
  License-File: LICENSE-MIT
36
36
  License-File: LICENSE-AGPL3
37
- Requires-Dist: pyhabitat>=1.1.5
37
+ Requires-Dist: openpyxl>=3.1.5
38
+ Requires-Dist: pyhabitat>=1.1.6
38
39
  Requires-Dist: pypdf>=6.4.2
39
40
  Requires-Dist: rich>=14.2.0
40
41
  Requires-Dist: typer>=0.20.0
41
- Provides-Extra: mupdf
42
- Requires-Dist: pymupdf<2.0.0,>=1.24.0; extra == "mupdf"
42
+ Provides-Extra: pymupdf
43
+ Requires-Dist: pymupdf<2.0.0,>=1.24.0; extra == "pymupdf"
43
44
  Provides-Extra: pdfium
44
45
  Requires-Dist: pypdfium2<6.0.0,>=5.2.0; extra == "pdfium"
45
46
  Provides-Extra: full
@@ -51,9 +52,11 @@ Dynamic: license-file
51
52
 
52
53
  A purpose-built tool for comprehensive analysis of hyperlinks and GoTo links within PDF documents. Users may leverage either the PyMuPDF or the pypdf library. Use the CLI or the GUI.
53
54
 
55
+ [![Get it from the Microsoft Store](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/ms_store_badge_en-us-light.svg)](https://apps.microsoft.com/store/detail/9n11hxvls1wg)
56
+
54
57
  -----
55
58
 
56
- ![Screenshot of the pdflinkcheck GUI](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_gui_v1.1.97.png)
59
+ ![Screenshot of the pdflinkcheck GUI](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_gui_v1.3.3.png)
57
60
 
58
61
  -----
59
62
 
@@ -102,7 +105,7 @@ Ways to launch the GUI interface:
102
105
  The core functionality is accessed via the `analyze` command.
103
106
 
104
107
  `pdflinkcheck --help`:
105
- ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.1.97.png)
108
+ ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.3.3.png)
106
109
 
107
110
 
108
111
  See the Help Tree by unlocking the help-tree CLI command, using the DEV_TYPER_HELP_TREE env var.
@@ -112,7 +115,7 @@ DEV_TYPER_HELP_TREE=1 pdflinkcheck help-tree` # bash
112
115
  $env:DEV_TYPER_HELP_TREE = "1"; pdflinkcheck help-tree` # PowerShell
113
116
  ```
114
117
 
115
- ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.1.97_tree_help.png)
118
+ ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.3.3_tree_help.png)
116
119
 
117
120
 
118
121
 
@@ -132,7 +135,7 @@ $env:DEV_TYPER_HELP_TREE = "1"; pdflinkcheck help-tree` # PowerShell
132
135
  |---|---|---|
133
136
  |`<PDF_PATH>`|**Required.** The path to the PDF file to analyze.|N/A|
134
137
  |`--pdf-library / -p`|Select engine: `pymupdf` or `pypdf`.|`pypdf`|
135
- |`--export-format / -e`|Export to `JSON`, `TXT`, or `None` to suppress file output.|`JSON`|
138
+ |`--format / -f`|Export to `JSON`, `TXT`, `XLSX`, and/or `None` to suppress file output.|`JSON`|
136
139
 
137
140
  ### `gui` Command Options
138
141
 
@@ -143,8 +146,8 @@ $env:DEV_TYPER_HELP_TREE = "1"; pdflinkcheck help-tree` # PowerShell
143
146
  #### Example Runs
144
147
 
145
148
  ```bash
146
- # Analyze a document, show all links, and save the report as JSON and TXT
147
- pdflinkcheck analyze "TE Maxson WWTF O&M Manual.pdf" --export-format JSON,TXT
149
+ # Analyze a document, show all links, and save the report as XLSX, JSON, and TXT
150
+ pdflinkcheck analyze "TE Maxson WWTF O&M Manual.pdf" --format xlsx -f json -f txt
148
151
 
149
152
  # Show the GUI for only a moment, like in a build check
150
153
  pdflinkcheck gui --auto-close 3000
@@ -177,8 +180,8 @@ from pdflinkcheck import ( run_report,
177
180
 
178
181
  file = "document1.pdf"
179
182
  report_data = run_report(file)
180
- links_pymupdf = extract_links_pymupdf(file)
181
- links_pypdf = extract_links_pypdf(file)
183
+ links_pdfium = analyze_pdf_pdfium(file)
184
+ links_pypdf = analyze_pdf_pypdf(file)
182
185
  ```
183
186
 
184
187
  -----
@@ -254,7 +257,7 @@ Expecte that all binaries and artifacts contain PyMuPDF, unlss they are built on
254
257
  To install the complete version use one of these options:
255
258
 
256
259
  ```bash
257
- pip install "pdflinkcheck[mupdf]"
260
+ pip install "pdflinkcheck[pymupdf]"
258
261
  pipx install "pdflinkcheck[pdfium]"
259
262
  uv tool install "pdflinkcheck[pdfium]"
260
263
  uv add "pdflinkcheck[pdfium]"
@@ -279,12 +282,12 @@ git clone http://github.com/city-of-memphis-wastewater/pdflinkcheck.git
279
282
  cd pdflinkcheck
280
283
 
281
284
  # To include the PyMuPDF dependency in the installation:
282
- uv sync --extras full
285
+ uv sync --extras pdfium --extra pymupdf
283
286
 
284
287
  # On Termux, to not include PyMuPDF:
285
- uv sync
288
+ uv sync --extra pdfium
286
289
 
287
- # To include developer depedecies:
290
+ # To include developer dependencies:
288
291
  uv sync --all-extras --group dev
289
292
 
290
293
  # Run the CLI
@@ -2,9 +2,11 @@
2
2
 
3
3
  A purpose-built tool for comprehensive analysis of hyperlinks and GoTo links within PDF documents. Users may leverage either the PyMuPDF or the pypdf library. Use the CLI or the GUI.
4
4
 
5
+ [![Get it from the Microsoft Store](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/ms_store_badge_en-us-light.svg)](https://apps.microsoft.com/store/detail/9n11hxvls1wg)
6
+
5
7
  -----
6
8
 
7
- ![Screenshot of the pdflinkcheck GUI](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_gui_v1.1.97.png)
9
+ ![Screenshot of the pdflinkcheck GUI](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_gui_v1.3.3.png)
8
10
 
9
11
  -----
10
12
 
@@ -53,7 +55,7 @@ Ways to launch the GUI interface:
53
55
  The core functionality is accessed via the `analyze` command.
54
56
 
55
57
  `pdflinkcheck --help`:
56
- ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.1.97.png)
58
+ ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.3.3.png)
57
59
 
58
60
 
59
61
  See the Help Tree by unlocking the help-tree CLI command, using the DEV_TYPER_HELP_TREE env var.
@@ -63,7 +65,7 @@ DEV_TYPER_HELP_TREE=1 pdflinkcheck help-tree` # bash
63
65
  $env:DEV_TYPER_HELP_TREE = "1"; pdflinkcheck help-tree` # PowerShell
64
66
  ```
65
67
 
66
- ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.1.97_tree_help.png)
68
+ ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.3.3_tree_help.png)
67
69
 
68
70
 
69
71
 
@@ -83,7 +85,7 @@ $env:DEV_TYPER_HELP_TREE = "1"; pdflinkcheck help-tree` # PowerShell
83
85
  |---|---|---|
84
86
  |`<PDF_PATH>`|**Required.** The path to the PDF file to analyze.|N/A|
85
87
  |`--pdf-library / -p`|Select engine: `pymupdf` or `pypdf`.|`pypdf`|
86
- |`--export-format / -e`|Export to `JSON`, `TXT`, or `None` to suppress file output.|`JSON`|
88
+ |`--format / -f`|Export to `JSON`, `TXT`, `XLSX`, and/or `None` to suppress file output.|`JSON`|
87
89
 
88
90
  ### `gui` Command Options
89
91
 
@@ -94,8 +96,8 @@ $env:DEV_TYPER_HELP_TREE = "1"; pdflinkcheck help-tree` # PowerShell
94
96
  #### Example Runs
95
97
 
96
98
  ```bash
97
- # Analyze a document, show all links, and save the report as JSON and TXT
98
- pdflinkcheck analyze "TE Maxson WWTF O&M Manual.pdf" --export-format JSON,TXT
99
+ # Analyze a document, show all links, and save the report as XLSX, JSON, and TXT
100
+ pdflinkcheck analyze "TE Maxson WWTF O&M Manual.pdf" --format xlsx -f json -f txt
99
101
 
100
102
  # Show the GUI for only a moment, like in a build check
101
103
  pdflinkcheck gui --auto-close 3000
@@ -128,8 +130,8 @@ from pdflinkcheck import ( run_report,
128
130
 
129
131
  file = "document1.pdf"
130
132
  report_data = run_report(file)
131
- links_pymupdf = extract_links_pymupdf(file)
132
- links_pypdf = extract_links_pypdf(file)
133
+ links_pdfium = analyze_pdf_pdfium(file)
134
+ links_pypdf = analyze_pdf_pypdf(file)
133
135
  ```
134
136
 
135
137
  -----
@@ -205,7 +207,7 @@ Expecte that all binaries and artifacts contain PyMuPDF, unlss they are built on
205
207
  To install the complete version use one of these options:
206
208
 
207
209
  ```bash
208
- pip install "pdflinkcheck[mupdf]"
210
+ pip install "pdflinkcheck[pymupdf]"
209
211
  pipx install "pdflinkcheck[pdfium]"
210
212
  uv tool install "pdflinkcheck[pdfium]"
211
213
  uv add "pdflinkcheck[pdfium]"
@@ -230,12 +232,12 @@ git clone http://github.com/city-of-memphis-wastewater/pdflinkcheck.git
230
232
  cd pdflinkcheck
231
233
 
232
234
  # To include the PyMuPDF dependency in the installation:
233
- uv sync --extras full
235
+ uv sync --extras pdfium --extra pymupdf
234
236
 
235
237
  # On Termux, to not include PyMuPDF:
236
- uv sync
238
+ uv sync --extra pdfium
237
239
 
238
- # To include developer depedecies:
240
+ # To include developer dependencies:
239
241
  uv sync --all-extras --group dev
240
242
 
241
243
  # Run the CLI
@@ -1,11 +1,12 @@
1
1
  [project]
2
2
  name = "pdflinkcheck"
3
- version = "1.2.29"
3
+ version = "1.3.8"
4
4
  description = "A purpose-built PDF link analysis and reporting tool with GUI and CLI."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
7
7
  dependencies = [
8
- "pyhabitat>=1.1.5",
8
+ "openpyxl>=3.1.5",
9
+ "pyhabitat>=1.1.6",
9
10
  "pypdf>=6.4.2",
10
11
  "rich>=14.2.0",
11
12
  "typer>=0.20.0",
@@ -56,7 +57,7 @@ pdflinkcheck = "pdflinkcheck.cli:app"
56
57
 
57
58
  [project.optional-dependencies]
58
59
  # If you choose to include PyMuPDF, you must comply with the AGPL3
59
- mupdf = ["pymupdf>=1.24.0,<2.0.0"] # fails on termux
60
+ pymupdf = ["pymupdf>=1.24.0,<2.0.0"] # fails on termux
60
61
  pdfium = ["pypdfium2>=5.2.0,<6.0.0"]
61
62
  full = ["pymupdf>=1.24.0,<2.0.0", "pypdfium2>=5.2.0,<6.0.0"]
62
63
 
@@ -49,7 +49,7 @@ def analyze_pdf_pymupdf(path):
49
49
  except ImportError:
50
50
  raise ImportError(
51
51
  "PyMuPDF engine is not installed. "
52
- "Install with the [mupdf] extra to enable PyMuPDF support."
52
+ "Install with the [pymupdf] extra to enable PyMuPDF support."
53
53
  )
54
54
  return _analyze(path)
55
55
  analyze_pdf_pymupdf.__doc__ = (
@@ -3,7 +3,7 @@
3
3
  # src/pdflinkcheck/cli.py
4
4
  from __future__ import annotations
5
5
  import typer
6
- from typing import Literal
6
+ from typing import Literal, List
7
7
  from typer.models import OptionInfo
8
8
  from rich.console import Console
9
9
  from pathlib import Path
@@ -13,10 +13,10 @@ import pyhabitat
13
13
  import sys
14
14
  import os
15
15
  from importlib.resources import files
16
+ from enum import Enum
16
17
 
17
18
  from pdflinkcheck.version_info import get_version_from_pyproject
18
- from pdflinkcheck.validate import run_validation
19
- from pdflinkcheck.environment import is_in_git_repo, assess_default_pdf_library
19
+ from pdflinkcheck.environment import is_in_git_repo, assess_default_pdf_library, pymupdf_is_available, pdfium_is_available
20
20
  from pdflinkcheck.io import get_first_pdf_in_cwd
21
21
 
22
22
  console = Console() # to be above the tkinter check, in case of console.print
@@ -37,6 +37,13 @@ app = typer.Typer(
37
37
  "help_option_names": ["-h", "--help"]},
38
38
  )
39
39
 
40
+ class ExportFormat(str, Enum):
41
+ json = "json"
42
+ txt = "txt"
43
+ xlsx = "xlsx"
44
+ none = "none"
45
+
46
+ ALLOWED_EXPORTS = {"json", "txt", "xlsx", "none"}
40
47
 
41
48
  def debug_callback(value: bool):
42
49
  #def debug_callback(ctx: typer.Context, value: bool):
@@ -50,8 +57,36 @@ def debug_callback(value: bool):
50
57
  typer.echo(f"command:\n{command_string}\n")
51
58
  return value
52
59
 
53
- if "--show-command" in sys.argv or "--debug" in sys.argv:
60
+ if "--show-command" in sys.argv or "--debug" in sys.argv: # requires that --show-command flag be used before the sub command
54
61
  debug_callback(True)
62
+
63
+
64
+
65
+ def _parse_export_formats(value: str) -> List[str]:
66
+ """
67
+ Parse a comma-separated string of export formats, validate allowed values.
68
+ Converts everything to lowercase.
69
+ """
70
+ if not value:
71
+ return []
72
+
73
+ # Split by comma and normalize
74
+ parts = [v.strip().lower() for v in value.split(",")]
75
+
76
+ # Validate
77
+ invalid = [v for v in parts if v not in ALLOWED_EXPORTS]
78
+ if invalid:
79
+ raise typer.BadParameter(
80
+ f"Invalid export format(s): {', '.join(invalid)}. "
81
+ f"Allowed values: {', '.join(sorted(ALLOWED_EXPORTS))}"
82
+ )
83
+
84
+ # If 'none' is included, return empty list to suppress exports
85
+ if "none" in parts:
86
+ return []
87
+
88
+ return parts
89
+
55
90
 
56
91
  @app.callback()
57
92
  def main(ctx: typer.Context,
@@ -136,8 +171,8 @@ def docs_command(
136
171
 
137
172
  # Exit successfully if any flag was processed
138
173
  raise typer.Exit(code=0)
139
-
140
- @app.command(name="tools", help= "Additional features, hamburger menu.")
174
+ """
175
+ @app.command(name="tools_defunct", help= "Additional features, hamburger menu.")
141
176
  def tools_command(
142
177
  clear_cache: bool = typer.Option(
143
178
  False,
@@ -149,6 +184,34 @@ def tools_command(
149
184
  from pdflinkcheck.environment import clear_all_caches
150
185
  if clear_cache:
151
186
  clear_all_caches()
187
+ """
188
+ # Create the sub-group
189
+ tools_app = typer.Typer(help="Additional utility features and maintenance tools.")
190
+ app.add_typer(tools_app, name="tools")
191
+
192
+ @tools_app.command(name="clear-cache")
193
+ def tools_clear_cache():
194
+ """Clear the environment and engine discovery caches."""
195
+ from pdflinkcheck.environment import clear_all_caches
196
+ clear_all_caches()
197
+ console.print("[green]Discovery caches cleared.[/green]")
198
+ console.print(f"pymupdf_is_available: {pymupdf_is_available()}")
199
+ console.print(f"pymupdf_is_available: {pdfium_is_available()}")
200
+
201
+
202
+ @tools_app.command(name="browse-exports")
203
+ def tools_browse_exports():
204
+ """Open the system file explorer at the report output directory."""
205
+ from pdflinkcheck.helpers import show_system_explorer, get_export_path
206
+
207
+ target_dir = get_export_path()
208
+ console.print(f"Opening: [bold cyan]{target_dir}[/bold cyan]")
209
+
210
+ try:
211
+ show_system_explorer()
212
+ except Exception as e:
213
+ console.print(f"[bold red]Error:[/bold red] {e}")
214
+ raise typer.Exit(code=1)
152
215
 
153
216
  @app.command(name="analyze") # Added a command name 'analyze' for clarity
154
217
  def analyze_pdf( # Renamed function for clarity
@@ -161,11 +224,25 @@ def analyze_pdf( # Renamed function for clarity
161
224
  resolve_path=True,
162
225
  help="Path to the PDF file to analyze. If omitted, searches current directory."
163
226
  ),
164
- export_format: Optional[Literal["JSON", "TXT", "JSON,TXT", "NONE"]] = typer.Option(
165
- "JSON,TXT",
166
- "--format","-f",
167
- case_sensitive=False,
168
- help="Export format. Use 'None' to suppress file export.",
227
+ #export_format: Optional[Literal["JSON", "TXT", "XLSX", "JSON,TXT,XLSX", "NONE"]] = typer.Option(
228
+ #export_format: str = typer.Option(
229
+ # "json,txt,xlsx",
230
+ # "--format","-f",
231
+ # case_sensitive=False,
232
+ # help="Export format. Use 'None' to suppress file export.",
233
+ #),
234
+ #export_format: List[str] = typer.Option(
235
+ # ["json", "txt", "xlsx"],
236
+ # "--format", "-f",
237
+ # case_sensitive=False,
238
+ # callback=_parse_export_formats,
239
+ # help="Comma-separated list of export formats. Allowed: json, txt, xlsx, none."
240
+ #),
241
+ export_format: List[ExportFormat] = typer.Option(
242
+ [ExportFormat.json, ExportFormat.txt, ExportFormat.xlsx],
243
+ "--format", "-f",
244
+ case_sensitive=False,
245
+ help="Export formats (repeatable). Use --format none to suppress all exports."
169
246
  ),
170
247
 
171
248
  pdf_library: Literal["auto","pdfium","pypdf", "pymupdf"] = typer.Option(
@@ -213,44 +290,49 @@ def analyze_pdf( # Renamed function for clarity
213
290
  raise typer.Exit(code=1)
214
291
  console.print(f"[dim]No file specified — using: {Path(pdf_path).name}[/dim]")
215
292
 
216
- pdf_path_str = str(pdf_path)
217
-
218
- VALID_FORMATS = ("JSON") # extend later
293
+
294
+ if ExportFormat.none in export_format:
295
+ export_formats = []
296
+ else:
297
+ export_formats = [f.name.upper() for f in export_format]
298
+ export_format="".join(export_formats)
299
+ """#VALID_FORMATS = ("JSON","TXT") # extend later
219
300
  requested_formats = [fmt.strip().upper() for fmt in export_format.split(",")]
220
301
  if "NONE" in requested_formats or not export_format.strip() or export_format == "0":
221
302
  export_formats = ""
222
303
  else:
223
304
  # Filter for valid ones: ("JSON", "TXT")
224
305
  # This allows "JSON,TXT" to become "JSONTXT" which run_report logic can handle
225
- valid = [f for f in requested_formats if f in ("JSON", "TXT")]
306
+ valid = [f for f in requested_formats if f in ("JSON", "TXT", "XLSX")]
226
307
  export_formats = "".join(valid)
227
308
 
228
309
  if not valid and "NONE" not in requested_formats:
229
310
  typer.echo(f"Warning: No valid formats found in '{export_format}'. Supported: JSON, TXT.")
230
-
311
+ """
231
312
 
232
313
  # The meat and potatoes
233
314
  report_results = run_report_and_call_exports(
234
315
  pdf_path=str(pdf_path),
235
- export_format = export_formats,
316
+ export_format = export_format,
236
317
  pdf_library = pdf_library,
237
318
  print_bool = print_bool,
319
+ concise_print = True, # ideal for CLI, to not overwhelm the terminal.
238
320
  )
239
321
 
240
322
  if not report_results or not report_results.get("data"):
241
323
  console.print("[yellow]No links or TOC found — nothing to validate.[/yellow]")
242
324
  raise typer.Exit(code=0)
243
325
 
244
- validation_results = report_results["data"]["validation"]
326
+ #validation_results = report_results["data"]["validation"]
245
327
  # Optional: fail on broken links
246
- broken_page_count = validation_results["summary-stats"]["broken-page"] + validation_results["summary-stats"]["broken-file"]
328
+ #broken_page_count = validation_results["summary-stats"]["broken-page"] + validation_results["summary-stats"]["broken-file"]
247
329
 
248
- if broken_page_count > 0:
330
+ #if broken_page_count > 0:
249
331
  console.print(f"\n[bold yellow]Warning:[/bold yellow] {broken_page_count} broken link(s) found.")
250
332
  #else:
251
333
  # console.print(f"\n[bold green]Success:[/bold green] No broken links or TOC issues!\n")
252
334
 
253
- raise typer.Exit(code=0 if broken_page_count == 0 else 1)
335
+ #raise typer.Exit(code=0 if broken_page_count == 0 else 1)
254
336
 
255
337
  @app.command(name="serve")
256
338
  def serve(
@@ -270,13 +352,14 @@ def serve(
270
352
  console.print(" → [yellow]Reload mode enabled[/yellow]")
271
353
 
272
354
  # Import here to avoid slow imports on other commands
273
- from pdflinkcheck.stdlib_server_alt import ThreadedTCPServer, PDFLinkCheckHandler
355
+ from pdflinkcheck.stdlib_server import main as stdlib_server_main# ThreadedHTTPServer, PDFLinkCheckHandler
274
356
  import socketserver
275
357
 
276
358
  try:
277
- with ThreadedTCPServer((host, port), PDFLinkCheckHandler) as httpd:
278
- console.print(f"[green]Server running press Ctrl+C to stop[/green]\n")
279
- httpd.serve_forever()
359
+ stdlib_server_main()
360
+ #with ThreadedTCPServer((host, port), PDFLinkCheckHandler) as httpd:
361
+ # console.print(f"[green]Server running — press Ctrl+C to stop[/green]\n")
362
+ # httpd.serve_forever()
280
363
  except OSError as e:
281
364
  if "Address already in use" in str(e):
282
365
  console.print(f"[red]Error: Port {port} is already in use.[/red]")
@@ -314,8 +397,7 @@ def gui_command(
314
397
  if not pyhabitat.tkinter_is_available():
315
398
  _gui_failure_msg()
316
399
  return
317
- #from pdflinkcheck.gui import start_gui
318
- #from pdflinkcheck.gui_alt import start_gui
400
+
319
401
  from pdflinkcheck.gui import start_gui
320
402
  start_gui(time_auto_close = assured_auto_close_value)
321
403
 
@@ -329,6 +411,8 @@ def _gui_failure_msg():
329
411
  console.print(f"pyhabitat.tkinter_is_available() = {pyhabitat.tkinter_is_available()}")
330
412
  pass
331
413
 
414
+
415
+
332
416
  if __name__ == "__main__":
333
417
  app()
334
418
 
@@ -2,11 +2,11 @@ Some distributed binaries of this project include the PyMuPDF library, which is
2
2
  Any binary that incorporates PyMuPDF is therefore distributed under **AGPL3.0orlater**.
3
3
  Other binaries use only the `pypdf` library and do not include PyMuPDF; these binaries are distributed under the **MIT License**.
4
4
 
5
- For AGPLlicensed binaries, the complete corresponding source code must be made available to anyone who possesses a copy, upon request.
5
+ For AGPL-licensed binaries, the complete corresponding source code must be made available to anyone who possesses a copy, upon request.
6
6
  This obligation applies only to recipients of those binaries, and hosting the source code in GitHub Releases satisfies this requirement.
7
7
 
8
- A binary becomes AGPLlicensed only when built with the optional `"full"` dependency group (as defined in `pyproject.toml` under `[project.optional-dependencies]`) or when PyMuPDF is otherwise included in the build environment.
9
- The **source code of pdflinkcheck itself** remains licensed under the **MIT License**; only the distributed binary becomes AGPLlicensed when PyMuPDF is included.
8
+ A binary becomes AGPL-licensed only when built with the optional `"full"` dependency group (as defined in `pyproject.toml` under `[project.optional-dependencies]`) or when PyMuPDF is otherwise included in the build environment.
9
+ The **source code of pdflinkcheck itself** remains licensed under the **MIT License**. Only a distributed binary (or a publicly served web app) becomes AGPL-licensed when PyMuPDF is included.
10
10
 
11
11
  Source code for each released version is available in the `pdflinkcheckVERSION.tar.gz` files on the projects GitHub Releases page.
12
12
 
@@ -2,9 +2,11 @@
2
2
 
3
3
  A purpose-built tool for comprehensive analysis of hyperlinks and GoTo links within PDF documents. Users may leverage either the PyMuPDF or the pypdf library. Use the CLI or the GUI.
4
4
 
5
+ [![Get it from the Microsoft Store](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/ms_store_badge_en-us-light.svg)](https://apps.microsoft.com/store/detail/9n11hxvls1wg)
6
+
5
7
  -----
6
8
 
7
- ![Screenshot of the pdflinkcheck GUI](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_gui_v1.1.97.png)
9
+ ![Screenshot of the pdflinkcheck GUI](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_gui_v1.3.3.png)
8
10
 
9
11
  -----
10
12
 
@@ -53,7 +55,7 @@ Ways to launch the GUI interface:
53
55
  The core functionality is accessed via the `analyze` command.
54
56
 
55
57
  `pdflinkcheck --help`:
56
- ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.1.97.png)
58
+ ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.3.3.png)
57
59
 
58
60
 
59
61
  See the Help Tree by unlocking the help-tree CLI command, using the DEV_TYPER_HELP_TREE env var.
@@ -63,7 +65,7 @@ DEV_TYPER_HELP_TREE=1 pdflinkcheck help-tree` # bash
63
65
  $env:DEV_TYPER_HELP_TREE = "1"; pdflinkcheck help-tree` # PowerShell
64
66
  ```
65
67
 
66
- ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.1.97_tree_help.png)
68
+ ![Screenshot of the pdflinkcheck CLI Tree Help](https://raw.githubusercontent.com/City-of-Memphis-Wastewater/pdflinkcheck/main/assets/pdflinkcheck_cli_v1.3.3_tree_help.png)
67
69
 
68
70
 
69
71
 
@@ -83,7 +85,7 @@ $env:DEV_TYPER_HELP_TREE = "1"; pdflinkcheck help-tree` # PowerShell
83
85
  |---|---|---|
84
86
  |`<PDF_PATH>`|**Required.** The path to the PDF file to analyze.|N/A|
85
87
  |`--pdf-library / -p`|Select engine: `pymupdf` or `pypdf`.|`pypdf`|
86
- |`--export-format / -e`|Export to `JSON`, `TXT`, or `None` to suppress file output.|`JSON`|
88
+ |`--format / -f`|Export to `JSON`, `TXT`, `XLSX`, and/or `None` to suppress file output.|`JSON`|
87
89
 
88
90
  ### `gui` Command Options
89
91
 
@@ -94,8 +96,8 @@ $env:DEV_TYPER_HELP_TREE = "1"; pdflinkcheck help-tree` # PowerShell
94
96
  #### Example Runs
95
97
 
96
98
  ```bash
97
- # Analyze a document, show all links, and save the report as JSON and TXT
98
- pdflinkcheck analyze "TE Maxson WWTF O&M Manual.pdf" --export-format JSON,TXT
99
+ # Analyze a document, show all links, and save the report as XLSX, JSON, and TXT
100
+ pdflinkcheck analyze "TE Maxson WWTF O&M Manual.pdf" --format xlsx -f json -f txt
99
101
 
100
102
  # Show the GUI for only a moment, like in a build check
101
103
  pdflinkcheck gui --auto-close 3000
@@ -128,8 +130,8 @@ from pdflinkcheck import ( run_report,
128
130
 
129
131
  file = "document1.pdf"
130
132
  report_data = run_report(file)
131
- links_pymupdf = extract_links_pymupdf(file)
132
- links_pypdf = extract_links_pypdf(file)
133
+ links_pdfium = analyze_pdf_pdfium(file)
134
+ links_pypdf = analyze_pdf_pypdf(file)
133
135
  ```
134
136
 
135
137
  -----
@@ -205,7 +207,7 @@ Expecte that all binaries and artifacts contain PyMuPDF, unlss they are built on
205
207
  To install the complete version use one of these options:
206
208
 
207
209
  ```bash
208
- pip install "pdflinkcheck[mupdf]"
210
+ pip install "pdflinkcheck[pymupdf]"
209
211
  pipx install "pdflinkcheck[pdfium]"
210
212
  uv tool install "pdflinkcheck[pdfium]"
211
213
  uv add "pdflinkcheck[pdfium]"
@@ -230,12 +232,12 @@ git clone http://github.com/city-of-memphis-wastewater/pdflinkcheck.git
230
232
  cd pdflinkcheck
231
233
 
232
234
  # To include the PyMuPDF dependency in the installation:
233
- uv sync --extras full
235
+ uv sync --extras pdfium --extra pymupdf
234
236
 
235
237
  # On Termux, to not include PyMuPDF:
236
- uv sync
238
+ uv sync --extra pdfium
237
239
 
238
- # To include developer depedecies:
240
+ # To include developer dependencies:
239
241
  uv sync --all-extras --group dev
240
242
 
241
243
  # Run the CLI
@@ -1,11 +1,12 @@
1
1
  [project]
2
2
  name = "pdflinkcheck"
3
- version = "1.2.29"
3
+ version = "1.3.8"
4
4
  description = "A purpose-built PDF link analysis and reporting tool with GUI and CLI."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
7
7
  dependencies = [
8
- "pyhabitat>=1.1.5",
8
+ "openpyxl>=3.1.5",
9
+ "pyhabitat>=1.1.6",
9
10
  "pypdf>=6.4.2",
10
11
  "rich>=14.2.0",
11
12
  "typer>=0.20.0",
@@ -56,7 +57,7 @@ pdflinkcheck = "pdflinkcheck.cli:app"
56
57
 
57
58
  [project.optional-dependencies]
58
59
  # If you choose to include PyMuPDF, you must comply with the AGPL3
59
- mupdf = ["pymupdf>=1.24.0,<2.0.0"] # fails on termux
60
+ pymupdf = ["pymupdf>=1.24.0,<2.0.0"] # fails on termux
60
61
  pdfium = ["pypdfium2>=5.2.0,<6.0.0"]
61
62
  full = ["pymupdf>=1.24.0,<2.0.0", "pypdfium2>=5.2.0,<6.0.0"]
62
63