rxiv-maker 1.16.5__tar.gz → 1.16.7__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 (398) hide show
  1. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/.gitignore +2 -3
  2. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/CHANGELOG.md +31 -0
  3. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/PKG-INFO +10 -5
  4. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/README.md +8 -3
  5. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/pyproject.toml +1 -1
  6. rxiv_maker-1.16.7/src/docs/api/README.md +4 -0
  7. rxiv_maker-1.16.7/src/docs/api/index.md +4 -0
  8. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/__version__.py +1 -1
  9. rxiv_maker-1.16.7/src/rxiv_maker/cli/commands/upgrade.py +52 -0
  10. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/framework/utility_commands.py +5 -2
  11. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/generate_figures.py +146 -18
  12. rxiv_maker-1.16.7/src/rxiv_maker/utils/rich_upgrade_notifier.py +162 -0
  13. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/syntax_validator.py +13 -4
  14. rxiv_maker-1.16.7/tests/unit/test_rich_upgrade_notifier.py +206 -0
  15. rxiv_maker-1.16.7/tests/unit/test_upgrade_command.py +134 -0
  16. rxiv_maker-1.16.5/src/docs/api/README.md +0 -28
  17. rxiv_maker-1.16.5/src/docs/api/__version__.py.md +0 -9
  18. rxiv_maker-1.16.5/src/docs/api/author_name_formatter.py.md +0 -165
  19. rxiv_maker-1.16.5/src/docs/api/bibliography_parser.py.md +0 -123
  20. rxiv_maker-1.16.5/src/docs/api/cache_utils.py.md +0 -150
  21. rxiv_maker-1.16.5/src/docs/api/changelog_parser.py.md +0 -260
  22. rxiv_maker-1.16.5/src/docs/api/citation_utils.py.md +0 -78
  23. rxiv_maker-1.16.5/src/docs/api/email_encoder.py.md +0 -126
  24. rxiv_maker-1.16.5/src/docs/api/error_codes.py.md +0 -49
  25. rxiv_maker-1.16.5/src/docs/api/figure_utils.py.md +0 -253
  26. rxiv_maker-1.16.5/src/docs/api/github.py.md +0 -312
  27. rxiv_maker-1.16.5/src/docs/api/homebrew_checker.py.md +0 -99
  28. rxiv_maker-1.16.5/src/docs/api/index.md +0 -28
  29. rxiv_maker-1.16.5/src/docs/api/install_detector.py.md +0 -81
  30. rxiv_maker-1.16.5/src/docs/api/logging_config.py.md +0 -371
  31. rxiv_maker-1.16.5/src/docs/api/operation_ids.py.md +0 -218
  32. rxiv_maker-1.16.5/src/docs/api/platform.py.md +0 -527
  33. rxiv_maker-1.16.5/src/docs/api/python_execution_reporter.py.md +0 -302
  34. rxiv_maker-1.16.5/src/docs/api/text_utils.py.md +0 -71
  35. rxiv_maker-1.16.5/src/docs/api/unicode_safe.py.md +0 -230
  36. rxiv_maker-1.16.5/src/docs/api/url_to_doi.py.md +0 -80
  37. rxiv_maker-1.16.5/src/docs/api/validate.py.md +0 -142
  38. rxiv_maker-1.16.5/src/rxiv_maker/cli/commands/upgrade.py +0 -164
  39. rxiv_maker-1.16.5/tests/unit/test_upgrade_command.py +0 -193
  40. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/LICENSE +0 -0
  41. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/logo/logo-rxiv-maker.afdesign +0 -0
  42. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/logo/logo-rxiv-maker.png +0 -0
  43. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/logo/logo-rxiv-maker.svg +0 -0
  44. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/__init__.py +0 -0
  45. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/__init__.py +0 -0
  46. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/__main__.py +0 -0
  47. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/__init__.py +0 -0
  48. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/arxiv.py +0 -0
  49. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/bibliography.py +0 -0
  50. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/build.py +0 -0
  51. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/cache_management.py +0 -0
  52. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/changelog.py +0 -0
  53. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/check_installation.py +0 -0
  54. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/clean.py +0 -0
  55. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/completion.py +0 -0
  56. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/config.py +0 -0
  57. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/create_repo.py +0 -0
  58. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/docx.py +0 -0
  59. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/figures.py +0 -0
  60. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/get_rxiv_preprint.py +0 -0
  61. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/init.py +0 -0
  62. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/install_deps.py +0 -0
  63. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/repo_init.py +0 -0
  64. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/repos.py +0 -0
  65. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/repos_search.py +0 -0
  66. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/setup.py +0 -0
  67. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/track_changes.py +0 -0
  68. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/validate.py +0 -0
  69. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/commands/version.py +0 -0
  70. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/framework/__init__.py +0 -0
  71. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/framework/base.py +0 -0
  72. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/framework/cache_commands.py +0 -0
  73. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/framework/config_commands.py +0 -0
  74. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/framework/content_commands.py +0 -0
  75. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/framework/decorators.py +0 -0
  76. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/framework/workflow_commands.py +0 -0
  77. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/framework.py +0 -0
  78. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/interactive.py +0 -0
  79. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/interactive_prompts.py +0 -0
  80. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/cli/main.py +0 -0
  81. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/config/defaults.py +0 -0
  82. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/config/validator.py +0 -0
  83. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/__init__.py +0 -0
  84. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/citation_processor.py +0 -0
  85. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/code_processor.py +0 -0
  86. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/comment_processor.py +0 -0
  87. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/custom_command_processor.py +0 -0
  88. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/figure_processor.py +0 -0
  89. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/html_processor.py +0 -0
  90. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/list_processor.py +0 -0
  91. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/math_processor.py +0 -0
  92. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/md2tex.py +0 -0
  93. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/python_executor.py +0 -0
  94. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/section_processor.py +0 -0
  95. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/supplementary_note_processor.py +0 -0
  96. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/table_processor.py +0 -0
  97. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/text_formatters.py +0 -0
  98. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/types.py +0 -0
  99. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/converters/url_processor.py +0 -0
  100. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/cache/__init__.py +0 -0
  101. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/cache/advanced_cache.py +0 -0
  102. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/cache/bibliography_cache.py +0 -0
  103. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/cache/cache_utils.py +0 -0
  104. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/cache/doi_cache.py +0 -0
  105. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/cache/secure_cache_utils.py +0 -0
  106. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/content_processor.py +0 -0
  107. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/environment_bootstrap.py +0 -0
  108. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/environment_manager.py +0 -0
  109. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/error_codes.py +0 -0
  110. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/error_recovery.py +0 -0
  111. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/logging_config.py +0 -0
  112. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/__init__.py +0 -0
  113. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/cache_manager.py +0 -0
  114. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/config_manager.py +0 -0
  115. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/dependency_manager.py +0 -0
  116. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/execution_manager.py +0 -0
  117. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/file_manager.py +0 -0
  118. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/install_manager.py +0 -0
  119. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/state_manager.py +0 -0
  120. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/unified_config_manager.py +0 -0
  121. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/validation_manager.py +0 -0
  122. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/managers/workflow_manager.py +0 -0
  123. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/path_manager.py +0 -0
  124. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/progress_framework.py +0 -0
  125. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/repo_config.py +0 -0
  126. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/repository.py +0 -0
  127. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/session_optimizer.py +0 -0
  128. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/core/validation_framework.py +0 -0
  129. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/data/tips.yaml +0 -0
  130. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/__init__.py +0 -0
  131. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/__init__.py +0 -0
  132. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/add_bibliography.py +0 -0
  133. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/build_manager.py +0 -0
  134. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/cleanup.py +0 -0
  135. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/fix_bibliography.py +0 -0
  136. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/generate_docs.py +0 -0
  137. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/generate_preprint.py +0 -0
  138. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/prepare_arxiv.py +0 -0
  139. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/setup_environment.py +0 -0
  140. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/track_changes.py +0 -0
  141. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/validate.py +0 -0
  142. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/engines/operations/validate_pdf.py +0 -0
  143. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/exporters/__init__.py +0 -0
  144. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/exporters/docx_citation_mapper.py +0 -0
  145. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/exporters/docx_content_processor.py +0 -0
  146. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/exporters/docx_exporter.py +0 -0
  147. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/exporters/docx_writer.py +0 -0
  148. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/__init__.py +0 -0
  149. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/dependency_handlers/__init__.py +0 -0
  150. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/dependency_handlers/latex.py +0 -0
  151. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/dependency_handlers/r_lang.py +0 -0
  152. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/dependency_handlers/system_libs.py +0 -0
  153. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/platform_installers/__init__.py +0 -0
  154. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/platform_installers/base.py +0 -0
  155. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/platform_installers/linux.py +0 -0
  156. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/platform_installers/macos.py +0 -0
  157. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/platform_installers/windows.py +0 -0
  158. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/utils/__init__.py +0 -0
  159. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/utils/logging.py +0 -0
  160. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/utils/progress.py +0 -0
  161. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/install/utils/verification.py +0 -0
  162. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/manuscript_utils/__init__.py +0 -0
  163. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/manuscript_utils/figure_utils.py +0 -0
  164. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/processors/__init__.py +0 -0
  165. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/processors/author_processor.py +0 -0
  166. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/processors/markdown_preprocessor.py +0 -0
  167. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/processors/template_processor.py +0 -0
  168. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/processors/yaml_processor.py +0 -0
  169. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/rxiv_maker_cli.py +0 -0
  170. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/scripts/__init__.py +0 -0
  171. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/scripts/custom_doc_generator.py +0 -0
  172. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/scripts/validate_manuscript.py +0 -0
  173. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/services/__init__.py +0 -0
  174. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/services/base.py +0 -0
  175. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/services/build_service.py +0 -0
  176. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/services/configuration_service.py +0 -0
  177. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/services/manuscript_service.py +0 -0
  178. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/services/publication_service.py +0 -0
  179. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/services/validation_service.py +0 -0
  180. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/templates/__init__.py +0 -0
  181. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/templates/manager.py +0 -0
  182. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/templates/registry.py +0 -0
  183. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/tex/python_execution_section.tex +0 -0
  184. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/__init__.py +0 -0
  185. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/author_name_formatter.py +0 -0
  186. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/bibliography_checksum.py +0 -0
  187. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/bibliography_parser.py +0 -0
  188. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/bst_generator.py +0 -0
  189. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/changelog_parser.py +0 -0
  190. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/citation_utils.py +0 -0
  191. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/dependency_checker.py +0 -0
  192. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/docx_helpers.py +0 -0
  193. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/doi_resolver.py +0 -0
  194. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/email_encoder.py +0 -0
  195. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/figure_checksum.py +0 -0
  196. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/file_helpers.py +0 -0
  197. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/github.py +0 -0
  198. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/homebrew_checker.py +0 -0
  199. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/install_detector.py +0 -0
  200. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/operation_ids.py +0 -0
  201. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/pdf_utils.py +0 -0
  202. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/performance.py +0 -0
  203. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/platform.py +0 -0
  204. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/python_execution_reporter.py +0 -0
  205. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/retry.py +0 -0
  206. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/text_utils.py +0 -0
  207. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/tips.py +0 -0
  208. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/title_sync.py +0 -0
  209. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/unicode_safe.py +0 -0
  210. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/update_checker.py +0 -0
  211. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/utils/url_to_doi.py +0 -0
  212. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validate.py +0 -0
  213. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/__init__.py +0 -0
  214. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/base_validator.py +0 -0
  215. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/citation_validator.py +0 -0
  216. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/doi/__init__.py +0 -0
  217. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/doi/api_clients.py +0 -0
  218. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/doi/metadata_comparator.py +0 -0
  219. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/doi_validator.py +0 -0
  220. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/figure_validator.py +0 -0
  221. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/latex_error_parser.py +0 -0
  222. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/math_validator.py +0 -0
  223. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/pdf_validator.py +0 -0
  224. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/rxiv_maker/validators/reference_validator.py +0 -0
  225. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/tex/style/rxiv_maker_style.bst +0 -0
  226. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/tex/style/rxiv_maker_style.cls +0 -0
  227. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/src/tex/template.tex +0 -0
  228. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/__init__.py +0 -0
  229. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/cli/__init__.py +0 -0
  230. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/cli/test_build.py +0 -0
  231. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/cli/test_changelog_command.py +0 -0
  232. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/cli/test_init_command.py +0 -0
  233. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/cli/test_main.py +0 -0
  234. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/conftest.py +0 -0
  235. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/e2e/__init__.py +0 -0
  236. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/e2e/test_dummy_manuscript_generator.py +0 -0
  237. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/e2e/test_figure_workflow_validation.py +0 -0
  238. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/00_CONFIG.yml +0 -0
  239. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/01_MAIN.md +0 -0
  240. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/03_REFERENCES.bib +0 -0
  241. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/FIGURES/Fig1.png +0 -0
  242. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/FIGURES/Fig2.png +0 -0
  243. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/FIGURES/Fig3.png +0 -0
  244. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/README.md +0 -0
  245. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/docx_export/sample_manuscript/01_MAIN.md +0 -0
  246. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/docx_export/sample_manuscript/02_SUPPLEMENTARY_INFO.md +0 -0
  247. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/docx_export/sample_manuscript/03_REFERENCES.bib +0 -0
  248. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/docx_export/sample_manuscript/2025__unknown_et_al__rxiv.docx +0 -0
  249. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/fixtures/docx_export/sample_manuscript/sample_manuscript.docx +0 -0
  250. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/__init__.py +0 -0
  251. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_article_generation.py +0 -0
  252. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_bibliography_author_format_docx.py +0 -0
  253. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_binary_distribution.py +0 -0
  254. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_centralized_components.py +0 -0
  255. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_citation_injection.py +0 -0
  256. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_comment_system_integration.py +0 -0
  257. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_docx_export_integration.py +0 -0
  258. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_doi_fallback_integration.py +0 -0
  259. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_doi_validation_integration.py +0 -0
  260. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_example_manuscript.py +0 -0
  261. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_guillaume_fixtures.py +0 -0
  262. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_homebrew_workflow_validation.py +0 -0
  263. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_infrastructure_suite.py +0 -0
  264. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_init_build_workflow.py +0 -0
  265. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_install_verification_integration.py +0 -0
  266. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_latex_dependency_integration.py +0 -0
  267. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_manuscript_directory_integration.py +0 -0
  268. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_manuscript_python_execution_reporting.py +0 -0
  269. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_practical_manuscript_workflows.py +0 -0
  270. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_pypi_package_integration.py +0 -0
  271. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_python_execution_integration.py +0 -0
  272. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_repository_cli_integration.py +0 -0
  273. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_supplementary_formatting.py +0 -0
  274. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_user_reported_issue.py +0 -0
  275. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/integration/test_validation_workflow.py +0 -0
  276. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/README.md +0 -0
  277. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/conftest.py +0 -0
  278. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/test_cli_argument_parsing.py +0 -0
  279. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/test_discord_reported_issues.py +0 -0
  280. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/test_error_message_quality.py +0 -0
  281. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/test_google_colab_integration.py +0 -0
  282. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/test_guillaume_edge_cases.py +0 -0
  283. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/test_guillaume_pr131_rewrite.py +0 -0
  284. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/test_path_resolution.py +0 -0
  285. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/test_widget_author_behavior.py +0 -0
  286. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/regression/test_widget_interactions_playwright.py +0 -0
  287. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/smoke/__init__.py +0 -0
  288. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/smoke/test_basic_functionality.py +0 -0
  289. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/smoke/test_cli_smoke.py +0 -0
  290. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/system/__init__.py +0 -0
  291. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/system/test_ci_matrix.py +0 -0
  292. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/system/test_cli_workflows.py +0 -0
  293. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/system/test_end_to_end.py +0 -0
  294. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/test_homebrew_checker.py +0 -0
  295. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/test_install_detector.py +0 -0
  296. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/__init__.py +0 -0
  297. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/exporters/__init__.py +0 -0
  298. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/exporters/test_docx_citation_mapper.py +0 -0
  299. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/exporters/test_docx_content_processor.py +0 -0
  300. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_add_bibliography.py +0 -0
  301. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_arxiv_command.py +0 -0
  302. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_async_execution_manager.py +0 -0
  303. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_author_name_formatter.py +0 -0
  304. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_author_processor.py +0 -0
  305. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_build_command.py +0 -0
  306. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_build_manager.py +0 -0
  307. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_build_manager_manuscript_path.py +0 -0
  308. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_cache_security.py +0 -0
  309. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_cache_utils.py +0 -0
  310. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_check_installation_command.py +0 -0
  311. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_citation_processor.py +0 -0
  312. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_citation_rendering.py +0 -0
  313. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_citation_style.py +0 -0
  314. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_citation_utils.py +0 -0
  315. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_cli_cleanup_integration.py +0 -0
  316. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_cli_structure.py +0 -0
  317. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_comment_processor.py +0 -0
  318. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_conda_installation_manager.py +0 -0
  319. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_conda_platform_detection.py +0 -0
  320. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_cross_platform_optimizations.py +0 -0
  321. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_custom_command_processor.py +0 -0
  322. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_dependency_manager.py +0 -0
  323. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_dependency_package_names.py +0 -0
  324. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_docx_helpers.py +0 -0
  325. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_doi_fallback_system.py +0 -0
  326. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_doi_resolver.py +0 -0
  327. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_doi_validator.py +0 -0
  328. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_email_encoder.py +0 -0
  329. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_environment_manager.py +0 -0
  330. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_error_handling_scenarios.py +0 -0
  331. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_execution_manager_comprehensive.py +0 -0
  332. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_figure_generator.py +0 -0
  333. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_figure_processor.py +0 -0
  334. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_figure_processor_error_handling.py +0 -0
  335. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_file_helpers.py +0 -0
  336. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_fix_bibliography.py +0 -0
  337. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_generate_docs.py +0 -0
  338. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_generate_preprint.py +0 -0
  339. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_github.py +0 -0
  340. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_github_actions_integration.py +0 -0
  341. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_importlib_edge_cases.py +0 -0
  342. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_install_platform_installers.py +0 -0
  343. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_install_system_libs.py +0 -0
  344. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_install_verification.py +0 -0
  345. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_interactive_path_change.py +0 -0
  346. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_interactive_validators.py +0 -0
  347. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_latex_dependency_handler.py +0 -0
  348. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_manuscript_figure_utils.py +0 -0
  349. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_manuscript_repository.py +0 -0
  350. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_math_processor.py +0 -0
  351. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_md2tex.py +0 -0
  352. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_mermaid_fallback.py +0 -0
  353. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_path_manager.py +0 -0
  354. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_pdf_validator.py +0 -0
  355. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_platform_comprehensive.py +0 -0
  356. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_platform_detector.py +0 -0
  357. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_processor_suite.py +0 -0
  358. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_python_execution_reporter.py +0 -0
  359. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_python_executor.py +0 -0
  360. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_release_orchestrator.py +0 -0
  361. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_repository_manager.py +0 -0
  362. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_rxiv_setup_command.py +0 -0
  363. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_security_features.py +0 -0
  364. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_security_scanner.py +0 -0
  365. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_setup_environment.py +0 -0
  366. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_style_file_resolution.py +0 -0
  367. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_supplementary_note_processor.py +0 -0
  368. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_table_rotation.py +0 -0
  369. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_template_processor.py +0 -0
  370. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_text_formatters.py +0 -0
  371. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_text_utils.py +0 -0
  372. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_tips.py +0 -0
  373. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_title_sync.py +0 -0
  374. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_title_sync_validation.py +0 -0
  375. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_track_changes.py +0 -0
  376. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_trailing_slash_regression.py +0 -0
  377. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_url_to_doi.py +0 -0
  378. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_utils.py +0 -0
  379. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_validate_backticks.py +0 -0
  380. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_validate_command_fixed.py +0 -0
  381. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_validate_manuscript.py +0 -0
  382. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_validation_suite.py +0 -0
  383. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_validators.py +0 -0
  384. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/unit/test_yaml_processor.py +0 -0
  385. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/README.md +0 -0
  386. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/figure-positioning/00_CONFIG.yml +0 -0
  387. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/figure-positioning/01_MAIN.md +0 -0
  388. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/figure-positioning/03_REFERENCES.bib +0 -0
  389. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/figure-positioning/FIGURES/Figure__positioning_test.png +0 -0
  390. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/figure-positioning/FIGURES/Figure__positioning_test.py +0 -0
  391. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/figure-positioning/FIGURES/ReadyFig.png +0 -0
  392. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/figure-positioning/FIGURES/ReadyFig.py +0 -0
  393. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/figure-positioning/README.md +0 -0
  394. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/methods-placement/00_CONFIG.yml +0 -0
  395. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/methods-placement/01_MAIN.md +0 -0
  396. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/methods-placement/02_SUPPLEMENTARY_INFO.md +0 -0
  397. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/methods-placement/03_REFERENCES.bib +0 -0
  398. {rxiv_maker-1.16.5 → rxiv_maker-1.16.7}/tests/visual/methods-placement/README.md +0 -0
