rxiv-maker 1.16.7__tar.gz → 1.17.0__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.
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/CHANGELOG.md +117 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/PKG-INFO +2 -1
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/pyproject.toml +2 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/__version__.py +1 -1
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/build.py +7 -0
- rxiv_maker-1.17.0/src/rxiv_maker/cli/commands/docx.py +177 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/framework/workflow_commands.py +66 -2
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/citation_processor.py +5 -3
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/config_manager.py +1 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/dependency_manager.py +12 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/exporters/docx_citation_mapper.py +99 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/exporters/docx_content_processor.py +128 -30
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/exporters/docx_exporter.py +179 -24
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/exporters/docx_writer.py +227 -27
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/templates/registry.py +1 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/bst_generator.py +27 -7
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/docx_helpers.py +62 -3
- rxiv_maker-1.17.0/src/rxiv_maker/utils/pdf_splitter.py +116 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/tex/style/rxiv_maker_style.cls +33 -33
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/exporters/test_docx_citation_mapper.py +11 -1
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/exporters/test_docx_content_processor.py +8 -9
- rxiv_maker-1.17.0/tests/unit/test_bst_generator.py +132 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_citation_processor.py +90 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_dependency_package_names.py +37 -0
- rxiv_maker-1.17.0/tests/unit/test_docx_doi_resolution.py +248 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_docx_helpers.py +4 -2
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_importlib_edge_cases.py +2 -1
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_track_changes.py +27 -35
- rxiv_maker-1.16.7/src/rxiv_maker/cli/commands/docx.py +0 -103
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/.gitignore +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/LICENSE +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/README.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/docs/api/README.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/docs/api/index.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/logo/logo-rxiv-maker.afdesign +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/logo/logo-rxiv-maker.png +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/logo/logo-rxiv-maker.svg +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/__main__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/arxiv.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/bibliography.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/cache_management.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/changelog.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/check_installation.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/clean.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/completion.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/config.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/create_repo.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/figures.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/get_rxiv_preprint.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/init.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/install_deps.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/repo_init.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/repos.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/repos_search.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/setup.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/track_changes.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/upgrade.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/validate.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/commands/version.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/framework/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/framework/base.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/framework/cache_commands.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/framework/config_commands.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/framework/content_commands.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/framework/decorators.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/framework/utility_commands.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/framework.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/interactive.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/interactive_prompts.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/cli/main.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/config/defaults.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/config/validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/code_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/comment_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/custom_command_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/figure_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/html_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/list_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/math_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/md2tex.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/python_executor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/section_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/supplementary_note_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/table_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/text_formatters.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/types.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/converters/url_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/cache/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/cache/advanced_cache.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/cache/bibliography_cache.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/cache/cache_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/cache/doi_cache.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/cache/secure_cache_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/content_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/environment_bootstrap.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/environment_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/error_codes.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/error_recovery.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/logging_config.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/cache_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/execution_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/file_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/install_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/state_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/unified_config_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/validation_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/managers/workflow_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/path_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/progress_framework.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/repo_config.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/repository.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/session_optimizer.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/core/validation_framework.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/data/tips.yaml +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/add_bibliography.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/build_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/cleanup.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/fix_bibliography.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/generate_docs.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/generate_figures.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/generate_preprint.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/prepare_arxiv.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/setup_environment.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/track_changes.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/validate.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/engines/operations/validate_pdf.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/exporters/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/dependency_handlers/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/dependency_handlers/latex.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/dependency_handlers/r_lang.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/dependency_handlers/system_libs.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/platform_installers/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/platform_installers/base.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/platform_installers/linux.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/platform_installers/macos.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/platform_installers/windows.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/utils/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/utils/logging.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/utils/progress.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/install/utils/verification.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/manuscript_utils/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/manuscript_utils/figure_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/processors/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/processors/author_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/processors/markdown_preprocessor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/processors/template_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/processors/yaml_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/rxiv_maker_cli.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/scripts/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/scripts/custom_doc_generator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/scripts/validate_manuscript.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/services/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/services/base.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/services/build_service.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/services/configuration_service.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/services/manuscript_service.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/services/publication_service.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/services/validation_service.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/templates/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/templates/manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/tex/python_execution_section.tex +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/author_name_formatter.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/bibliography_checksum.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/bibliography_parser.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/changelog_parser.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/citation_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/dependency_checker.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/doi_resolver.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/email_encoder.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/figure_checksum.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/file_helpers.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/github.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/homebrew_checker.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/install_detector.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/operation_ids.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/pdf_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/performance.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/platform.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/python_execution_reporter.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/retry.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/rich_upgrade_notifier.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/text_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/tips.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/title_sync.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/unicode_safe.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/update_checker.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/utils/url_to_doi.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validate.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/base_validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/citation_validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/doi/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/doi/api_clients.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/doi/metadata_comparator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/doi_validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/figure_validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/latex_error_parser.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/math_validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/pdf_validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/reference_validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/rxiv_maker/validators/syntax_validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/tex/style/rxiv_maker_style.bst +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/src/tex/template.tex +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/cli/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/cli/test_build.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/cli/test_changelog_command.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/cli/test_init_command.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/cli/test_main.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/conftest.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/e2e/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/e2e/test_dummy_manuscript_generator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/e2e/test_figure_workflow_validation.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/00_CONFIG.yml +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/01_MAIN.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/03_REFERENCES.bib +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/FIGURES/Fig1.png +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/FIGURES/Fig2.png +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/FIGURES/Fig3.png +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/README.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/docx_export/sample_manuscript/01_MAIN.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/docx_export/sample_manuscript/02_SUPPLEMENTARY_INFO.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/docx_export/sample_manuscript/03_REFERENCES.bib +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/docx_export/sample_manuscript/2025__unknown_et_al__rxiv.docx +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/fixtures/docx_export/sample_manuscript/sample_manuscript.docx +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_article_generation.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_bibliography_author_format_docx.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_binary_distribution.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_centralized_components.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_citation_injection.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_comment_system_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_docx_export_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_doi_fallback_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_doi_validation_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_example_manuscript.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_guillaume_fixtures.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_homebrew_workflow_validation.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_infrastructure_suite.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_init_build_workflow.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_install_verification_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_latex_dependency_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_manuscript_directory_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_manuscript_python_execution_reporting.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_practical_manuscript_workflows.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_pypi_package_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_python_execution_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_repository_cli_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_supplementary_formatting.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_user_reported_issue.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/integration/test_validation_workflow.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/README.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/conftest.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/test_cli_argument_parsing.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/test_discord_reported_issues.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/test_error_message_quality.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/test_google_colab_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/test_guillaume_edge_cases.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/test_guillaume_pr131_rewrite.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/test_path_resolution.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/test_widget_author_behavior.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/regression/test_widget_interactions_playwright.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/smoke/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/smoke/test_basic_functionality.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/smoke/test_cli_smoke.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/system/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/system/test_ci_matrix.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/system/test_cli_workflows.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/system/test_end_to_end.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/test_homebrew_checker.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/test_install_detector.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/exporters/__init__.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_add_bibliography.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_arxiv_command.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_async_execution_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_author_name_formatter.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_author_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_build_command.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_build_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_build_manager_manuscript_path.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_cache_security.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_cache_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_check_installation_command.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_citation_rendering.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_citation_style.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_citation_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_cli_cleanup_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_cli_structure.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_comment_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_conda_installation_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_conda_platform_detection.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_cross_platform_optimizations.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_custom_command_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_dependency_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_doi_fallback_system.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_doi_resolver.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_doi_validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_email_encoder.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_environment_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_error_handling_scenarios.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_execution_manager_comprehensive.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_figure_generator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_figure_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_figure_processor_error_handling.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_file_helpers.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_fix_bibliography.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_generate_docs.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_generate_preprint.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_github.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_github_actions_integration.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_install_platform_installers.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_install_system_libs.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_install_verification.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_interactive_path_change.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_interactive_validators.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_latex_dependency_handler.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_manuscript_figure_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_manuscript_repository.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_math_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_md2tex.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_mermaid_fallback.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_path_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_pdf_validator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_platform_comprehensive.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_platform_detector.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_processor_suite.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_python_execution_reporter.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_python_executor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_release_orchestrator.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_repository_manager.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_rich_upgrade_notifier.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_rxiv_setup_command.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_security_features.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_security_scanner.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_setup_environment.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_style_file_resolution.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_supplementary_note_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_table_rotation.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_template_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_text_formatters.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_text_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_tips.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_title_sync.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_title_sync_validation.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_trailing_slash_regression.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_upgrade_command.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_url_to_doi.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_utils.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_validate_backticks.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_validate_command_fixed.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_validate_manuscript.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_validation_suite.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_validators.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/unit/test_yaml_processor.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/README.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/figure-positioning/00_CONFIG.yml +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/figure-positioning/01_MAIN.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/figure-positioning/03_REFERENCES.bib +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/figure-positioning/FIGURES/Figure__positioning_test.png +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/figure-positioning/FIGURES/Figure__positioning_test.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/figure-positioning/FIGURES/ReadyFig.png +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/figure-positioning/FIGURES/ReadyFig.py +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/figure-positioning/README.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/methods-placement/00_CONFIG.yml +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/methods-placement/01_MAIN.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/methods-placement/02_SUPPLEMENTARY_INFO.md +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/methods-placement/03_REFERENCES.bib +0 -0
- {rxiv_maker-1.16.7 → rxiv_maker-1.17.0}/tests/visual/methods-placement/README.md +0 -0
|
@@ -7,6 +7,123 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.17.0] - 2025-12-22
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **PDF Splitting Feature**: New `--split-si` flag for `rxiv pdf` command
|
|
15
|
+
- Automatically splits generated PDFs into main manuscript and supplementary information sections
|
|
16
|
+
- Auto-detects SI markers ("Supplementary Information", "Supplementary Material", "Supporting Information", etc.)
|
|
17
|
+
- Generates properly named split files: `{year}__{author}_et_al__rxiv__main.pdf` and `{year}__{author}_et_al__rxiv__si.pdf`
|
|
18
|
+
- Places split files in MANUSCRIPT directory with consistent naming convention
|
|
19
|
+
- Addresses common journal submission requirements for separate main and SI files
|
|
20
|
+
- **Color-Coded DOCX References**: Visual distinction for different reference types
|
|
21
|
+
- Main figures: bright green highlighting
|
|
22
|
+
- Main tables: blue highlighting
|
|
23
|
+
- Supplementary elements (figures, tables, notes): turquoise highlighting
|
|
24
|
+
- Citations: yellow highlighting
|
|
25
|
+
- Equations: violet highlighting
|
|
26
|
+
- Improves readability and helps track different element types during review
|
|
27
|
+
- **Citation Range Formatting**: Automatic formatting of adjacent citations
|
|
28
|
+
- Formats `[4][5][6]` as `[4-6]` for cleaner presentation
|
|
29
|
+
- Handles both adjacent bracket citations and comma-separated citations
|
|
30
|
+
- Maintains readability while reducing visual clutter
|
|
31
|
+
- **DOCX Configuration Options**: New manuscript config options
|
|
32
|
+
- `docx.hide_si`: Control supplementary information visibility (default: false)
|
|
33
|
+
- `docx.figures_at_end`: Place main figures at end before bibliography (default: false)
|
|
34
|
+
- Clearer semantics than previous `add_si` option
|
|
35
|
+
- Supports different journal formatting requirements
|
|
36
|
+
- **Subscript/Superscript Support**: Chemical formulas and mathematical notation in DOCX
|
|
37
|
+
- Supports `~subscript~` and `^superscript^` markdown syntax
|
|
38
|
+
- Enables proper formatting of chemical formulas (H~2~O) and exponents (x^2^)
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- **Citation Extraction Bug**: Citations between triple-backtick code blocks now extract correctly
|
|
43
|
+
- Fixed regex processing order to handle triple backticks before single backticks
|
|
44
|
+
- Prevents citations from being incorrectly marked as "protected code content"
|
|
45
|
+
- Resolves issue where `[@key]` citations remained unconverted in DOCX output
|
|
46
|
+
- Added regression tests to prevent future occurrences
|
|
47
|
+
- **Bibliography Formatting**: Enhanced cleanup for malformed BibTeX entries
|
|
48
|
+
- HTML entity decoding: `é` → `é`, `á` → `á`, `…` → `…`
|
|
49
|
+
- Malformed name repair: fixes split author names (e.g., "Pé and Rez, Fernando" → "Pérez, Fernando")
|
|
50
|
+
- Brace cleanup: removes stray braces after Unicode characters
|
|
51
|
+
- Handles escaped HTML entities from BibTeX (`\&\#233` → `é`)
|
|
52
|
+
- Whitespace normalization for cleaner bibliography entries
|
|
53
|
+
- **Table Caption Formatting**: Supplementary tables now show proper labels
|
|
54
|
+
- Displays "Supp. Table SX." prefix with correct font sizing
|
|
55
|
+
- Preserves table label identifiers during processing
|
|
56
|
+
- Supports hyphens in table label names
|
|
57
|
+
- **Comment Filtering**: Markdown metadata comments no longer appear in DOCX
|
|
58
|
+
- Filters comments starting with "note:", "comment:" (case-insensitive)
|
|
59
|
+
- Prevents manuscript-specific metadata from appearing in final output
|
|
60
|
+
- Improves multi-line comment parsing
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- **Figure Centering**: All figures now centered by default in DOCX exports
|
|
65
|
+
- Improves visual presentation and alignment with journal standards
|
|
66
|
+
- Consistent formatting across all figure types
|
|
67
|
+
- **Citation Handling**: Citations treated as highlighted text instead of separate objects
|
|
68
|
+
- Maintains citation ranges in yellow highlighting
|
|
69
|
+
- Simplifies DOCX structure while preserving visual distinction
|
|
70
|
+
- **PDF Spacing**: Optimized manuscript spacing for increased content density
|
|
71
|
+
- Tighter spacing between back matter section headers and text
|
|
72
|
+
- Improved overall visual hierarchy
|
|
73
|
+
- More content per page without sacrificing readability
|
|
74
|
+
|
|
75
|
+
### Documentation
|
|
76
|
+
|
|
77
|
+
- **Updated CLAUDE.md**: Enhanced development documentation
|
|
78
|
+
- Removed Docker/Podman engine references (moved to separate docker-rxiv-maker repository)
|
|
79
|
+
- Added PDF splitting feature documentation
|
|
80
|
+
- Clarified testing workflows and CI requirements
|
|
81
|
+
|
|
82
|
+
## [1.16.8] - 2025-12-19
|
|
83
|
+
|
|
84
|
+
### Added
|
|
85
|
+
|
|
86
|
+
- **Automatic Poppler Installation**: Interactive installation prompt for DOCX export on macOS
|
|
87
|
+
- Detects missing poppler utilities when exporting to DOCX with PDF figures
|
|
88
|
+
- Offers automatic installation via Homebrew with user confirmation
|
|
89
|
+
- Shows clear installation instructions for Linux (apt) and other platforms
|
|
90
|
+
- Gracefully falls back to placeholders when poppler unavailable
|
|
91
|
+
- **DOI Resolution Implementation**: `--resolve-dois` flag now fully functional for DOCX export
|
|
92
|
+
- Resolves missing DOIs using CrossRef API with intelligent title matching
|
|
93
|
+
- Cleans LaTeX commands from titles for accurate search results
|
|
94
|
+
- Validates matches using year information when available
|
|
95
|
+
- Handles network failures and timeouts gracefully
|
|
96
|
+
- Logs resolved DOIs for transparency
|
|
97
|
+
- **Poppler Dependency Tracking**: Registered poppler in DependencyManager
|
|
98
|
+
- Added as system binary dependency with alternatives (pdftoppm, pdfinfo)
|
|
99
|
+
- Included in `rxiv check-installation` output
|
|
100
|
+
- Provides platform-specific installation hints
|
|
101
|
+
|
|
102
|
+
### Fixed
|
|
103
|
+
|
|
104
|
+
- **BST File Regex Bug**: Corrected bibliography style file generation to only modify `format.names`
|
|
105
|
+
- Previous regex matched both `format.names` and `format.full.names` functions
|
|
106
|
+
- Now specifically targets only `format.names` function using DOTALL flag
|
|
107
|
+
- Prevents corruption of citation labels in natbib
|
|
108
|
+
- Eliminates warning: "Found 2 format string patterns in .bst file"
|
|
109
|
+
- Raises error if unexpected matches found (defensive programming)
|
|
110
|
+
- **PDF to Image Conversion**: Improved error handling for missing poppler utilities
|
|
111
|
+
- Distinguishes between poppler not installed, corrupted PDFs, and other errors
|
|
112
|
+
- Uses proper logging instead of print statements
|
|
113
|
+
- Re-raises poppler errors to allow CLI to offer installation
|
|
114
|
+
- Provides specific error messages for different failure types
|
|
115
|
+
|
|
116
|
+
### Changed
|
|
117
|
+
|
|
118
|
+
- **DOCX Export Experience**: Enhanced PDF figure embedding workflow
|
|
119
|
+
- Pre-flight check detects poppler availability before attempting conversion
|
|
120
|
+
- Caches poppler status to avoid repeated checks
|
|
121
|
+
- Shows helpful warnings with installation instructions
|
|
122
|
+
- PDF figures embed correctly when poppler is installed
|
|
123
|
+
- **Homebrew Formula**: Added poppler as dependency
|
|
124
|
+
- Users installing via `brew install rxiv-maker` now get poppler automatically
|
|
125
|
+
- Ensures DOCX export works out of the box for Homebrew users
|
|
126
|
+
|
|
10
127
|
## [1.16.7] - 2025-12-18
|
|
11
128
|
|
|
12
129
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rxiv-maker
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.17.0
|
|
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
|
|
@@ -56,6 +56,7 @@ Requires-Dist: mypy>=1.0; extra == 'dev'
|
|
|
56
56
|
Requires-Dist: nbstripout>=0.7.1; extra == 'dev'
|
|
57
57
|
Requires-Dist: nox>=2023.0.0; extra == 'dev'
|
|
58
58
|
Requires-Dist: pre-commit>=4.2.0; extra == 'dev'
|
|
59
|
+
Requires-Dist: pypdf2>=3.0.0; extra == 'dev'
|
|
59
60
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
60
61
|
Requires-Dist: pytest-benchmark>=4.0.0; extra == 'dev'
|
|
61
62
|
Requires-Dist: pytest-clarity>=1.0.0; extra == 'dev'
|
|
@@ -30,6 +30,7 @@ from ..framework import BuildCommand
|
|
|
30
30
|
@click.option("--keep-output", is_flag=True, help="Preserve existing output directory (default: clear before build)")
|
|
31
31
|
@click.option("--docx", is_flag=True, help="Also export to DOCX format for collaborative review")
|
|
32
32
|
@click.option("--resolve-dois", "-r", is_flag=True, help="Attempt to resolve missing DOIs (when using --docx)")
|
|
33
|
+
@click.option("--split-si", is_flag=True, help="Split PDF into main and SI sections (__main.pdf and __si.pdf)")
|
|
33
34
|
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose output")
|
|
34
35
|
@click.option("--quiet", "-q", is_flag=True, help="Suppress non-essential output")
|
|
35
36
|
@click.option("--debug", "-d", is_flag=True, help="Enable debug output")
|
|
@@ -49,6 +50,7 @@ def build(
|
|
|
49
50
|
keep_output: bool,
|
|
50
51
|
docx: bool,
|
|
51
52
|
resolve_dois: bool,
|
|
53
|
+
split_si: bool,
|
|
52
54
|
verbose: bool,
|
|
53
55
|
quiet: bool,
|
|
54
56
|
debug: bool,
|
|
@@ -81,6 +83,10 @@ def build(
|
|
|
81
83
|
|
|
82
84
|
$ rxiv pdf --docx --resolve-dois
|
|
83
85
|
|
|
86
|
+
**Split PDF into main and SI sections:**
|
|
87
|
+
|
|
88
|
+
$ rxiv pdf --split-si
|
|
89
|
+
|
|
84
90
|
**Force regenerate all figures:**
|
|
85
91
|
|
|
86
92
|
$ rxiv pdf --force-figures
|
|
@@ -108,6 +114,7 @@ def build(
|
|
|
108
114
|
keep_output=keep_output,
|
|
109
115
|
docx=docx,
|
|
110
116
|
resolve_dois=resolve_dois,
|
|
117
|
+
split_si=split_si,
|
|
111
118
|
debug=debug or verbose,
|
|
112
119
|
quiet=quiet,
|
|
113
120
|
container_mode=container_mode,
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"""DOCX export command for rxiv-maker CLI."""
|
|
2
|
+
|
|
3
|
+
import platform
|
|
4
|
+
import shutil
|
|
5
|
+
import subprocess
|
|
6
|
+
|
|
7
|
+
import rich_click as click
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
from ...core.logging_config import get_logger
|
|
11
|
+
from ...core.managers.dependency_manager import DependencyStatus, get_dependency_manager
|
|
12
|
+
from ...exporters.docx_exporter import DocxExporter
|
|
13
|
+
|
|
14
|
+
logger = get_logger()
|
|
15
|
+
console = Console()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _check_and_offer_poppler_installation(console: Console, quiet: bool, verbose: bool) -> None:
|
|
19
|
+
"""Check poppler availability and offer automatic installation via brew.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
console: Rich console for output
|
|
23
|
+
quiet: Whether to suppress output
|
|
24
|
+
verbose: Whether verbose mode is enabled
|
|
25
|
+
"""
|
|
26
|
+
# Check if poppler is installed
|
|
27
|
+
manager = get_dependency_manager()
|
|
28
|
+
result = manager.check_dependency("pdftoppm")
|
|
29
|
+
|
|
30
|
+
if result.status == DependencyStatus.AVAILABLE:
|
|
31
|
+
if verbose:
|
|
32
|
+
console.print("[dim]✓ Poppler utilities available[/dim]")
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
# Poppler is missing - offer to install
|
|
36
|
+
system = platform.system()
|
|
37
|
+
|
|
38
|
+
if system == "Darwin" and shutil.which("brew"):
|
|
39
|
+
# macOS with Homebrew
|
|
40
|
+
if not quiet:
|
|
41
|
+
console.print("[yellow]⚠️ Poppler not found[/yellow]")
|
|
42
|
+
console.print(" Poppler is needed to embed PDF figures in DOCX files.")
|
|
43
|
+
console.print(" Without it, PDF figures will appear as placeholders.")
|
|
44
|
+
console.print()
|
|
45
|
+
|
|
46
|
+
if click.confirm(" Would you like to install poppler now via Homebrew?", default=True):
|
|
47
|
+
console.print("[cyan]Installing poppler...[/cyan]")
|
|
48
|
+
try:
|
|
49
|
+
result = subprocess.run(
|
|
50
|
+
["brew", "install", "poppler"],
|
|
51
|
+
capture_output=True,
|
|
52
|
+
text=True,
|
|
53
|
+
timeout=300,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
if result.returncode == 0:
|
|
57
|
+
console.print("[green]✅ Poppler installed successfully![/green]")
|
|
58
|
+
# Clear dependency cache so it gets re-checked
|
|
59
|
+
manager.clear_cache()
|
|
60
|
+
else:
|
|
61
|
+
console.print(f"[red]❌ Installation failed:[/red] {result.stderr}")
|
|
62
|
+
console.print(" You can install manually with: brew install poppler")
|
|
63
|
+
except subprocess.TimeoutExpired:
|
|
64
|
+
console.print("[red]❌ Installation timed out[/red]")
|
|
65
|
+
except Exception as e:
|
|
66
|
+
console.print(f"[red]❌ Installation error:[/red] {e}")
|
|
67
|
+
else:
|
|
68
|
+
console.print(" [dim]Skipping poppler installation. PDF figures will show as placeholders.[/dim]")
|
|
69
|
+
|
|
70
|
+
elif system == "Linux":
|
|
71
|
+
# Linux
|
|
72
|
+
if not quiet:
|
|
73
|
+
console.print("[yellow]⚠️ Poppler not found[/yellow]")
|
|
74
|
+
console.print(" Install with: sudo apt install poppler-utils")
|
|
75
|
+
console.print()
|
|
76
|
+
else:
|
|
77
|
+
# Other platforms or brew not available
|
|
78
|
+
if not quiet:
|
|
79
|
+
console.print("[yellow]⚠️ Poppler not found[/yellow]")
|
|
80
|
+
console.print(f" Install instructions: {result.resolution_hint}")
|
|
81
|
+
console.print()
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@click.command(context_settings={"help_option_names": ["-h", "--help"]})
|
|
85
|
+
@click.argument(
|
|
86
|
+
"manuscript_path",
|
|
87
|
+
type=click.Path(exists=True, file_okay=False),
|
|
88
|
+
required=False,
|
|
89
|
+
metavar="[MANUSCRIPT_PATH]",
|
|
90
|
+
)
|
|
91
|
+
@click.option(
|
|
92
|
+
"--resolve-dois",
|
|
93
|
+
"-r",
|
|
94
|
+
is_flag=True,
|
|
95
|
+
help="Attempt to resolve missing DOIs from metadata",
|
|
96
|
+
)
|
|
97
|
+
@click.option(
|
|
98
|
+
"--no-footnotes",
|
|
99
|
+
is_flag=True,
|
|
100
|
+
help="Disable references section (citations only)",
|
|
101
|
+
)
|
|
102
|
+
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose output")
|
|
103
|
+
@click.option("--quiet", "-q", is_flag=True, help="Suppress non-essential output")
|
|
104
|
+
def docx(
|
|
105
|
+
manuscript_path: str | None,
|
|
106
|
+
resolve_dois: bool,
|
|
107
|
+
no_footnotes: bool,
|
|
108
|
+
verbose: bool,
|
|
109
|
+
quiet: bool,
|
|
110
|
+
) -> None:
|
|
111
|
+
"""Export manuscript to DOCX format for collaborative review.
|
|
112
|
+
|
|
113
|
+
Generates a Word document with numbered citations, embedded figures,
|
|
114
|
+
and a complete references section with DOI links. Output is automatically
|
|
115
|
+
saved to the manuscript directory with the same naming pattern as the PDF.
|
|
116
|
+
|
|
117
|
+
**MANUSCRIPT_PATH**: Directory containing manuscript files.
|
|
118
|
+
Defaults to MANUSCRIPT/
|
|
119
|
+
|
|
120
|
+
**Output**: Automatically saved to MANUSCRIPT/YEAR__lastname_et_al__rxiv.docx
|
|
121
|
+
|
|
122
|
+
## Examples
|
|
123
|
+
|
|
124
|
+
**Basic export:**
|
|
125
|
+
|
|
126
|
+
$ rxiv docx
|
|
127
|
+
|
|
128
|
+
**Export from custom directory:**
|
|
129
|
+
|
|
130
|
+
$ rxiv docx MY_PAPER/
|
|
131
|
+
|
|
132
|
+
**With DOI resolution for missing entries:**
|
|
133
|
+
|
|
134
|
+
$ rxiv docx --resolve-dois
|
|
135
|
+
|
|
136
|
+
**Without references section (citations only):**
|
|
137
|
+
|
|
138
|
+
$ rxiv docx --no-footnotes
|
|
139
|
+
"""
|
|
140
|
+
try:
|
|
141
|
+
# Configure logging
|
|
142
|
+
if verbose:
|
|
143
|
+
logger.set_level("DEBUG")
|
|
144
|
+
elif quiet:
|
|
145
|
+
logger.set_level("WARNING")
|
|
146
|
+
|
|
147
|
+
# Set manuscript path
|
|
148
|
+
manuscript_path = manuscript_path or "MANUSCRIPT"
|
|
149
|
+
|
|
150
|
+
# Create exporter
|
|
151
|
+
if not quiet:
|
|
152
|
+
console.print("[cyan]📄 Exporting manuscript to DOCX...[/cyan]")
|
|
153
|
+
|
|
154
|
+
exporter = DocxExporter(
|
|
155
|
+
manuscript_path=manuscript_path,
|
|
156
|
+
resolve_dois=resolve_dois,
|
|
157
|
+
include_footnotes=not no_footnotes,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Pre-flight check for poppler (if manuscript contains PDF figures)
|
|
161
|
+
_check_and_offer_poppler_installation(console, quiet, verbose)
|
|
162
|
+
|
|
163
|
+
# Perform export
|
|
164
|
+
docx_path = exporter.export()
|
|
165
|
+
|
|
166
|
+
# Success message
|
|
167
|
+
if not quiet:
|
|
168
|
+
console.print(f"[green]✅ DOCX exported:[/green] {docx_path}")
|
|
169
|
+
|
|
170
|
+
except FileNotFoundError as e:
|
|
171
|
+
console.print(f"[red]❌ Error:[/red] {e}")
|
|
172
|
+
raise click.Abort() from e
|
|
173
|
+
except Exception as e:
|
|
174
|
+
if verbose:
|
|
175
|
+
logger.error(f"DOCX export failed: {e}")
|
|
176
|
+
console.print(f"[red]❌ Export failed:[/red] {e}")
|
|
177
|
+
raise click.Abort() from e
|
|
@@ -142,6 +142,7 @@ class BuildCommand(BaseCommand):
|
|
|
142
142
|
keep_output: bool = False,
|
|
143
143
|
docx: bool = False,
|
|
144
144
|
resolve_dois: bool = False,
|
|
145
|
+
split_si: bool = False,
|
|
145
146
|
debug: bool = False,
|
|
146
147
|
quiet: bool = False,
|
|
147
148
|
container_mode: Optional[str] = None,
|
|
@@ -156,6 +157,7 @@ class BuildCommand(BaseCommand):
|
|
|
156
157
|
keep_output: Preserve existing output directory
|
|
157
158
|
docx: Also export to DOCX format
|
|
158
159
|
resolve_dois: Attempt to resolve missing DOIs (for DOCX export)
|
|
160
|
+
split_si: Split PDF into main and SI sections
|
|
159
161
|
debug: Enable debug output
|
|
160
162
|
quiet: Suppress non-critical warnings
|
|
161
163
|
container_mode: Container behavior mode
|
|
@@ -223,6 +225,10 @@ class BuildCommand(BaseCommand):
|
|
|
223
225
|
if docx:
|
|
224
226
|
self._export_docx(resolve_dois=resolve_dois, quiet=quiet, debug=debug)
|
|
225
227
|
|
|
228
|
+
# Split PDF if requested
|
|
229
|
+
if split_si:
|
|
230
|
+
self._split_pdf(pdf_path, quiet=quiet, debug=debug)
|
|
231
|
+
|
|
226
232
|
# Show helpful tips after successful build
|
|
227
233
|
self._show_build_tips()
|
|
228
234
|
|
|
@@ -252,11 +258,69 @@ class BuildCommand(BaseCommand):
|
|
|
252
258
|
self.console.print(f"[green]✅ DOCX exported:[/green] {docx_path}")
|
|
253
259
|
|
|
254
260
|
except Exception as e:
|
|
255
|
-
self.console.print(f"[yellow]⚠️ DOCX export failed:[/yellow] {e}"
|
|
261
|
+
self.console.print(f"[yellow]⚠️ DOCX export failed:[/yellow] {e}")
|
|
262
|
+
if debug:
|
|
263
|
+
import traceback
|
|
264
|
+
|
|
265
|
+
self.console.print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
266
|
+
|
|
267
|
+
def _split_pdf(self, pdf_path: Path, quiet: bool = False, debug: bool = False) -> None:
|
|
268
|
+
"""Split PDF into main and SI sections after successful PDF build.
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
pdf_path: Path to the generated PDF
|
|
272
|
+
quiet: Suppress non-essential output
|
|
273
|
+
debug: Enable debug output
|
|
274
|
+
"""
|
|
275
|
+
try:
|
|
276
|
+
from ...processors.yaml_processor import extract_yaml_metadata
|
|
277
|
+
from ...utils.file_helpers import find_manuscript_md
|
|
278
|
+
from ...utils.pdf_splitter import split_pdf
|
|
279
|
+
from ...utils.pdf_utils import get_custom_pdf_filename
|
|
280
|
+
|
|
281
|
+
if not quiet:
|
|
282
|
+
self.console.print("\n[cyan]✂️ Splitting PDF into main and SI sections...[/cyan]")
|
|
283
|
+
|
|
284
|
+
# Split the PDF
|
|
285
|
+
main_path, si_path = split_pdf(pdf_path)
|
|
286
|
+
|
|
287
|
+
if main_path and si_path:
|
|
288
|
+
# Extract metadata to generate custom filename
|
|
289
|
+
manuscript_md = find_manuscript_md(str(self.path_manager.manuscript_path))
|
|
290
|
+
yaml_metadata = extract_yaml_metadata(str(manuscript_md))
|
|
291
|
+
|
|
292
|
+
# Get base filename (e.g., "2025__saraiva_et_al__rxiv.pdf")
|
|
293
|
+
base_filename = get_custom_pdf_filename(yaml_metadata)
|
|
294
|
+
base_name = base_filename.replace(".pdf", "")
|
|
295
|
+
|
|
296
|
+
# Generate final filenames with __main and __si suffixes
|
|
297
|
+
main_filename = f"{base_name}__main.pdf"
|
|
298
|
+
si_filename = f"{base_name}__si.pdf"
|
|
299
|
+
|
|
300
|
+
# Copy split files to manuscript directory
|
|
301
|
+
final_main_path = self.path_manager.manuscript_path / main_filename
|
|
302
|
+
final_si_path = self.path_manager.manuscript_path / si_filename
|
|
303
|
+
|
|
304
|
+
shutil.copy2(main_path, final_main_path)
|
|
305
|
+
shutil.copy2(si_path, final_si_path)
|
|
306
|
+
|
|
307
|
+
if not quiet:
|
|
308
|
+
self.console.print("[green]✅ PDF split successfully:[/green]")
|
|
309
|
+
self.console.print(f" 📄 Main: {final_main_path}")
|
|
310
|
+
self.console.print(f" 📄 SI: {final_si_path}")
|
|
311
|
+
elif main_path is None and si_path is None:
|
|
312
|
+
if not quiet:
|
|
313
|
+
self.console.print("[yellow]⚠️ Could not split PDF: SI section marker not found[/yellow]")
|
|
314
|
+
else:
|
|
315
|
+
if not quiet:
|
|
316
|
+
self.console.print("[yellow]⚠️ PDF splitting partially failed[/yellow]")
|
|
317
|
+
|
|
318
|
+
except Exception as e:
|
|
319
|
+
self.console.print(f"[yellow]⚠️ PDF splitting failed:[/yellow] {e}")
|
|
256
320
|
if debug:
|
|
257
321
|
import traceback
|
|
258
322
|
|
|
259
|
-
self.console.print(f"[dim]{traceback.format_exc()}[/dim]"
|
|
323
|
+
self.console.print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
260
324
|
|
|
261
325
|
def _show_build_tips(self) -> None:
|
|
262
326
|
"""Show helpful tips after successful PDF build."""
|
|
@@ -202,9 +202,11 @@ def extract_citations_from_text(text: MarkdownContent) -> list[CitationKey]:
|
|
|
202
202
|
backtick_patterns.append(match.group(0))
|
|
203
203
|
return f"__BACKTICK_PATTERN_{len(backtick_patterns) - 1}__"
|
|
204
204
|
|
|
205
|
-
# Match
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
# IMPORTANT: Match triple backticks FIRST, then single backticks
|
|
206
|
+
# This prevents the single-backtick pattern from matching across triple-backtick blocks
|
|
207
|
+
# (e.g., from a ` before ```latex to the first ` inside the code block)
|
|
208
|
+
text_cleaned = re.sub(r"```.*?```", protect_backticks, text, flags=re.DOTALL)
|
|
209
|
+
text_cleaned = re.sub(r"`[^`]+`", protect_backticks, text_cleaned)
|
|
208
210
|
|
|
209
211
|
# Find bracketed multiple citations
|
|
210
212
|
bracketed_matches = re.findall(r"\[(@[^]]+)\]", text_cleaned)
|
|
@@ -343,6 +343,7 @@ class ConfigManager:
|
|
|
343
343
|
"bibliography": {"file": "03_REFERENCES.bib", "style": "nature"},
|
|
344
344
|
"citation_style": "numbered",
|
|
345
345
|
"enable_inline_doi_resolution": False,
|
|
346
|
+
"docx": {"hide_si": False, "figures_at_end": False},
|
|
346
347
|
"cache": {"enabled": True, "ttl_hours": 24},
|
|
347
348
|
"version": "1.0",
|
|
348
349
|
"acknowledge_rxiv_maker": True,
|
|
@@ -487,6 +487,18 @@ class DependencyManager:
|
|
|
487
487
|
)
|
|
488
488
|
)
|
|
489
489
|
|
|
490
|
+
# Poppler utilities for PDF to image conversion (DOCX export)
|
|
491
|
+
self.register_dependency(
|
|
492
|
+
DependencySpec(
|
|
493
|
+
name="pdftoppm",
|
|
494
|
+
type=DependencyType.SYSTEM_BINARY,
|
|
495
|
+
required=False, # Only needed for DOCX export with PDF figures
|
|
496
|
+
alternatives=["pdfinfo"],
|
|
497
|
+
contexts={"docx", "export"},
|
|
498
|
+
install_hint="macOS: brew install poppler | Linux: sudo apt install poppler-utils",
|
|
499
|
+
)
|
|
500
|
+
)
|
|
501
|
+
|
|
490
502
|
def register_dependency(self, spec: DependencySpec) -> None:
|
|
491
503
|
"""Register a dependency specification.
|
|
492
504
|
|
|
@@ -13,6 +13,102 @@ from ..converters.citation_processor import extract_citations_from_text
|
|
|
13
13
|
class CitationMapper:
|
|
14
14
|
"""Maps citation keys to sequential numbers for DOCX export."""
|
|
15
15
|
|
|
16
|
+
@staticmethod
|
|
17
|
+
def _format_citation_ranges(text: str) -> str:
|
|
18
|
+
"""Format consecutive citations as ranges.
|
|
19
|
+
|
|
20
|
+
Converts patterns like [1][2][3] to [1-3], [15][16] to [15-16], etc.
|
|
21
|
+
Also formats comma-separated lists like [1, 2, 3] to [1-3].
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
text: Text with numbered citations
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
Text with consecutive citations formatted as ranges
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
>>> CitationMapper._format_citation_ranges("text [1][2][3] more")
|
|
31
|
+
'text [1-3] more'
|
|
32
|
+
>>> CitationMapper._format_citation_ranges("text [1, 2, 3] more")
|
|
33
|
+
'text [1-3] more'
|
|
34
|
+
>>> CitationMapper._format_citation_ranges("text [1][3][4] more")
|
|
35
|
+
'text [1][3-4] more'
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
# Pattern 1: Handle adjacent bracketed citations [1][2][3] or [1] [2] [3]
|
|
39
|
+
def combine_adjacent(match_obj):
|
|
40
|
+
# Extract all numbers from consecutive brackets (allowing spaces between)
|
|
41
|
+
numbers = [int(n) for n in re.findall(r"\[(\d+)\]", match_obj.group(0))]
|
|
42
|
+
return CitationMapper._format_number_list(numbers)
|
|
43
|
+
|
|
44
|
+
# Find sequences of adjacent bracketed numbers (with optional spaces between)
|
|
45
|
+
text = re.sub(r"(?:\[\d+\]\s*){2,}", combine_adjacent, text)
|
|
46
|
+
|
|
47
|
+
# Pattern 2: Handle comma-separated citations within single brackets [1, 2, 3]
|
|
48
|
+
def combine_comma_separated(match_obj):
|
|
49
|
+
# Extract all numbers from comma-separated list
|
|
50
|
+
numbers_str = match_obj.group(1)
|
|
51
|
+
numbers = [int(n.strip()) for n in numbers_str.split(",")]
|
|
52
|
+
return CitationMapper._format_number_list(numbers)
|
|
53
|
+
|
|
54
|
+
text = re.sub(r"\[([\d,\s]+)\]", combine_comma_separated, text)
|
|
55
|
+
|
|
56
|
+
return text
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def _format_number_list(numbers: List[int]) -> str:
|
|
60
|
+
"""Format a list of citation numbers as ranges.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
numbers: List of citation numbers
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Formatted string with ranges
|
|
67
|
+
|
|
68
|
+
Example:
|
|
69
|
+
>>> CitationMapper._format_number_list([1, 2, 3, 5, 6, 8])
|
|
70
|
+
'[1-3, 5-6, 8]'
|
|
71
|
+
>>> CitationMapper._format_number_list([15, 16])
|
|
72
|
+
'[15-16]'
|
|
73
|
+
>>> CitationMapper._format_number_list([1, 3, 5])
|
|
74
|
+
'[1, 3, 5]'
|
|
75
|
+
"""
|
|
76
|
+
if not numbers:
|
|
77
|
+
return "[]"
|
|
78
|
+
|
|
79
|
+
# Sort numbers
|
|
80
|
+
sorted_nums = sorted(set(numbers))
|
|
81
|
+
|
|
82
|
+
# Build ranges
|
|
83
|
+
ranges = []
|
|
84
|
+
start = sorted_nums[0]
|
|
85
|
+
end = sorted_nums[0]
|
|
86
|
+
|
|
87
|
+
for num in sorted_nums[1:]:
|
|
88
|
+
if num == end + 1:
|
|
89
|
+
# Continue current range
|
|
90
|
+
end = num
|
|
91
|
+
else:
|
|
92
|
+
# End current range and start new one
|
|
93
|
+
if start == end:
|
|
94
|
+
# Single number
|
|
95
|
+
ranges.append(str(start))
|
|
96
|
+
else:
|
|
97
|
+
# Range (including 2 consecutive numbers like 15-16)
|
|
98
|
+
ranges.append(f"{start}-{end}")
|
|
99
|
+
start = num
|
|
100
|
+
end = num
|
|
101
|
+
|
|
102
|
+
# Add final range
|
|
103
|
+
if start == end:
|
|
104
|
+
# Single number
|
|
105
|
+
ranges.append(str(start))
|
|
106
|
+
else:
|
|
107
|
+
# Range (including 2 consecutive numbers like 15-16)
|
|
108
|
+
ranges.append(f"{start}-{end}")
|
|
109
|
+
|
|
110
|
+
return f"[{', '.join(ranges)}]"
|
|
111
|
+
|
|
16
112
|
def create_mapping(self, citations: List[str]) -> Dict[str, int]:
|
|
17
113
|
"""Create citation key → number mapping.
|
|
18
114
|
|
|
@@ -121,4 +217,7 @@ class CitationMapper:
|
|
|
121
217
|
for i, pattern in enumerate(email_patterns):
|
|
122
218
|
text = text.replace(f"__EMAIL_PATTERN_{i}__", pattern)
|
|
123
219
|
|
|
220
|
+
# Format consecutive citations as ranges (e.g., [1][2][3] -> [1-3])
|
|
221
|
+
text = self._format_citation_ranges(text)
|
|
222
|
+
|
|
124
223
|
return text
|