easydiffraction 0.5.5__tar.gz → 0.5.6__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.
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.github/workflows/build-docs.yml +31 -23
- easydiffraction-0.5.6/.github/workflows/draft-release-notes.yml +27 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.github/workflows/test-tutorials.yaml +1 -1
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/DEVELOPMENT.md +18 -9
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/PKG-INFO +1 -1
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/introduction/index.md +1 -1
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/plotting/plotters/plotter_plotly.py +8 -9
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/utils/utils.py +11 -0
- easydiffraction-0.5.6/tools/prepare_notebooks.py +255 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/dmsc-summer-school-2025_analysis-powder-diffraction.ipynb +911 -468
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/dmsc-summer-school-2025_analysis-powder-diffraction.py +261 -179
- easydiffraction-0.5.5/.github/workflows/update-release-draft.yml +0 -22
- easydiffraction-0.5.5/tools/nb_uncomment_pip.py +0 -108
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.github/release-drafter.yml +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.github/workflows/delete-old-runs.yml +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.github/workflows/publish-pypi.yml +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.github/workflows/scan-security.yml +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.github/workflows/test-code.yaml +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.github/workflows/test-tutorials-colab.yaml +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.github/workflows/verify-pr-labels.yml +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.gitignore +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/.prettierignore +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/CONTRIBUTING.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/LICENSE +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/README.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/deps/pycrysfml-0.1.6-py312-none-macosx_14_0_arm64.whl +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/deps/pycrysfml-0.1.6-py312-none-win_amd64.whl +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/api-reference/analysis.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/api-reference/core.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/api-reference/crystallography.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/api-reference/experiments.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/api-reference/index.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/api-reference/plotting.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/api-reference/project.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/api-reference/sample_models.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/api-reference/summary.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/api-reference/utils.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/assets/images/user-guide/data-acquisition_2d-raw-data.jpg +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/assets/images/user-guide/data-acquisition_instrument.png +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/assets/images/user-guide/data-analysis_model.png +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/assets/images/user-guide/data-analysis_refinement.png +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/assets/images/user-guide/data-reduction_1d-pattern.png +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/index.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/installation-and-setup/index.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/mkdocs.yml +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/tutorials/index.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/analysis-workflow/analysis.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/analysis-workflow/experiment.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/analysis-workflow/index.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/analysis-workflow/model.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/analysis-workflow/project.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/analysis-workflow/summary.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/concept.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/data-format.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/first-steps.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/glossary.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/index.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/_diffrn_radiation.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/_diffrn_radiation_wavelength.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/_exptl_crystal.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/_extinction.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/_pd_calib.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/atom_site.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/background.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/cell.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/expt_type.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/instrument.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/linked_phases.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/pd_meas.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/peak.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters/space_group.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/docs/user-guide/parameters.md +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/prettierrc.toml +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/pyproject.toml +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/analysis.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/calculation.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/calculators/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/calculators/calculator_base.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/calculators/calculator_crysfml.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/calculators/calculator_cryspy.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/calculators/calculator_factory.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/calculators/calculator_pdffit.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/collections/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/collections/aliases.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/collections/constraints.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/collections/joint_fit_experiments.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/minimization.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/minimizers/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/minimizers/fitting_progress_tracker.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/minimizers/minimizer_base.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/minimizers/minimizer_dfols.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/minimizers/minimizer_factory.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/minimizers/minimizer_lmfit.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/analysis/reliability_factors.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/core/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/core/constants.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/core/objects.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/core/singletons.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/crystallography/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/crystallography/crystallography.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/crystallography/space_group_lookup_table.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/collections/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/collections/background.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/collections/datastore.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/collections/excluded_regions.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/collections/linked_phases.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/components/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/components/experiment_type.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/components/instrument.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/components/peak.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/experiment.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/experiments/experiments.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/plotting/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/plotting/plotters/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/plotting/plotters/plotter_ascii.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/plotting/plotters/plotter_base.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/plotting/plotting.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/project.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/sample_models/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/sample_models/collections/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/sample_models/collections/atom_sites.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/sample_models/components/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/sample_models/components/cell.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/sample_models/components/space_group.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/sample_models/sample_model.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/sample_models/sample_models.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/summary.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/utils/__init__.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/utils/decorators.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/src/easydiffraction/utils/formatting.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/functional_tests/fitting/test_pair-distribution-function.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/functional_tests/fitting/test_powder-diffraction_constant-wavelength.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/functional_tests/fitting/test_powder-diffraction_joint-fit.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/functional_tests/fitting/test_powder-diffraction_multiphase.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/functional_tests/fitting/test_powder-diffraction_time-of-flight.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/calculators/test_calculator_base.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/calculators/test_calculator_cryspy.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/calculators/test_calculator_factory.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/collections/test_joint_fit_experiment.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/minimizers/test_fitting_progress_tracker.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/minimizers/test_minimizer_base.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/minimizers/test_minimizer_dfols.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/minimizers/test_minimizer_factory.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/minimizers/test_minimizer_lmfit.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/test_analysis.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/test_minimization.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/analysis/test_reliability_factors.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/core/test_objects.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/core/test_singletons.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/experiments/collections/test_background.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/experiments/collections/test_datastore.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/experiments/collections/test_linked_phases.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/experiments/components/test_experiment_type.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/experiments/components/test_instrument.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/experiments/components/test_peak.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/experiments/test_experiment.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/experiments/test_experiments.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/sample_models/collections/test_atom_sites.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/sample_models/components/test_cell.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/sample_models/components/test_space_group.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/sample_models/test_sample_models.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/test_project.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tests/unit_tests/test_symmetry_lookup_table.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tools/build_docs.sh +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tools/cleanup_docs.sh +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tools/create_mkdocs-yml.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tools/install_deps.sh +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tools/prepare_docs.sh +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tools/run_notebooks.sh +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tools/update_spdx-headers.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/advanced_joint-fit_pd-neut-xray-cwl_PbSO4.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/advanced_joint-fit_pd-neut-xray-cwl_PbSO4.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/basic_single-fit_pd-neut-cwl_LBCO-HRPT.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/basic_single-fit_pd-neut-cwl_LBCO-HRPT.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/cryst-struct_pd-neut-cwl_CoSiO4-D20.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/cryst-struct_pd-neut-cwl_CoSiO4-D20.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/cryst-struct_pd-neut-cwl_HS-HRPT.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/cryst-struct_pd-neut-cwl_HS-HRPT.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/cryst-struct_pd-neut-tof_Si-SEPD.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/cryst-struct_pd-neut-tof_Si-SEPD.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/cryst-struct_pd-neut-tof_multidata_NCAF-WISH.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/cryst-struct_pd-neut-tof_multidata_NCAF-WISH.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/cryst-struct_pd-neut-tof_multiphase-LBCO-Si_McStas.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/cryst-struct_pd-neut-tof_multiphase-LBCO-Si_McStas.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/NOM_9999_Si_640g_PAC_50_ff_ftfrgr_up-to-50.gr +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/NaCl.gr +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/co2sio4_d20.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/d1a_pbso4.dat +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/d1a_pbso4_first-half.dat +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/d1a_pbso4_second-half.dat +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/hrpt_hs.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/hrpt_lbco.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/lab_pbso4.dat +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/mcstas_lbco-si.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/mcstas_lbco-si.xys +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/mcstas_lbco-si_up-to-108k.xys +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/ni-q27r100-neutron_from-2.gr +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/powder_reduced_Si_2large_bank.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/reduced_LBCO.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/reduced_Si.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/sepd_si.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/wish_ncaf.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/wish_ncaf_2_9.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/wish_ncaf_4_7.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/wish_ncaf_4_7.xys +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/wish_ncaf_5_6.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/wish_ncaf_5_6.xys +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/data/wish_ybcfo_5_6.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/pdf_pd-neut-cwl_Ni.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/pdf_pd-neut-cwl_Ni.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/pdf_pd-neut-tof_Si-NOMAD.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/pdf_pd-neut-tof_Si-NOMAD.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/pdf_pd-xray_NaCl.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/pdf_pd-xray_NaCl.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/quick_single-fit_pd-neut-cwl_LBCO-HRPT.ipynb +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials/quick_single-fit_pd-neut-cwl_LBCO-HRPT.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials-drafts/cryst-struct_pd-neut-tof_multiphase-BSFTO-HRPT.py +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials-drafts/data/DREAM_mantle_bc240_nist_cif.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials-drafts/data/DREAM_mantle_bc240_nist_cif_2.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials-drafts/data/DREAM_mantle_bc240_nist_nc.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials-drafts/data/DREAM_mantle_bc240_nist_nc_2.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials-drafts/data/Si_mp-149_symmetrized_mcstas.cif +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials-drafts/hrpt_n_Bi0p88Sm0p12Fe0p94Ti0p06O3_DW_V_9x8x52_1p49_HI.xye +0 -0
- {easydiffraction-0.5.5 → easydiffraction-0.5.6}/tutorials-drafts/test_single-fit_pd-neut-tof_Si-DREAM_nc.py +0 -0
|
@@ -5,6 +5,9 @@ on:
|
|
|
5
5
|
push:
|
|
6
6
|
# Selected branches
|
|
7
7
|
branches: [develop, master, docs, patch]
|
|
8
|
+
# Runs on creating a new tag starting with 'v', e.g. 'v1.0.3'
|
|
9
|
+
tags:
|
|
10
|
+
- 'v*'
|
|
8
11
|
# Allows you to run this workflow manually from the Actions tab
|
|
9
12
|
workflow_dispatch:
|
|
10
13
|
|
|
@@ -33,18 +36,22 @@ jobs:
|
|
|
33
36
|
runs-on: ${{ matrix.os }}
|
|
34
37
|
|
|
35
38
|
steps:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
- name: Check-out repository
|
|
40
|
+
uses: actions/checkout@v4
|
|
41
|
+
with:
|
|
42
|
+
fetch-depth: 0 # full history + tags. needed to get the latest release version
|
|
39
43
|
|
|
40
44
|
# Save the latest release version of easyscience/diffraction-lib to RELEASE_VERSION
|
|
41
45
|
# RELEASE_VERSION is used in the mkdocs.yml file to set release_version.
|
|
42
46
|
# The release_version is then needed to display the latest release version in the index.md file
|
|
43
|
-
- name:
|
|
47
|
+
- name: Set RELEASE_VERSION env variable (latest easydiffraction release)
|
|
44
48
|
run: |
|
|
45
|
-
git
|
|
46
|
-
git
|
|
47
|
-
|
|
49
|
+
git fetch --tags --force
|
|
50
|
+
echo "RELEASE_VERSION=$(git describe --tags --abbrev=0)" >> "$GITHUB_ENV"
|
|
51
|
+
|
|
52
|
+
# Without this step, GITHUB_REPOSITORY is not accessible from mkdocs.yml
|
|
53
|
+
- name: Set GITHUB_REPOSITORY env variable
|
|
54
|
+
run: echo "GITHUB_REPOSITORY=$GITHUB_REPOSITORY" >> "$GITHUB_ENV"
|
|
48
55
|
|
|
49
56
|
# Activate dark mode to create documentation with Plotly charts in dark mode
|
|
50
57
|
# Need a better solution to automatically switch the chart colour theme based on the mkdocs material switcher
|
|
@@ -57,9 +64,6 @@ jobs:
|
|
|
57
64
|
# dark-mode on
|
|
58
65
|
# dark-mode status
|
|
59
66
|
|
|
60
|
-
- name: Check-out repository
|
|
61
|
-
uses: actions/checkout@v4
|
|
62
|
-
|
|
63
67
|
- name: Set up Python ${{ matrix.python-version }}
|
|
64
68
|
uses: actions/setup-python@v5
|
|
65
69
|
with:
|
|
@@ -113,7 +117,7 @@ jobs:
|
|
|
113
117
|
cp -R ${{ env.NOTEBOOKS_DIR }}/data docs/${{ env.NOTEBOOKS_DIR }}/
|
|
114
118
|
jupytext ${{ env.NOTEBOOKS_DIR }}/*.py --from py:percent --to ipynb
|
|
115
119
|
nbstripout ${{ env.NOTEBOOKS_DIR }}/*.ipynb
|
|
116
|
-
python tools/
|
|
120
|
+
python tools/prepare_notebooks.py ${{ env.NOTEBOOKS_DIR }}/
|
|
117
121
|
mv ${{ env.NOTEBOOKS_DIR }}/*.ipynb docs/${{ env.NOTEBOOKS_DIR }}/
|
|
118
122
|
|
|
119
123
|
# The following step is needed to avoid the following message during the build:
|
|
@@ -159,10 +163,10 @@ jobs:
|
|
|
159
163
|
path: site/
|
|
160
164
|
|
|
161
165
|
# Upload the static files from the site/ directory to be used in the next job
|
|
162
|
-
# This
|
|
163
|
-
#
|
|
164
|
-
- name: Upload built site as artifact for gh_pages (
|
|
165
|
-
if:
|
|
166
|
+
# This artifact is only uploaded on tagged releases (tags starting with 'v', e.g., v1.0.3)
|
|
167
|
+
# and is used to push content to gh_pages for custom domain deployment.
|
|
168
|
+
- name: Upload built site as artifact for gh_pages (tagged release)
|
|
169
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
166
170
|
uses: actions/upload-artifact@v4
|
|
167
171
|
with:
|
|
168
172
|
name: artifact # name of the artifact (without the extension zip)
|
|
@@ -205,26 +209,30 @@ jobs:
|
|
|
205
209
|
(all branches)
|
|
206
210
|
uses: actions/deploy-pages@v4
|
|
207
211
|
|
|
208
|
-
# Download built site as artifact from a previous job for gh_pages (
|
|
209
|
-
|
|
210
|
-
|
|
212
|
+
# Download built site as artifact from a previous job for gh_pages (tagged release)
|
|
213
|
+
# This artifact is only downloaded on tagged releases (tags starting with 'v', e.g., v1.0.3)
|
|
214
|
+
# and is used to push content to gh_pages for custom domain deployment.
|
|
215
|
+
- name: Download built site from previous job (tagged release)
|
|
216
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
211
217
|
uses: actions/download-artifact@v4
|
|
212
218
|
with: # name or path are taken from the upload step of the previous job
|
|
213
219
|
name: artifact
|
|
214
220
|
path: site/ # directory to extract downloaded zipped artifacts
|
|
215
221
|
|
|
216
222
|
# Push the site files created in the previous job to the gh_pages branch
|
|
223
|
+
# This push happens only for tagged releases (tags starting with 'v'),
|
|
224
|
+
# which triggers deployment to the custom domain via webhook.
|
|
225
|
+
#
|
|
217
226
|
# To be able to push to the gh_pages branch, the personal GitHub API access
|
|
218
227
|
# token GH_API_PERSONAL_ACCSESS_TOKEN must be set for this repository via
|
|
219
228
|
# https://github.com/easyscience/diffraction-lib/settings/secrets/actions
|
|
220
|
-
#
|
|
221
|
-
# Deploying is done with a webhook:
|
|
229
|
+
# Then the gh_pages branch is used to deploy the site to the custom domain.
|
|
230
|
+
# Deploying is done with a webhook added via:
|
|
222
231
|
# https://github.com/easyscience/diffraction-lib/settings/hooks
|
|
223
|
-
# This is done for the gh_pages branch when the site is tested with a step above
|
|
224
232
|
- name:
|
|
225
233
|
Deploy to gh_pages branch to trigger deployment to custom domain
|
|
226
|
-
(
|
|
227
|
-
if:
|
|
234
|
+
(tagged release)
|
|
235
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
228
236
|
uses: s0/git-publish-subdir-action@develop
|
|
229
237
|
env:
|
|
230
238
|
GITHUB_TOKEN: ${{ secrets.GH_API_PERSONAL_ACCSESS_TOKEN }}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Drafts your next Release notes as pull requests are merged into
|
|
2
|
+
# default branch
|
|
3
|
+
|
|
4
|
+
name: Update release draft
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
# Runs on pushes targeting the default branch
|
|
8
|
+
push:
|
|
9
|
+
branches:
|
|
10
|
+
- main
|
|
11
|
+
- master
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
draft-release-notes:
|
|
15
|
+
permissions:
|
|
16
|
+
# write permission is required to create a github release
|
|
17
|
+
contents: write
|
|
18
|
+
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- name: Drafts the next Release notes
|
|
23
|
+
uses: release-drafter/release-drafter@v6
|
|
24
|
+
with:
|
|
25
|
+
disable-autolabeler: true
|
|
26
|
+
env:
|
|
27
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -151,7 +151,7 @@ jobs:
|
|
|
151
151
|
run: |
|
|
152
152
|
jupytext ${{ env.NOTEBOOKS_DIR }}/*.py --from py:percent --to ipynb
|
|
153
153
|
nbstripout ${{ env.NOTEBOOKS_DIR }}/*.ipynb
|
|
154
|
-
python tools/
|
|
154
|
+
python tools/prepare_notebooks.py ${{ env.NOTEBOOKS_DIR }}/
|
|
155
155
|
|
|
156
156
|
- name: Run tutorials as Jupyter Notebooks (using src/ as the source dir)
|
|
157
157
|
shell: bash
|
|
@@ -106,22 +106,31 @@ This is an example of a workflow that describes the development process.
|
|
|
106
106
|
```
|
|
107
107
|
- Add extra files to build documentation (from `../assets-docs/` and
|
|
108
108
|
`../assets-branding/` directories)
|
|
109
|
+
|
|
109
110
|
```bash
|
|
110
111
|
cp -R ../assets-docs/docs/assets/ docs/assets/
|
|
111
112
|
cp -R ../assets-docs/includes/ includes/
|
|
112
113
|
cp -R ../assets-docs/overrides/ overrides/
|
|
114
|
+
|
|
113
115
|
mkdir -p docs/assets/images/
|
|
114
|
-
cp ../assets-branding/
|
|
115
|
-
cp ../assets-branding/
|
|
116
|
-
cp ../assets-branding/
|
|
117
|
-
cp ../assets-branding/
|
|
118
|
-
cp ../assets-branding/
|
|
116
|
+
cp ../assets-branding/easydiffraction/hero/dark.png docs/assets/images/hero_dark.png
|
|
117
|
+
cp ../assets-branding/easydiffraction/hero/light.png docs/assets/images/hero_light.png
|
|
118
|
+
cp ../assets-branding/easydiffraction/logos/dark.svg docs/assets/images/logo_dark.svg
|
|
119
|
+
cp ../assets-branding/easydiffraction/logos/light.svg docs/assets/images/logo_light.svg
|
|
120
|
+
cp ../assets-branding/easydiffraction/icons/color.png docs/assets/images/favicon.png
|
|
121
|
+
|
|
119
122
|
mkdir -p overrides/.icons/
|
|
120
|
-
cp ../assets-branding/
|
|
121
|
-
cp ../assets-branding/
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
cp ../assets-branding/easydiffraction/icons/bw.svg overrides/.icons/easydiffraction.svg
|
|
124
|
+
cp ../assets-branding/easyscience-org/icons/eso-icon_bw.svg overrides/.icons/easyscience.svg
|
|
125
|
+
|
|
126
|
+
jupytext tutorials/*.py --from py:percent --to ipynb
|
|
127
|
+
nbstripout tutorials/*.ipynb
|
|
128
|
+
cp tutorials/*.ipynb docs/tutorials/
|
|
129
|
+
cp -R tutorials/data docs/tutorials/
|
|
130
|
+
|
|
131
|
+
python tools/create_mkdocs-yml.py
|
|
124
132
|
```
|
|
133
|
+
|
|
125
134
|
- Build documentation with MkDocs - static site generator
|
|
126
135
|
```bash
|
|
127
136
|
export JUPYTER_PLATFORM_DIRS=1
|
|
@@ -49,7 +49,7 @@ Zenodo, each with a version-specific Digital Object Identifier (DOI).
|
|
|
49
49
|
Citation details in various styles (e.g., APA, MLA) and formats (e.g., BibTeX,
|
|
50
50
|
JSON)
|
|
51
51
|
are available on the
|
|
52
|
-
[Zenodo archive page](https://doi.org/10.5281/zenodo.
|
|
52
|
+
[Zenodo archive page](https://doi.org/10.5281/zenodo.16806521).
|
|
53
53
|
|
|
54
54
|
## Contributing
|
|
55
55
|
|
|
@@ -12,7 +12,7 @@ except ImportError:
|
|
|
12
12
|
display = None
|
|
13
13
|
HTML = None
|
|
14
14
|
|
|
15
|
-
from easydiffraction.utils.utils import
|
|
15
|
+
from easydiffraction.utils.utils import is_github_ci
|
|
16
16
|
|
|
17
17
|
from .plotter_base import SERIES_CONFIG
|
|
18
18
|
from .plotter_base import PlotterBase
|
|
@@ -106,14 +106,13 @@ class PlotlyPlotter(PlotterBase):
|
|
|
106
106
|
|
|
107
107
|
# Show the figure
|
|
108
108
|
|
|
109
|
-
#
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
# application/vnd.plotly.v1+json
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
|
|
116
|
-
if is_pycharm() or display is None or HTML is None:
|
|
109
|
+
# In GitHub CI builds (e.g., during Jupyter Book generation), avoid
|
|
110
|
+
#
|
|
111
|
+
# calling `fig.show()`
|
|
112
|
+
# because it can emit `application/vnd.plotly.v1+json` outputs that some toolchains warn about.
|
|
113
|
+
# Instead, convert the figure to HTML and display it directly.
|
|
114
|
+
# Use a regular Figure and show it
|
|
115
|
+
if not is_github_ci() or display is None or HTML is None:
|
|
117
116
|
fig.show(config=config)
|
|
118
117
|
else:
|
|
119
118
|
html_fig = pio.to_html(
|
|
@@ -101,6 +101,17 @@ def is_pycharm() -> bool:
|
|
|
101
101
|
return os.environ.get('PYCHARM_HOSTED') == '1'
|
|
102
102
|
|
|
103
103
|
|
|
104
|
+
def is_github_ci() -> bool:
|
|
105
|
+
"""
|
|
106
|
+
Determines if the current process is running in GitHub Actions CI.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
bool: True if the environment variable ``GITHUB_ACTIONS`` is set
|
|
110
|
+
(Always "true" on GitHub Actions), False otherwise.
|
|
111
|
+
"""
|
|
112
|
+
return os.environ.get('GITHUB_ACTIONS') is not None
|
|
113
|
+
|
|
114
|
+
|
|
104
115
|
def render_table(
|
|
105
116
|
columns_data,
|
|
106
117
|
columns_alignment,
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Uncomment `# !pip ...` and `# ed.download_from_repository ...` lines in Jupyter
|
|
4
|
+
notebooks so they become `!pip ...` and `ed.download_from_repository ...` respectively.
|
|
5
|
+
|
|
6
|
+
Additionally, adjust cell metadata and tags according to DMSC Summer School rules:
|
|
7
|
+
- If a cell has the `dmsc-school-hint` or `solution` tag, add
|
|
8
|
+
`{"jupyter": {"source_hidden": true}}` so it is collapsed by default.
|
|
9
|
+
- If a cell has the `remove-cell` tag, replace it with `hide_in_docs`.
|
|
10
|
+
- If a cell has the `non-editable` tag, set `editable: false` in metadata.
|
|
11
|
+
- Remove all tags except `hide_in_docs`.
|
|
12
|
+
|
|
13
|
+
Notes:
|
|
14
|
+
- Operates only on code cells for uncommenting (does not touch markdown sources),
|
|
15
|
+
but processes metadata/tags for ALL cells.
|
|
16
|
+
- Matches lines that start with optional whitespace, then `# !pip`
|
|
17
|
+
(e.g., " # !pip install ...").
|
|
18
|
+
- Also matches lines that start with optional whitespace, then
|
|
19
|
+
`# ed.download_from_repository` (e.g., " # ed.download_from_repository(...)").
|
|
20
|
+
- Rewrites to keep the original indentation and replace the leading
|
|
21
|
+
"# !pip" with "!pip", and "# ed.download_from_repository" with "ed.download_from_repository".
|
|
22
|
+
- Processes one or more paths (files or directories) given as CLI args,
|
|
23
|
+
recursively for directories.
|
|
24
|
+
|
|
25
|
+
New CLI options:
|
|
26
|
+
- `--remove-cell true|false` to control how cells tagged `remove-cell` are handled:
|
|
27
|
+
remove entirely (true) or map tag to `hide_in_docs` (false, default).
|
|
28
|
+
- `--strip-solution true|false` to control handling of cells tagged `solution`:
|
|
29
|
+
replace content with placeholder (true) or collapse via source_hidden (false, default).
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
import argparse
|
|
35
|
+
import re
|
|
36
|
+
import sys
|
|
37
|
+
from pathlib import Path
|
|
38
|
+
|
|
39
|
+
import nbformat
|
|
40
|
+
from nbformat.validator import normalize
|
|
41
|
+
|
|
42
|
+
# Regex: beginning-of-line, capture leading whitespace, then "#", spaces, then "!pip"
|
|
43
|
+
_PIP_PATTERN = re.compile(r'^(\s*)#\s*!pip\b')
|
|
44
|
+
# Regex: beginning-of-line, capture leading whitespace, then "#", spaces, then "ed.download_from_repository"
|
|
45
|
+
_ED_PATTERN = re.compile(r'^(\s*)#\s*ed\.download_from_repository\b')
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def fix_cell_source(src: str) -> tuple[str, int]:
|
|
49
|
+
"""
|
|
50
|
+
Replace lines starting with optional whitespace + '# !pip' with '!pip',
|
|
51
|
+
and lines starting with optional whitespace + '# ed.download_from_repository'
|
|
52
|
+
with 'ed.download_from_repository'.
|
|
53
|
+
Returns the updated source and number of replacements performed.
|
|
54
|
+
"""
|
|
55
|
+
changed = 0
|
|
56
|
+
new_lines: list[str] = []
|
|
57
|
+
for line in src.splitlines(keepends=False):
|
|
58
|
+
orig_line = line
|
|
59
|
+
# Replace # !pip
|
|
60
|
+
if _PIP_PATTERN.match(line):
|
|
61
|
+
line = _PIP_PATTERN.sub(r'\1!pip', line, count=1)
|
|
62
|
+
# Replace # ed.download_from_repository
|
|
63
|
+
if _ED_PATTERN.match(line):
|
|
64
|
+
line = _ED_PATTERN.sub(r'\1ed.download_from_repository', line, count=1)
|
|
65
|
+
if line != orig_line:
|
|
66
|
+
changed += 1
|
|
67
|
+
new_lines.append(line)
|
|
68
|
+
return ('\n'.join(new_lines), changed)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def fix_cell_metadata(cell, *, remove_cell: bool, strip_solution: bool) -> tuple[int, bool]:
|
|
72
|
+
"""
|
|
73
|
+
Apply tag/metadata rules:
|
|
74
|
+
- 'dmsc-school-hint' or 'solution' -> jupyter.source_hidden = True (unless strip_solution is True)
|
|
75
|
+
- 'remove-cell' -> either remove cell (if remove_cell=True) or rename to 'hide_in_docs'
|
|
76
|
+
- 'non-editable' -> editable = False
|
|
77
|
+
- keep only 'hide_in_docs' tag, drop all others (unless cell removed)
|
|
78
|
+
- if strip_solution=True and 'solution' tag present, replace source with placeholder instead of collapsing
|
|
79
|
+
Returns (number of changes applied, remove_this_cell flag).
|
|
80
|
+
"""
|
|
81
|
+
changed = 0
|
|
82
|
+
remove_flag = False
|
|
83
|
+
md = cell.metadata
|
|
84
|
+
|
|
85
|
+
# Normalize tags list
|
|
86
|
+
tags = list(md.get('tags', []))
|
|
87
|
+
|
|
88
|
+
# Check for remove-cell tag and remove_cell flag
|
|
89
|
+
if 'remove-cell' in tags:
|
|
90
|
+
if remove_cell:
|
|
91
|
+
# Mark cell for removal
|
|
92
|
+
remove_flag = True
|
|
93
|
+
# Count change if tags existed (since removal is a change)
|
|
94
|
+
if tags:
|
|
95
|
+
changed += 1
|
|
96
|
+
# Skip further processing for this cell
|
|
97
|
+
return changed, remove_flag
|
|
98
|
+
else:
|
|
99
|
+
# rename remove-cell -> hide_in_docs (without duplicating)
|
|
100
|
+
new_tags = []
|
|
101
|
+
seen_hide = 'hide_in_docs' in tags
|
|
102
|
+
for t in tags:
|
|
103
|
+
if t == 'remove-cell':
|
|
104
|
+
if not seen_hide:
|
|
105
|
+
new_tags.append('hide_in_docs')
|
|
106
|
+
seen_hide = True
|
|
107
|
+
else:
|
|
108
|
+
new_tags.append(t)
|
|
109
|
+
if new_tags != tags:
|
|
110
|
+
tags = new_tags
|
|
111
|
+
changed += 1
|
|
112
|
+
|
|
113
|
+
# Handle 'solution' tag with strip_solution flag
|
|
114
|
+
if strip_solution and ('solution' in tags):
|
|
115
|
+
if getattr(cell, 'source', None) != '# Insert your solution:':
|
|
116
|
+
cell.source = '# Insert your solution:'
|
|
117
|
+
changed += 1
|
|
118
|
+
# Do not add jupyter.source_hidden in this case
|
|
119
|
+
else:
|
|
120
|
+
# Add jupyter.source_hidden when hint or solution tag present
|
|
121
|
+
if ('dmsc-school-hint' in tags) or ('solution' in tags):
|
|
122
|
+
jup = md.get('jupyter', {})
|
|
123
|
+
if jup.get('source_hidden') is not True:
|
|
124
|
+
jup['source_hidden'] = True
|
|
125
|
+
md['jupyter'] = jup
|
|
126
|
+
changed += 1
|
|
127
|
+
|
|
128
|
+
# 3) add editable: false for non-editable tag
|
|
129
|
+
if 'non-editable' in tags:
|
|
130
|
+
if md.get('editable') is not False:
|
|
131
|
+
md['editable'] = False
|
|
132
|
+
changed += 1
|
|
133
|
+
|
|
134
|
+
# 4) keep only 'hide_in_docs' and drop empty tag arrays from metadata, unless removing cell
|
|
135
|
+
if not remove_flag:
|
|
136
|
+
keep = ['hide_in_docs'] if 'hide_in_docs' in tags else []
|
|
137
|
+
|
|
138
|
+
if keep: # we want to keep only 'hide_in_docs'
|
|
139
|
+
if md.get('tags') != keep:
|
|
140
|
+
md['tags'] = keep
|
|
141
|
+
changed += 1
|
|
142
|
+
else:
|
|
143
|
+
# remove empty tags key if present
|
|
144
|
+
if 'tags' in md:
|
|
145
|
+
# count as change if previously non-empty
|
|
146
|
+
if md['tags']:
|
|
147
|
+
changed += 1
|
|
148
|
+
md.pop('tags', None)
|
|
149
|
+
|
|
150
|
+
return changed, remove_flag
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def process_notebook(path: Path, *, remove_cell: bool, strip_solution: bool) -> int:
|
|
154
|
+
"""
|
|
155
|
+
Process a single .ipynb file.
|
|
156
|
+
- Uncomment magic/commented lines in code cells.
|
|
157
|
+
- Adjust cell metadata/tags as per school rules.
|
|
158
|
+
Returns number of changes made.
|
|
159
|
+
"""
|
|
160
|
+
nb = nbformat.read(path, as_version=4)
|
|
161
|
+
total_changes = 0
|
|
162
|
+
new_cells = []
|
|
163
|
+
for cell in nb.cells:
|
|
164
|
+
# Source-only changes for code cells
|
|
165
|
+
if cell.cell_type == 'code':
|
|
166
|
+
new_src, changes = fix_cell_source(cell.source or '')
|
|
167
|
+
if changes:
|
|
168
|
+
cell.source = new_src
|
|
169
|
+
total_changes += changes
|
|
170
|
+
# Metadata/tag changes for all cells
|
|
171
|
+
md_changes, remove_it = fix_cell_metadata(cell, remove_cell=remove_cell, strip_solution=strip_solution)
|
|
172
|
+
total_changes += md_changes
|
|
173
|
+
if not remove_it:
|
|
174
|
+
new_cells.append(cell)
|
|
175
|
+
nb.cells = new_cells
|
|
176
|
+
|
|
177
|
+
# Normalize/add missing IDs if needed, even when no source/metadata changes were made
|
|
178
|
+
need_normalize = any('id' not in cell for cell in nb.cells)
|
|
179
|
+
if total_changes or need_normalize:
|
|
180
|
+
normalize(nb)
|
|
181
|
+
nbformat.write(nb, path)
|
|
182
|
+
return total_changes + (1 if need_normalize and not total_changes else 0)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def iter_notebooks(paths: list[Path]):
|
|
186
|
+
for p in paths:
|
|
187
|
+
if p.is_dir():
|
|
188
|
+
yield from (q for q in p.rglob('*.ipynb') if q.is_file())
|
|
189
|
+
elif p.is_file() and p.suffix == '.ipynb':
|
|
190
|
+
yield p
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def main(argv: list[str]) -> int:
|
|
194
|
+
ap = argparse.ArgumentParser(
|
|
195
|
+
description=(
|
|
196
|
+
"Uncomment '# !pip ...' and '# ed.download_from_repository ...' in code cells, "
|
|
197
|
+
"and adjust cell metadata/tags (collapse hints/solutions, map 'remove-cell' "
|
|
198
|
+
"to 'hide_in_docs' or remove cells, keep only 'hide_in_docs', and mark 'non-editable' cells as not editable)."
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
ap.add_argument('paths', nargs='+', help='Notebook files or directories to process')
|
|
202
|
+
ap.add_argument('--dry-run', action='store_true', help='Report changes without writing files')
|
|
203
|
+
ap.add_argument(
|
|
204
|
+
'--remove-cell',
|
|
205
|
+
dest='remove_cell',
|
|
206
|
+
type=lambda s: str(s).lower() == 'true',
|
|
207
|
+
default=False,
|
|
208
|
+
help='true: remove cells tagged "remove-cell"; false (default): map tag to hide_in_docs',
|
|
209
|
+
)
|
|
210
|
+
ap.add_argument(
|
|
211
|
+
'--strip-solution',
|
|
212
|
+
dest='strip_solution',
|
|
213
|
+
type=lambda s: str(s).lower() == 'true',
|
|
214
|
+
default=False,
|
|
215
|
+
help='true: replace content of cells tagged "solution" with placeholder; false (default): collapse via source_hidden',
|
|
216
|
+
)
|
|
217
|
+
args = ap.parse_args(argv)
|
|
218
|
+
|
|
219
|
+
targets = list(iter_notebooks([Path(p) for p in args.paths]))
|
|
220
|
+
if not targets:
|
|
221
|
+
print('No .ipynb files found.', file=sys.stderr)
|
|
222
|
+
return 1
|
|
223
|
+
|
|
224
|
+
total_files = 0
|
|
225
|
+
total_changes = 0
|
|
226
|
+
for nb_path in targets:
|
|
227
|
+
changes = 0
|
|
228
|
+
if args.dry_run:
|
|
229
|
+
nb = nbformat.read(nb_path, as_version=4)
|
|
230
|
+
for cell in nb.cells:
|
|
231
|
+
if cell.cell_type == 'code':
|
|
232
|
+
_, c = fix_cell_source(cell.source or '')
|
|
233
|
+
changes += c
|
|
234
|
+
md_c, remove_it = fix_cell_metadata(cell, remove_cell=args.remove_cell, strip_solution=args.strip_solution)
|
|
235
|
+
changes += md_c
|
|
236
|
+
if remove_it:
|
|
237
|
+
changes += 1 # count removal as a change
|
|
238
|
+
else:
|
|
239
|
+
changes = process_notebook(nb_path, remove_cell=args.remove_cell, strip_solution=args.strip_solution)
|
|
240
|
+
|
|
241
|
+
if changes:
|
|
242
|
+
action = 'WOULD UPDATE' if args.dry_run else 'UPDATED'
|
|
243
|
+
print(f'{action}: {nb_path} ({changes} change(s))')
|
|
244
|
+
total_files += 1
|
|
245
|
+
total_changes += changes
|
|
246
|
+
|
|
247
|
+
if total_files == 0:
|
|
248
|
+
print('No changes needed.')
|
|
249
|
+
else:
|
|
250
|
+
print(f'Done. Files changed: {total_files}, total changes: {total_changes}')
|
|
251
|
+
return 0
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
if __name__ == '__main__':
|
|
255
|
+
raise SystemExit(main(sys.argv[1:]))
|