@@ -52,7 +52,6 @@ output.txt
52
52
  *~
53
53
 
54
54
  # Claude Code configuration
55
- CLAUDE.md
56
55
  .claude
57
56
 
58
57
  # Byte-compiled / optimized / DLL files
@@ -316,6 +315,7 @@ GEMINI.md
316
315
  !CHANGELOG.md
317
316
  !CONTRIBUTING.md
318
317
  !CODE_OF_CONDUCT.md
318
+ !CLAUDE.md
319
319
  !docs/**/*.md
320
320
  !EXAMPLE_MANUSCRIPT/**/*.md
321
321
  !MANUSCRIPT/**/*.md
@@ -330,7 +330,6 @@ GEMINI.md
330
330
  todo*.md
331
331
  DOCKER_ACCELERATION.md
332
332
  GEMINI.md
333
- CLAUDE.md
334
333
  output.md
335
334
 
336
335
  # Temporary analysis files
@@ -394,4 +393,4 @@ rxivdraft/MANUSCRIPT/2025__antónio_d_brito_et_al__rxiv.pdf
394
393
  .gemini/
395
394
  .gemini-clipboard/
396
395
  gha-creds-*.json
397
- fatetracking/MANUSCRIPT/.rxiv_cache
396
+ fatetracking/MANUSCRIPT/.rxiv_cache
@@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.16.7] - 2025-12-18
11
+
12
+ ### Changed
13
+
14
+ - **Upgrade Workflow Centralization**: Migrated to henriqueslab-updater v1.2.0 for centralized upgrade management
15
+ - Simplified upgrade command implementation from 165 to 53 lines (68% reduction)
16
+ - Created custom `RxivUpgradeNotifier` implementing `UpgradeNotifier` protocol
17
+ - Integrated with existing changelog parser for rich change summaries with breaking change highlighting
18
+ - Maintains backward compatibility with all existing flags (`--yes`, `--check-only`)
19
+ - Reduces code duplication across HenriquesLab CLI tools
20
+ - Provides consistent upgrade UX across all HenriquesLab projects
21
+
22
+ ## [1.16.6] - 2025-12-17
23
+
24
+ ### Fixed
25
+
26
+ - **Check Installation Guidance**: Improved fresh install experience
27
+ - Updated `rxiv check-installation` next steps to guide users on downloading example manuscript
28
+ - Replaced assumption of existing manuscript with `rxiv get-rxiv-preprint` guidance
29
+ - Enhanced user onboarding for first-time users
30
+
31
+ - **Mermaid Diagram Error Messages**: Enhanced error reporting for figure generation
32
+ - Distinguished between timeout, HTTP errors (400/503/429), and network failures
33
+ - Shows specific error reasons: "syntax error or diagram too complex" for 400, "service timeout" for 503
34
+ - Improved diagnostic information for troubleshooting diagram rendering issues
35
+
36
+ - **Heading Validation False Positives**: Fixed validator treating Python comments as markdown headings
37
+ - Modified `_validate_headings()` to exclude `{{py:exec}}` code blocks from heading analysis
38
+ - Prevents false positives where Python `# comments` were flagged as H1 markdown headings
39
+ - Applies existing content protection mechanism to heading validation
40
+
10
41
  ## [1.16.5] - 2025-12-15
