diff --git a/.github/workflows/docs_workflow.yml b/.github/workflows/docs_workflow.yml index ee2051c19..3cb218f06 100644 --- a/.github/workflows/docs_workflow.yml +++ b/.github/workflows/docs_workflow.yml @@ -58,7 +58,7 @@ jobs: set -e cd conda_package/docs conda activate mpas_tools_dev - sphinx-multiversion . _build/html + DOCS_VERSION=${{ github.ref_name }} make versioned-html - name: Copy Docs and Commit run: | set -e @@ -66,17 +66,26 @@ jobs: conda activate mpas_tools_dev # gh-pages branch must already exist git clone https://github.com/MPAS-Dev/MPAS-Tools.git --branch gh-pages --single-branch gh-pages + + # Only replace docs in a directory with the destination branch name with latest changes. Docs for + # releases should be untouched. + rm -rf gh-pages/${{ github.ref_name }} + + # don't clobber existing release versions (in case we retroactively fixed them) + cp -r _build/html/${{ github.ref_name }} gh-pages/ + + mkdir -p gh-pages/shared + cp shared/version-switcher.js gh-pages/shared/version-switcher.js + + # Update the list of versions with all versions in the gh-pages directory. + python generate_versions_json.py + # Make sure we're in the gh-pages directory. cd gh-pages # Create `.nojekyll` (if it doesn't already exist) for proper GH Pages configuration. touch .nojekyll # Add `index.html` to point to the `master` branch automatically. printf '' > index.html - # Only replace docs in a directory with the destination branch name with latest changes. Docs for - # releases should be untouched. - rm -rf ${{ github.head_ref || github.ref_name }} - # don't clobber existing release versions (in case we retroactively fixed them) - cp -r -n ../_build/html/* . # Configure git using GitHub Actions credentials. git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" diff --git a/conda_package/dev-spec.txt b/conda_package/dev-spec.txt index 61a7c6c93..ead2a9c9f 100644 --- a/conda_package/dev-spec.txt +++ b/conda_package/dev-spec.txt @@ -35,6 +35,5 @@ setuptools # Documentation sphinx -sphinx-multiversion mock sphinx_rtd_theme diff --git a/conda_package/docs/Makefile b/conda_package/docs/Makefile index d3fbff817..f74cca1c3 100644 --- a/conda_package/docs/Makefile +++ b/conda_package/docs/Makefile @@ -8,10 +8,35 @@ SPHINXPROJ = mpas_tools SOURCEDIR = . BUILDDIR = _build +# Build into a versioned subdirectory +versioned-html: + @echo "Building version: $(DOCS_VERSION)" + $(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)/html/$(DOCS_VERSION)" + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html/$(DOCS_VERSION)." + @echo "Setting up shared version switcher for local preview..." + mkdir -p _build/html/shared + cp shared/version-switcher.js _build/html/shared/version-switcher.js + python generate_versions_json.py --local + +# Override html target to include local setup +html: + $(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)/html" + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +clean: + rm -rf generated + @$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +clean-versioned-html: + rm -rf $(BUILDDIR)/html/* + @echo "Cleaned versioned HTML builds." + .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new diff --git a/conda_package/docs/_static/style.css b/conda_package/docs/_static/style.css index 6cbfde333..02b08965f 100644 --- a/conda_package/docs/_static/style.css +++ b/conda_package/docs/_static/style.css @@ -2,3 +2,28 @@ max-width: 1200px !important; } +#version-switcher select { + background-color: #2980b9; + color: white; + border: none; + border-radius: 4px; + padding: 4px 30px 4px 10px; + font-size: 0.9em; + appearance: none; /* Remove default dropdown arrow */ + background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg fill='white' height='10' viewBox='0 0 24 24' width='10' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 10px center; + background-size: 12px; + } + + #version-switcher select:focus { + outline: none; + box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.4); + background-color: #2c89c4; /* slightly lighter blue on focus */ + } + + /* Selected item in the dropdown menu */ + #version-switcher option:checked { + background-color: #dddddd; /* for selected */ + color: black; + } diff --git a/conda_package/docs/_templates/layout.html b/conda_package/docs/_templates/layout.html index efc29758f..f628cb13d 100644 --- a/conda_package/docs/_templates/layout.html +++ b/conda_package/docs/_templates/layout.html @@ -1,5 +1,27 @@ {% extends "!layout.html" %} + {% block extrahead %} {% endblock %} +{% block footer %} + {{ super() }} + + + + + + + + + + +{% endblock %} diff --git a/conda_package/docs/_templates/versions.html b/conda_package/docs/_templates/versions.html deleted file mode 100644 index 625a9a384..000000000 --- a/conda_package/docs/_templates/versions.html +++ /dev/null @@ -1,28 +0,0 @@ -{%- if current_version %} -
- - Other Versions - v: {{ current_version.name }} - - -
- {%- if versions.tags %} -
-
Tags
- {%- for item in versions.tags %} -
{{ item.name }}
- {%- endfor %} -
- {%- endif %} - {%- if versions.branches %} -
-
Branches
- {%- for item in versions.branches %} -
{{ item.name }}
- {%- endfor %} -
- {%- endif %} -
-
-{%- endif %} - diff --git a/conda_package/docs/building_docs.rst b/conda_package/docs/building_docs.rst index 189014ba7..329e62e93 100644 --- a/conda_package/docs/building_docs.rst +++ b/conda_package/docs/building_docs.rst @@ -9,10 +9,21 @@ To make a local test build of the documentation, it is easiest to follow the ``mpas_tools`` package. The development environment includes the packages needed to build the documentation. Simply run: -code-block:: +.. code-block:: bash - export DOCS_VERSION="test" cd conda_package/docs - make html + DOCS_VERSION=master make versioned-html -Then, you can view the documentation by opening ``_build/html/index.html``. +**************************** +Previewing the Documentation +**************************** + +To preview the documentation locally, open the ``index.html`` file in the +``_build/html/master`` directory with your browser or try: + +.. code-block:: bash + + cd _build/html + python -m http.server 8000 + +Then, open http://0.0.0.0:8000/master/ in your browser. diff --git a/conda_package/docs/conf.py b/conda_package/docs/conf.py index 5d5e67ded..6cac7a1df 100644 --- a/conda_package/docs/conf.py +++ b/conda_package/docs/conf.py @@ -27,7 +27,6 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ['sphinx_rtd_theme', - 'sphinx_multiversion', 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'sphinx.ext.intersphinx', @@ -191,14 +190,6 @@ # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] -html_sidebars = { - "**": [ - "versions.html", - ], +html_context = { + "current_version": os.getenv("DOCS_VERSION", "master"), } - -# -- Options sphinx-multiversion ------------------------------------------- -# Include tags like "tags/1.0.0" -- 0.0.1, 0.0.10 don't build -smv_tag_whitelist = r'^(?!(0.0.1|0.0.10))\d+\.\d+.\d+$' -smv_branch_whitelist = 'master' -smv_remote_whitelist = 'origin' diff --git a/conda_package/docs/generate_versions_json.py b/conda_package/docs/generate_versions_json.py new file mode 100644 index 000000000..f1b7c7157 --- /dev/null +++ b/conda_package/docs/generate_versions_json.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +import argparse +import json +import os + +# Mode: local or production +parser = argparse.ArgumentParser( + description='Generate versions.json for MPAS-Tools documentation.') +parser.add_argument( + '--local', + action='store_true', + help='Generate versions.json for local build.' +) +args = parser.parse_args() +local = args.local +base_dir = '_build/html' if local else 'gh-pages' +shared_dir = os.path.join(base_dir, 'shared') + +entries = [] + +if not os.path.exists(base_dir) or not os.listdir(base_dir): + raise FileNotFoundError( + f"Base directory '{base_dir}' does not exist or is empty.") + +versions = sorted(os.listdir(base_dir), reverse=True) +if 'master' in versions: + versions.insert(0, versions.pop(versions.index('master'))) + +for name in versions: + path = os.path.join(base_dir, name) + if os.path.isdir(path) and name not in ('shared', '.git'): + entries.append({ + 'version': name, + 'url': f'../{name}/' if local else f'/MPAS-Tools/{name}/' + }) + +os.makedirs(shared_dir, exist_ok=True) +with open(os.path.join(shared_dir, 'versions.json'), 'w') as f: + json.dump(entries, f, indent=2) diff --git a/conda_package/docs/index.rst b/conda_package/docs/index.rst index 3dede4a94..02f775a4a 100644 --- a/conda_package/docs/index.rst +++ b/conda_package/docs/index.rst @@ -33,7 +33,13 @@ analyzing simulations, and in other MPAS-related workflows. vector +.. toctree:: + :caption: Visualization + :maxdepth: 2 + visualization + mpas_to_xdmf + paraview_extractor .. toctree:: :caption: Landice Tools diff --git a/conda_package/docs/making_changes.rst b/conda_package/docs/making_changes.rst index 98aae413c..b339d077c 100644 --- a/conda_package/docs/making_changes.rst +++ b/conda_package/docs/making_changes.rst @@ -162,20 +162,3 @@ needs to match: {% set name = "mpas_tools" %} {% set version = "0.6.0" %} - -Third, Add the new version to the :ref:`versions` in the documentation. - -.. code-block:: - - `v0.6.0`_ `0.6.0`_ - ================ =============== - - ... - - .. _`v0.6.0`: ../0.6.0/index.html - .. _`0.6.0`: https://github.com/MPAS-Dev/MPAS-Analysis/tree/0.6.0 - - -The new links won't be valid until a new release is made and Azure Pipelines -has generated the associated documentation. Eventually, it should be possible -to do this automatically but that has not yet been implemented. diff --git a/conda_package/docs/mpas_to_xdmf.rst b/conda_package/docs/mpas_to_xdmf.rst index d18dbbd2f..08c68f14e 100644 --- a/conda_package/docs/mpas_to_xdmf.rst +++ b/conda_package/docs/mpas_to_xdmf.rst @@ -139,10 +139,13 @@ ParaView for visualization. Follow these steps: 2. **Choose the Correct Reader**: When opening the ``.xdmf`` file, ParaView will prompt you to select one of three readers: + - **Xdmf3 Reader S**: This reader is optimized for static datasets without time information. It is not suitable for time-varying MPAS data. + - **Xdmf3 Reader T**: This reader is designed for time-varying datasets and is the preferred choice for MPAS data converted with this tool. + - **XDMF Reader**: This is an older reader that may not fully support modern XDMF features and should generally be avoided. diff --git a/conda_package/docs/paraview_extractor.rst b/conda_package/docs/paraview_extractor.rst index bca1bdc01..103116169 100644 --- a/conda_package/docs/paraview_extractor.rst +++ b/conda_package/docs/paraview_extractor.rst @@ -64,6 +64,8 @@ additional storage space. Since the extractor is fairly complex with a lot of possible use cases, we will describe its functionality in several examples. +.. _extract_temperature: + Extracting a Temperature Time-series ------------------------------------ @@ -273,7 +275,7 @@ The resulting fields are named: timeDaily_avg_layerThickness_maxLevelCell Indexing Time ------------------------------------- +------------- Time can also be indexed like the other dimensions, but it is not passed to the ``dimension_list`` argument but instead to the ``time`` argument. The time @@ -453,7 +455,7 @@ Here is the bottom temperature in such a plot: :align: center Extracting a Region ------------------------------------- +------------------- Some simulations are focused on a small region, even though the entire globe is included in the mesh. For such situations, we provide a way to extract a @@ -492,6 +494,8 @@ In this example, we extract sea surface temperature only in the Southern Ocean: :width: 500 px :align: center +.. _paraview_macros: + ParaView Macros --------------- diff --git a/conda_package/docs/shared/version-switcher.js b/conda_package/docs/shared/version-switcher.js new file mode 100644 index 000000000..2fd806393 --- /dev/null +++ b/conda_package/docs/shared/version-switcher.js @@ -0,0 +1,42 @@ +(async function () { + const container = document.getElementById("version-switcher"); + if (!container) return; + + const metaVersion = document.querySelector('meta[name="doc-version"]'); + const currentVersion = metaVersion ? metaVersion.content : "unknown"; + console.log("Stored current version:", currentVersion); + + async function fetchVersions() { + try { + const res = await fetch("/shared/versions.json"); + if (!res.ok) throw new Error(); + return await res.json(); + } catch { + const res = await fetch("../shared/versions.json"); + return await res.json(); + } + } + + const versions = await fetchVersions(); + + const select = document.createElement("select"); + select.style.marginLeft = "1em"; + select.onchange = () => { + window.location.href = select.value; + }; + + versions.forEach(({ version, url }) => { + const option = document.createElement("option"); + option.value = url; + option.textContent = version; + if (url.includes(`/${currentVersion}/`)) { + option.selected = true; + } + select.appendChild(option); + }); + + const label = document.createElement("label"); + label.textContent = "Version: "; + label.appendChild(select); + container.appendChild(label); + })(); diff --git a/conda_package/docs/testing_changes.rst b/conda_package/docs/testing_changes.rst index b34347368..7f0bdd54d 100644 --- a/conda_package/docs/testing_changes.rst +++ b/conda_package/docs/testing_changes.rst @@ -35,20 +35,7 @@ You should now find that ``mpas_tools`` can be imported in python codes and the various scripts and entry points are available in the path. If you have already created the ``mpas_tools_dev`` environment, it may be best -to remove it (see below) and create it again. If you are in a rush, you can -use: - -.. code-block:: bash - - conda env update -f ./dev_environment - conda activate mpas_tools_dev - python -m pip install --no-deps --no-build-isolation -e . - -to update the existing environment and make sure ``mpas_tools`` in the -environment points to your current branch. - -There is no need to build a conda package, as previous instructions had -suggested. +to remove it (see below) and create it again. Removing the test environment ***************************** diff --git a/conda_package/mpas_tools/ocean/viz/transect/__init__.py b/conda_package/mpas_tools/ocean/viz/transect/__init__.py index 65605b0e4..d4ae55df4 100644 --- a/conda_package/mpas_tools/ocean/viz/transect/__init__.py +++ b/conda_package/mpas_tools/ocean/viz/transect/__init__.py @@ -5,6 +5,7 @@ from mpas_tools.ocean.viz.transect.vert import ( # noqa: F401 compute_transect, find_transect_levels_and_weights, + interp_mpas_to_transect_cells, interp_mpas_to_transect_nodes, interp_transect_grid_to_transect_nodes, ) diff --git a/conda_package/mpas_tools/ocean/viz/transect/vert.py b/conda_package/mpas_tools/ocean/viz/transect/vert.py index 0412e4823..1d79c2147 100644 --- a/conda_package/mpas_tools/ocean/viz/transect/vert.py +++ b/conda_package/mpas_tools/ocean/viz/transect/vert.py @@ -343,26 +343,26 @@ def interp_mpas_to_transect_nodes(ds_transect, da): def interp_transect_grid_to_transect_nodes(ds_transect, da): """ - Interpolate a DataArray on the original transect grid to nodes on the - MPAS-Ocean transect. - - Parameters - ---------- - ds_transect : xarray.Dataset - A dataset that defines an MPAS-Ocean transect, the - results of calling ``find_transect_levels_and_weights()`` with the - ``z_transect`` parameter. - - da : xarray.DataArray - An field on the original transect (defined at vertical locations - corresponding to ``z_transect``) - - Returns - ------- - da_nodes : xarray.DataArray - The data array interpolated to transect nodes with dimensions - ``nHorizNodes`` and ``nVertNodes`` - ยท""" + Interpolate a DataArray on the original transect grid to nodes on the + MPAS-Ocean transect. + + Parameters + ---------- + ds_transect : xarray.Dataset + A dataset that defines an MPAS-Ocean transect, the + results of calling ``find_transect_levels_and_weights()`` with the + ``z_transect`` parameter. + + da : xarray.DataArray + An field on the original transect (defined at vertical locations + corresponding to ``z_transect``) + + Returns + ------- + da_nodes : xarray.DataArray + The data array interpolated to transect nodes with dimensions + ``nHorizNodes`` and ``nVertNodes`` + """ horiz_dim = ds_transect.dTransect.dims[0] z_transect = ds_transect.zTransect diff --git a/conda_package/pyproject.toml b/conda_package/pyproject.toml index a2140a3e9..de2253005 100644 --- a/conda_package/pyproject.toml +++ b/conda_package/pyproject.toml @@ -77,7 +77,6 @@ docs = [ "sphinx >=7.0.0", "sphinx_rtd_theme", "myst-parser", - "sphinx-multiversion", ] dev = [