11
42
 
12
43
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rxiv-maker
3
- Version: 1.16.5
3
+ Version: 1.16.7
4
4
  Summary: Write scientific preprints in Markdown. Generate publication-ready PDFs efficiently.
5
5
  Project-URL: Homepage, https://github.com/HenriquesLab/rxiv-maker
6
6
  Project-URL: Documentation, https://github.com/HenriquesLab/rxiv-maker#readme
@@ -27,7 +27,7 @@ Requires-Python: >=3.10
27
27
  Requires-Dist: click>=8.0.0
28
28
  Requires-Dist: crossref-commons>=0.0.7
29
29
  Requires-Dist: gitpython>=3.1.0
30
- Requires-Dist: henriqueslab-updater>=1.1.3
30
+ Requires-Dist: henriqueslab-updater>=1.2.0
31
31
  Requires-Dist: latex2mathml>=3.78.0
32
32
  Requires-Dist: matplotlib>=3.7.0
33
33
  Requires-Dist: numpy>=1.24.0
@@ -358,9 +358,14 @@ rxiv config --non-interactive # Show current settings
358
358
 
359
359
  ### Maintenance
360
360
  ```bash
361
- rxiv upgrade # Upgrade to latest version
362
- rxiv changelog # View changelog and release notes
363
- rxiv changelog --recent 5 # View last 5 versions
361
+ # Upgrade commands (auto-detects Homebrew, pip, uv, pipx)
362
+ rxiv upgrade # Interactive upgrade with confirmation
363
+ rxiv upgrade --yes # Upgrade without confirmation
364
+ rxiv upgrade --check-only # Check for updates only
365
+
366
+ # Changelog and version information
367
+ rxiv changelog # View changelog and release notes
368
+ rxiv changelog --recent 5 # View last 5 versions
364
369
  ```
365
370
 
366
371
  > **💡 CI/Automation Note:** All interactive commands support non-interactive mode or configuration files for use in CI/CD pipelines and automated workflows. Use `--non-interactive` flag or configure via `~/.rxiv-maker/config` for non-TTY environments.
@@ -281,9 +281,14 @@ rxiv config --non-interactive # Show current settings
281
281
 
282
282
  ### Maintenance
283
283
  ```bash
284
- rxiv upgrade # Upgrade to latest version
285
- rxiv changelog # View changelog and release notes
286
- rxiv changelog --recent 5 # View last 5 versions
284
+ # Upgrade commands (auto-detects Homebrew, pip, uv, pipx)
285
+ rxiv upgrade # Interactive upgrade with confirmation
286
+ rxiv upgrade --yes # Upgrade without confirmation
287
+ rxiv upgrade --check-only # Check for updates only
288
+
289
+ # Changelog and version information
290
+ rxiv changelog # View changelog and release notes
291
+ rxiv changelog --recent 5 # View last 5 versions
287
292
  ```
288
293
 
289
294
  > **💡 CI/Automation Note:** All interactive commands support non-interactive mode or configuration files for use in CI/CD pipelines and automated workflows. Use `--non-interactive` flag or configure via `~/.rxiv-maker/config` for non-TTY environments.
@@ -53,7 +53,7 @@ dependencies = [
53
53
  "GitPython>=3.1.0",
54
54
  "prompt_toolkit>=3.0.0",
55
55
  # Update checking
56
- "henriqueslab-updater>=1.1.3",
56
+ "henriqueslab-updater>=1.2.0",
57
57
  ]
58
58
 
59
59
  [project.urls]
@@ -0,0 +1,4 @@
1
+ # API Documentation
2
+
3
+ Welcome to the API documentation for rxiv-maker.
4
+
@@ -0,0 +1,4 @@
1
+ # API Documentation
2
+
3
+ Welcome to the API documentation for rxiv-maker.
4
+
@@ -1,3 +1,3 @@
1
1
  """Version information."""
2
2
 
3
- __version__ = "1.16.5"
3
+ __version__ = "1.16.7"
@@ -0,0 +1,52 @@
1
+ """Upgrade command for rxiv-maker CLI."""
2
+
3
+ import sys
4
+
5
+ import click
6
+ from henriqueslab_updater import handle_upgrade_workflow
7
+ from rich.console import Console
8
+
9
+ from ... import __version__
10
+ from ...utils.install_detector import detect_install_method
11
+ from ...utils.rich_upgrade_notifier import RxivUpgradeNotifier
12
+
13
+ console = Console()
14
+
15
+
16
+ @click.command()
17
+ @click.option("--yes", "-y", is_flag=True, help="Skip confirmation prompt")
18
+ @click.option("--check-only", "-c", is_flag=True, help="Only check for updates, don't upgrade")
19
+ @click.pass_context
20
+ def upgrade(ctx: click.Context, yes: bool, check_only: bool) -> None:
21
+ """Upgrade rxiv-maker to the latest version.
22
+
23
+ This command automatically detects how rxiv-maker was installed
24
+ (Homebrew, pip, uv, pipx, etc.) and runs the appropriate upgrade command.
25
+
26
+ Examples:
27
+ rxiv upgrade # Check and upgrade with confirmation
28
+ rxiv upgrade --yes # Upgrade without confirmation
29
+ rxiv upgrade --check-only # Only check for updates
30
+ """
31
+ # Handle development installations specially
32
+ install_method = detect_install_method()
33
+ if install_method == "dev":
34
+ console.print("⚠️ Development installation detected", style="yellow")
35
+ console.print(" To update, pull the latest changes from git:", style="yellow")
36
+ console.print(" [cyan]cd <repo> && git pull && uv sync[/cyan]", style="yellow")
37
+ sys.exit(0)
38
+
39
+ # Use centralized upgrade workflow
40
+ notifier = RxivUpgradeNotifier(console)
41
+ success, error = handle_upgrade_workflow(
42
+ package_name="rxiv-maker",
43
+ current_version=__version__,
44
+ check_only=check_only,
45
+ skip_confirmation=yes,
46
+ notifier=notifier,
47
+ github_org="HenriquesLab",
48
+ github_repo="rxiv-maker",
49
+ )
50
+
51
+ if not success and error:
52
+ sys.exit(1)
@@ -187,13 +187,16 @@ class CheckInstallationCommand(BaseCommand):
187
187
  """Show next steps after dependency check."""
188
188
  if not missing_results:
189
189
  self.console.print("\n🚀 Next steps:", style="blue")
190
- self.console.print(" • Test PDF generation: rxiv pdf ../manuscript-rxiv-maker/MANUSCRIPT")
190
+ self.console.print(" • Get example manuscript: rxiv get-rxiv-preprint")
191
+ self.console.print(" • Navigate to manuscript: cd manuscript-rxiv-maker/MANUSCRIPT")
192
+ self.console.print(" • Generate PDF: rxiv pdf")
191
193
  return
192
194
 
193
195
  self.console.print("\n🔧 Next steps:", style="blue")
194
196
  self.console.print(" • Install missing dependencies shown above")
195
197
  self.console.print(" • Re-run: rxiv check-installation")
196
- self.console.print(" • Test PDF generation: rxiv pdf ../manuscript-rxiv-maker/MANUSCRIPT")
198
+ self.console.print(" • Get example manuscript: rxiv get-rxiv-preprint")
199
+ self.console.print(" • Generate PDF: cd manuscript-rxiv-maker/MANUSCRIPT && rxiv pdf")
197
200
 
198
201
  def _show_basic_results(self, results: dict) -> None:
199
202
  """Show basic installation results."""
@@ -250,31 +250,95 @@ class FigureGenerator:
250
250
  response = get_with_retry(mermaid_url, max_attempts=5, timeout=30)
251
251
  else:
252
252
  response = requests.get(mermaid_url, timeout=30)
253
- except Exception:
254
- # If retry fails, fall back to placeholder
255
- return self._create_fallback_mermaid_diagram(input_file, output_file)
253
+ except requests.Timeout:
254
+ # Timeout - likely diagram too complex or service slow
255
+ return self._create_fallback_mermaid_diagram(
256
+ input_file, output_file, reason="timeout", details="30s timeout exceeded"
257
+ )
258
+ except requests.HTTPError as e:
259
+ # HTTP error (400, 503, etc.) - extract status code
260
+ status_code = e.response.status_code if hasattr(e, "response") else "unknown"
261
+ if status_code == 400:
262
+ details = "syntax error or diagram too complex"
263
+ elif status_code == 503:
264
+ details = "service timeout (diagram too complex)"
265
+ else:
266
+ details = f"HTTP {status_code}"
267
+ return self._create_fallback_mermaid_diagram(
268
+ input_file, output_file, reason="http_error", details=details
269
+ )
270
+ except Exception as e:
271
+ # Network or other error during request
272
+ error_msg = str(e)
273
+ # Try to extract status code from error message if it's there
274
+ if "400" in error_msg:
275
+ details = "syntax error or diagram too complex"
276
+ elif "503" in error_msg:
277
+ details = "service timeout (diagram too complex)"
278
+ elif "429" in error_msg:
279
+ details = "rate limit exceeded"
280
+ else:
281
+ details = "connection error"
282
+ return self._create_fallback_mermaid_diagram(
283
+ input_file, output_file, reason="network_error", details=details
284
+ )
256
285
 
257
286
  if response.status_code == 200:
258
287
  with open(output_file, "wb") as f:
259
288
  f.write(response.content)
260
289
  return True
261
290
  else:
262
- print(f"mermaid.ink service returned status {response.status_code}")
263
- print(
264
- "💡 Tip: If this is a syntax error, check your Mermaid diagram at https://www.mermaidchart.com/"
291
+ # Determine failure reason from status code
292
+ if response.status_code == 400:
293
+ reason_msg = "syntax error or diagram too complex"
294
+ elif response.status_code == 429:
295
+ reason_msg = "rate limit exceeded"
296
+ elif response.status_code == 503:
297
+ reason_msg = "service timeout (diagram too complex)"
298
+ elif response.status_code >= 500:
299
+ reason_msg = "service unavailable"
300
+ else:
301
+ reason_msg = f"HTTP {response.status_code}"
302
+
303
+ return self._create_fallback_mermaid_diagram(
304
+ input_file, output_file, reason="http_error", details=reason_msg
265
305
  )
266
- return self._create_fallback_mermaid_diagram(input_file, output_file)
267
306
  else:
268
- print("requests library not available for Mermaid generation")
269
- return self._create_fallback_mermaid_diagram(input_file, output_file)
307
+ return self._create_fallback_mermaid_diagram(
308
+ input_file, output_file, reason="no_requests_lib", details="requests library not available"
309
+ )
270
310
 
271
311
  except Exception as e:
272
- print(f"mermaid.ink service error: {e}")
273
- print("💡 Tip: Check your Mermaid diagram syntax at https://www.mermaidchart.com/")
274
- return self._create_fallback_mermaid_diagram(input_file, output_file)
312
+ return self._create_fallback_mermaid_diagram(
313
+ input_file, output_file, reason="unexpected_error", details=str(e)
314
+ )
315
+
316
+ def _create_fallback_mermaid_diagram(
317
+ self, input_file: Path, output_file: Path, reason: str = "unknown", details: str = "service unavailable"
318
+ ) -> bool:
319
+ """Create a fallback placeholder diagram when Mermaid service is unavailable.
320
+
321
+ Args:
322
+ input_file: Source mermaid file
323
+ output_file: Output file path
324
+ reason: Failure reason category (timeout, http_error, network_error, etc.)
325
+ details: Detailed error message
326
+
327
+ Returns:
328
+ True if placeholder was created successfully
329
+ """
330
+ # Generate user-friendly warning message based on failure reason
331
+ if reason == "timeout":
332
+ warning_msg = f"diagram rendering timed out ({details})"
333
+ elif reason == "http_error":
334
+ warning_msg = f"{details}"
335
+ elif reason == "network_error":
336
+ warning_msg = f"network error: {details}"
337
+ elif reason == "no_requests_lib":
338
+ warning_msg = "requests library not available"
339
+ else:
340
+ warning_msg = f"{details}"
275
341
 
276
- def _create_fallback_mermaid_diagram(self, input_file: Path, output_file: Path) -> bool:
277
- """Create a fallback placeholder diagram when Mermaid service is unavailable."""
278
342
  try:
279
343
  if self.output_format.lower() == "svg":
280
344
  # Create SVG placeholder
@@ -294,6 +358,7 @@ class FigureGenerator:
294
358
  </svg>"""
295
359
  with open(output_file, "w", encoding="utf-8") as f:
296
360
  f.write(svg_content)
361
+ print(f"⚠️ Created placeholder SVG for {input_file.name} ({warning_msg})")
297
362
  return True
298
363
  elif self.output_format.lower() == "png":
299
364
  # Create minimal PNG placeholder (1x1 white pixel)
@@ -303,7 +368,7 @@ class FigureGenerator:
303
368
  )
304
369
  with open(output_file, "wb") as f:
305
370
  f.write(png_data)
306
- print(f"⚠️ Created placeholder PNG for {input_file.name} (mermaid.ink unavailable)")
371
+ print(f"⚠️ Created placeholder PNG for {input_file.name} ({warning_msg})")
307
372
  return True
308
373
  elif self.output_format.lower() == "pdf":
309
374
  # Create minimal PDF placeholder
@@ -374,20 +439,83 @@ startxref
374
439
  """
375
440
  with open(output_file, "w", encoding="utf-8") as f:
376
441
  f.write(pdf_content)
377
- print(f"⚠️ Created placeholder PDF for {input_file.name} (mermaid.ink unavailable)")
442
+ print(f"⚠️ Created placeholder PDF for {input_file.name} ({warning_msg})")
378
443
  return True
379
444
  else:
380
445
  # Fallback for other formats - create text file with warning
381
446
  with open(output_file.with_suffix(".txt"), "w", encoding="utf-8") as f:
382
447
  f.write(f"Mermaid diagram placeholder for {input_file.name}\n")
383
- f.write("mermaid.ink service unavailable - diagram generation failed\n")
448
+ f.write(f"Reason: {warning_msg}\n")
384
449
  f.write("\n💡 Tip: Check your Mermaid diagram syntax at https://www.mermaidchart.com/\n")
385
- print(f"⚠️ Created text placeholder for {input_file.name} (mermaid.ink unavailable)")
450
+ print(f"⚠️ Created text placeholder for {input_file.name} ({warning_msg})")
386
451
  return True
387
452
  except Exception as e:
388
453
  print(f"Failed to create fallback diagram: {e}")
389
454
  return False
390
455
 
456
+ def validate_mermaid_diagram(self, mmd_file: Path) -> tuple[bool, str, dict]:
457
+ """Validate a Mermaid diagram for mermaid.ink compatibility.
458
+
459
+ Args:
460
+ mmd_file: Path to .mmd file
461
+
462
+ Returns:
463
+ Tuple of (is_valid, message, details_dict)
464
+ - is_valid: True if diagram will render successfully
465
+ - message: Human-readable validation result
466
+ - details_dict: Dict with complexity metrics and suggestions
467
+ """
468
+ if not requests:
469
+ return False, "requests library not available for validation", {}
470
+
471
+ try:
472
+ # Read and analyze the diagram
473
+ with open(mmd_file, "r", encoding="utf-8") as f:
474
+ content = f.read().strip()
475
+
476
+ # Analyze complexity
477
+ details = {
478
+ "file_size": len(content),
479
+ "line_count": content.count("\n") + 1,
480
+ "subgraph_count": content.count("subgraph"),
481
+ "node_count": len(re.findall(r"\w+\[", content)),
482
+ "class_def_count": content.count("classDef"),
483
+ }
484
+
485
+ # Check for known problematic patterns
486
+ warnings = []
487
+ if details["file_size"] > 2500:
488
+ warnings.append(f"Large diagram ({details['file_size']} chars, limit ~2500)")
489
+ if details["subgraph_count"] > 5:
490
+ warnings.append(f"Many subgraphs ({details['subgraph_count']}, limit ~5)")
491
+ if details["class_def_count"] > 6:
492
+ warnings.append(f"Heavy styling ({details['class_def_count']} classes, limit ~6)")
493
+
494
+ # Test with mermaid.ink
495
+ encoded = base64.b64encode(content.encode("utf-8")).decode("ascii")
496
+ test_url = f"https://mermaid.ink/svg/{encoded}" # Use SVG for faster testing
497
+
498
+ try:
499
+ response = requests.get(test_url, timeout=10)
500
+ if response.status_code == 200:
501
+ if warnings:
502
+ msg = f"✓ Valid (but complex: {', '.join(warnings)})"
503
+ return True, msg, details
504
+ return True, "✓ Valid and will render successfully", details
505
+ elif response.status_code == 400:
506
+ return False, "✗ Syntax error or too complex for mermaid.ink", details
507
+ elif response.status_code == 503:
508
+ return False, "✗ Diagram too complex (service timeout)", details
509
+ else:
510
+ return False, f"✗ HTTP {response.status_code}", details
511
+ except requests.Timeout:
512
+ return False, "✗ Validation timeout (diagram likely too complex)", details
513
+ except Exception as e:
514
+ return False, f"✗ Network error: {str(e)[:50]}", details
515
+
516
+ except Exception as e:
517
+ return False, f"✗ Error reading diagram: {str(e)[:50]}", {}
518
+
391
519
  def _execute_python_files(self, progress=None, task_id=None, use_rich: bool = True):
392
520
  """Execute Python scripts to generate figures using local Python."""
393
521
  py_files = list(self.figures_dir.glob("*.py"))
@@ -0,0 +1,162 @@
1
+ """Rich console adapter for upgrade notifications in rxiv-maker."""
2
+
3
+ import click
4
+ from rich.console import Console
5
+
6
+
7
+ class RxivUpgradeNotifier:
8
+ """Adapt Rich console to UpgradeNotifier protocol for rxiv-maker.
9
+
10
+ Integrates with rxiv-maker's changelog parser to show rich change summaries.
11
+ """
12
+
13
+ def __init__(self, console: Console):
14
+ """Initialize with Rich console instance.
15
+
16
+ Args:
17
+ console: Rich Console instance for styled output
18
+ """
19
+ self.console = console
20
+
21
+ def show_checking(self) -> None:
22
+ """Show 'checking for updates' message."""
23
+ self.console.print("🔍 Checking for updates...", style="blue")
24
+
25
+ def show_version_check(self, current: str, latest: str, available: bool) -> None:
26
+ """Show version check results.
27
+
28
+ Args:
29
+ current: Current installed version
30
+ latest: Latest available version
31
+ available: Whether an update is available
32
+ """
33
+ if available:
34
+ self.console.print(
35
+ f"📦 Update available: [cyan]v{current}[/cyan] → [green bold]v{latest}[/green bold]",
36
+ style="yellow",
37
+ )
38
+ else:
39
+ self.console.print(
40
+ f"✅ You already have the latest version ([cyan]v{current}[/cyan])",
41
+ style="green",
42
+ )
43
+
44
+ def show_update_info(self, current: str, latest: str, release_url: str) -> None:
45
+ """Show update available information with changelog integration.
46
+
47
+ Args:
48
+ current: Current version
49
+ latest: Latest version
50
+ release_url: URL to release notes
51
+ """
52
+ # Import here to avoid circular dependencies
53
+ from .changelog_parser import fetch_and_format_changelog
54
+
55
+ # Fetch and display changelog
56
+ summary, error = fetch_and_format_changelog(
57
+ current_version=current,
58
+ latest_version=latest,
59
+ highlights_per_version=3,
60
+ )
61
+
62
+ if summary and not error:
63
+ self.console.print("\n📋 What's changing:", style="bold blue")
64
+ # Display changelog - format_summary returns rich-formatted text
65
+ # Parse and display with proper styling
66
+ for line in summary.split("\n"):
67
+ if line.startswith("⚠️"):
68
+ # Highlight breaking changes prominently
69
+ self.console.print(line, style="bold red")
70
+ elif "What's New:" in line or "What's changing:" in line:
71
+ self.console.print(line, style="bold cyan")
72
+ elif line.strip().startswith("v"):
73
+ # Version headers
74
+ self.console.print(line, style="bold yellow")
75
+ elif line.strip().startswith(("✨", "🔄", "🐛", "🗑️", "🔒", "📝")):
76
+ # Change items with emojis
77
+ self.console.print(f" {line.strip()}", style="white")
78
+ elif line.strip().startswith("•"):
79
+ # Breaking change items
80
+ self.console.print(f" {line.strip()}", style="yellow")
81
+ elif line.strip():
82
+ self.console.print(f" {line}", style="dim")
83
+ else:
84
+ # Fallback if changelog unavailable
85
+ self.console.print(
86
+ f"\nView release notes: [link]{release_url}[/link]",
87
+ style="blue",
88
+ )
89
+
90
+ def show_installer_info(self, friendly_name: str, command: str) -> None:
91
+ """Show detected installer information.
92
+
93
+ Args:
94
+ friendly_name: Human-readable installer name
95
+ command: The upgrade command that will be executed
96
+ """
97
+ self.console.print()
98
+ self.console.print(
99
+ f"🔍 Detected installation method: [bold]{friendly_name}[/bold]",
100
+ style="blue",
101
+ )
102
+ self.console.print(f"📦 Running: [yellow]{command}[/yellow]")
103
+
104
+ def show_success(self, version: str) -> None:
105
+ """Show successful upgrade message.
106
+
107
+ Args:
108
+ version: Version that was successfully installed
109
+ """
110
+ self.console.print()
111
+ self.console.print("✅ Upgrade completed successfully!", style="green bold")
112
+ self.console.print(f" Now running: [green]v{version}[/green]")
113
+ self.console.print()
114
+ self.console.print(" Run [blue]'rxiv --version'[/blue] to verify the installation", style="dim")
115
+
116
+ def show_error(self, error: str | None) -> None:
117
+ """Show upgrade error message.
118
+
119
+ Args:
120
+ error: Error message or None
121
+ """
122
+ self.console.print()
123
+ self.console.print("❌ Upgrade failed", style="red bold")
124
+ if error:
125
+ self.console.print(f" {error}", style="red")
126
+
127
+ def show_manual_instructions(self, install_method: str) -> None:
128
+ """Show manual upgrade instructions.
129
+
130
+ Args:
131
+ install_method: The detected installation method
132
+ """
133
+ self.console.print("\n💡 Try running manually:", style="yellow bold")
134
+
135
+ if install_method == "homebrew":
136
+ self.console.print(" [cyan]brew update && brew upgrade rxiv-maker[/cyan]")
137
+ elif install_method == "pipx":
138
+ self.console.print(" [cyan]pipx upgrade rxiv-maker[/cyan]")
139
+ elif install_method == "uv":
140
+ self.console.print(" [cyan]uv tool upgrade rxiv-maker[/cyan]")
141
+ elif install_method == "dev":
142
+ self.console.print(" [cyan]cd <repo> && git pull && uv sync[/cyan]", style="dim")
143
+ else:
144
+ self.console.print(" [cyan]pip install --upgrade rxiv-maker[/cyan]")
145
+ self.console.print(" [dim]# Or with --user flag:[/dim]")
146
+ self.console.print(" [cyan]pip install --upgrade --user rxiv-maker[/cyan]")
147
+
148
+ def confirm_upgrade(self, version: str) -> bool:
149
+ """Prompt user for confirmation using click.
150
+
151
+ Args:
152
+ version: Version to upgrade to
153
+
154
+ Returns:
155
+ True if user confirms, False otherwise
156
+ """
157
+ try:
158
+ self.console.print()
159
+ return click.confirm(f"Upgrade rxiv-maker to v{version}?", default=True)
160
+ except (KeyboardInterrupt, EOFError):
161
+ self.console.print("\n⚠️ Upgrade cancelled.", style="yellow")
162
+ return False
@@ -854,8 +854,17 @@ class SyntaxValidator(BaseValidator):
854
854
  heading_texts = {}
855
855
  previous_level = 0
856
856
 
857
- for line_num, line in enumerate(lines, 1):
858
- match = heading_pattern.match(line)
857
+ # Protect code blocks (including {{py:exec}}) from being treated as headings
858
+ content = "\n".join(lines)
859
+ protected_content = self._protect_validation_sensitive_content(content)
860
+ protected_lines = protected_content.split("\n")
861
+
862
+ for line_num, (original_line, protected_line) in enumerate(zip(lines, protected_lines, strict=False), 1):
863
+ # Skip protected code blocks (they might contain # comments)
864
+ if "XXPROTECTEDCODEXX" in protected_line:
865
+ continue
866
+
867
+ match = heading_pattern.match(protected_line)
859
868
  if match:
860
869
  hashes = match.group(1)
861
870
  heading_text = match.group(2).strip()
@@ -904,7 +913,7 @@ class SyntaxValidator(BaseValidator):
904
913
  f"Heading hierarchy skips levels: {previous_level} → {level}",
905
914
  file_path=file_path,
906
915
  line_number=line_num,
907
- context=line.strip(),
916
+ context=original_line.strip(),
908
917
  suggestion=(
909
918
  f"Consider using {'#' * (previous_level + 1)} instead of {'#' * level}.\n"
910
919
  f" Skipping heading levels (e.g., ## to ####) makes document structure unclear."
@@ -927,7 +936,7 @@ class SyntaxValidator(BaseValidator):
927
936
  f"Standard section '{heading_text}' using level 1 heading (#)",
928
937
  file_path=file_path,
929
938
  line_number=line_num,
930
- context=line.strip(),
939
+ context=original_line.strip(),
931
940
  suggestion=(
932
941
  f"Change to level 2 heading: ## {heading_text}\n"
933
942
  f" Level 1 (#) should only be used for the document title.\n"