diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..c5f544c --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,51 @@ +version: 2.1 + +jobs: + build-site: + docker: + - image: cimg/python:3.13 + environment: + SITE_SRC: site + SITE_PATH: ${SITE_SRC}/_build/html + + steps: + - checkout + + - restore_cache: + keys: + - node-cache-v1 + + - run: + name: Install Node.js + command: | + curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash - + sudo apt-get install -y nodejs + + - run: + name: Install mystmd + command: | + npm install mystmd + + - save_cache: + key: node-cache-v1 + paths: + - node_modules + + - run: + name: Build site + command: | + export BASE_URL="/output/job/$CIRCLE_WORKFLOW_JOB_ID/artifacts/0/${SITE_PATH}" + + (cd ${SITE_SRC} && npx myst build --html) + + ## Temporary hack to remove unused thebe JS + rm ${SITE_PATH}/*thebe*.js + + - store_artifacts: + path: ${SITE_PATH} + +workflows: + version: 2 + build-and-site: + jobs: + - build-site diff --git a/.github/workflows/circleci.yml b/.github/workflows/circleci.yml new file mode 100644 index 0000000..33316ab --- /dev/null +++ b/.github/workflows/circleci.yml @@ -0,0 +1,22 @@ +name: circleci + +on: [status] +permissions: read-all + +jobs: + circleci_artifacts_redirector_job: + runs-on: ubuntu-latest + if: "${{ github.event.context == 'ci/circleci: build-site' }}" + permissions: + statuses: write + name: Run CircleCI artifacts redirector + steps: + - name: GitHub Action step + uses: scientific-python/circleci-artifacts-redirector-action@839631420e45a08af893032e5a5e8843bf47e8ff + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + api-token: ${{ secrets.CIRCLECI_ARTIFACT_REDIRECTOR_TOKEN }} + artifact-path: 0/site/_build/html/index.html + circleci-jobs: build-site + job-title: "--> site preview <--" + domain: circle.scientific-python.dev diff --git a/.gitignore b/.gitignore index bd3b629..f7c0de5 100644 --- a/.gitignore +++ b/.gitignore @@ -142,9 +142,6 @@ venv.bak/ # Rope project settings .ropeproject -# mkdocs documentation -/site - # mypy .mypy_cache/ .dmypy.json @@ -165,3 +162,12 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + +# MyST build outputs +_build + +# Vim swap files +*.swp + +# Javascript envieonment +node_modules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 230999c..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "themes/scientific-python-hugo-theme"] - path = themes/scientific-python-hugo-theme - url = https://github.com/scientific-python/scientific-python-hugo-theme diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 099e5ba..264e27d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,22 +25,6 @@ repos: files: \.(css|md|yml|yaml) args: [--prose-wrap=preserve] - - repo: https://github.com/psf/black-pre-commit-mirror - rev: 831207fd435b47aeffdf6af853097e64322b4d44 # frozen: 25.12.0 - hooks: - - id: black - - - repo: https://github.com/asottile/blacken-docs - rev: dda8db18cfc68df532abf33b185ecd12d5b7b326 # frozen: 1.20.0 - hooks: - - id: blacken-docs - - - repo: https://github.com/asottile/pyupgrade - rev: 75992aaa40730136014f34227e0135f63fc951b4 # frozen: v3.21.2 - hooks: - - id: pyupgrade - args: [--py38-plus] - - repo: https://github.com/codespell-project/codespell rev: "63c8f8312b7559622c0d82815639671ae42132ac" # frozen: v2.4.1 hooks: diff --git a/Makefile b/Makefile index 98d0559..a6971f7 100644 --- a/Makefile +++ b/Makefile @@ -1,46 +1,26 @@ -.PHONY: help themes html serve clean +.PHONY: help html serve clean .DEFAULT_GOAL := help help: @grep ": ##" Makefile | grep -v grep | tr -d '#' -themes/scientific-python-hugo-theme: - @if [ ! -d "$<" ]; then \ - echo "*** ERROR: missing theme" ; \ - echo ; \ - echo "It looks as though you are missing the themes directory."; \ - echo "You need to add the scientific-python-hugo-theme as a submodule."; \ - echo ; \ - echo "Please see https://theme.scientific-python.org/user_guide/getstarted/"; \ - echo ; \ - exit 1; \ - fi +team.md: + team_query.py --org scientific-python --team "tools-team" > team.md -themes: themes/scientific-python-hugo-theme +team-clean: + rm -f team.md -TEAMS_DIR = content/about -TEAMS = tools-team -TEAMS_QUERY = python themes/scientific-python-hugo-theme/tools/team_query.py +team: ## generates team gallery +team: | team-clean team.md -$(TEAMS_DIR)/%.toml: - $(TEAMS_QUERY) --org scientific-python --team "$*" > $(TEAMS_DIR)/$*.toml +html: ## Build site in `./site/_build` +html: + (cd site; myst build --html;) -teams-clean: - for team in $(TEAMS); do \ - rm -f $(TEAMS_DIR)/$${team}.toml ;\ - done - -teams: ## generates team gallery pages -teams: | teams-clean $(patsubst %,$(TEAMS_DIR)/%.toml,$(TEAMS)) - -html: ## Build site in `./public` -html: themes - hugo - -serve: ## Serve site, typically on http://localhost:1313 -serve: themes - @hugo --printI18nWarnings server +serve: ## Serve site, typically on http://localhost:3000 +serve: + (cd site; myst start;) clean: ## Remove built files clean: - rm -rf public + rm -rf site/_build diff --git a/README.md b/README.md index f817716..daffa42 100644 --- a/README.md +++ b/README.md @@ -1 +1,12 @@ # tools.scientific-python.org + +This repository hosts the source code for the website https://tools.scientific-python.org. + +The site is implemented with the mystmd book template. + +To run locally: + +``` +cd site +myst start +``` diff --git a/assets/css/custom.css b/assets/css/custom.css deleted file mode 100644 index 9c5e964..0000000 --- a/assets/css/custom.css +++ /dev/null @@ -1,3 +0,0 @@ -.navbar-logo-text { - font-family: "Lato"; -} diff --git a/config.yaml b/config.yaml deleted file mode 100644 index d27be8a..0000000 --- a/config.yaml +++ /dev/null @@ -1,64 +0,0 @@ -baseURL: "https://tools.scientific-python.org/" -title: "Tools" -theme: scientific-python-hugo-theme -disableKinds: ["term", "taxonomy"] - -markup: - highlight: - noClasses: false - -params: - description: "Tools and services for scientific Python developers and packages." - images: - - /images/logo.svg - navbarlogo: - image: logo.svg - text: Scientific Python Tools and Services - link: / - navbar: - - title: Home - url: https://scientific-python.org/ - - title: Blog - url: https://blog.scientific-python.org - - title: Learn - url: https://learn.scientific-python.org - - title: Tools - url: / - footer: - logo: logo.svg - socialmediatitle: "" - socialmedia: - - link: https://github.com/scientific-python/ - icon: github - - link: https://www.youtube.com/c/ScientificPython-org - icon: youtube - - link: https://fosstodon.org/@scientific_python - icon: mastodon - - link: https://discuss.scientific-python.org - icon: discourse - - link: https://discord.com/invite/vur45CbwMz - icon: discord - - quicklinks: - column1: - title: "" - links: - - text: About - link: /about/ - - text: Roadmap - link: /about/roadmap/ - - text: Code of Conduct - link: https://scientific-python.org/code_of_conduct/ - column2: - title: "Maintainers" - links: - - text: SPECs - link: https://scientific-python.org/specs/ - - text: Summits - link: https://scientific-python.org/summits/ - - text: Calendars - link: https://scientific-python.org/calendars/ - column3: - links: - - text: Press kit - link: https://scientific-python.org/press-kit/ diff --git a/content/about/tools-team.toml b/content/about/tools-team.toml deleted file mode 100644 index 7ade446..0000000 --- a/content/about/tools-team.toml +++ /dev/null @@ -1,69 +0,0 @@ -[[item]] -type = 'card' -classcard = 'text-center' -body = '''{{< image - src="https://avatars.githubusercontent.com/u/6788290?u=d9a388224b87d55106cb3e6199d02ebc1d8e0553&v=4\"" - alt="Avatar of Brigitta Sipőcz" ->}} -Brigitta Sipőcz''' -link = 'https://github.com/bsipocz' - -[[item]] -type = 'card' -classcard = 'text-center' -body = '''{{< image - src="https://avatars.githubusercontent.com/u/335567?v=4\"" - alt="Avatar of M Bussonnier" ->}} -M Bussonnier''' -link = 'https://github.com/Carreau' - -[[item]] -type = 'card' -classcard = 'text-center' -body = '''{{< image - src="https://avatars.githubusercontent.com/u/60778417?u=6272842e4c0946308604a5f54cdaa8e6505adcbe&v=4\"" - alt="Avatar of Jake Bowhay" ->}} -Jake Bowhay''' -link = 'https://github.com/j-bowhay' - -[[item]] -type = 'card' -classcard = 'text-center' -body = '''{{< image - src="https://avatars.githubusercontent.com/u/123428?v=4\"" - alt="Avatar of Jarrod Millman" ->}} -Jarrod Millman''' -link = 'https://github.com/jarrodmillman' - -[[item]] -type = 'card' -classcard = 'text-center' -body = '''{{< image - src="https://avatars.githubusercontent.com/u/20140352?u=fa6debadd435c15847d1435c49753f349e2d3526&v=4\"" - alt="Avatar of Lars Grüter" ->}} -Lars Grüter''' -link = 'https://github.com/lagru' - -[[item]] -type = 'card' -classcard = 'text-center' -body = '''{{< image - src="https://avatars.githubusercontent.com/u/2365790?v=4\"" - alt="Avatar of Eric Larson" ->}} -Eric Larson''' -link = 'https://github.com/larsoner' - -[[item]] -type = 'card' -classcard = 'text-center' -body = '''{{< image - src="https://avatars.githubusercontent.com/u/5142394?u=310e7999b329801a47ebc999c2243fc9f2b32434&v=4\"" - alt="Avatar of Matthew Feickert" ->}} -Matthew Feickert''' -link = 'https://github.com/matthewfeickert' diff --git a/content/github/index.md b/content/github/index.md deleted file mode 100644 index aa4e257..0000000 --- a/content/github/index.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: Github Actions and Bots ---- - -## Github Actions - -The following GitHub actions provide workflows that simplify various developer tasks. - -{{< grid columns="1 2 2 3" >}} - -[[item]] -type = 'card' -header = '[upload-nightly-action](https://github.com/scientific-python/upload-nightly-action)' -body = ''' -Uploads nightly builds to the [scientific-python conda channel](https://anaconda.org/scientific-python-nightly-wheels) as described in [SPEC4](https://scientific-python.org/specs/spec-0004/). -''' - -[[item]] -type = 'card' -header = '[attach-next-milestone-action](https://github.com/scientific-python/attach-next-milestone-action)' -body = ''' -When a PR is merged, attach it to the next upcoming milestone. -''' - -[[item]] -type = 'card' -header = '[action-check-changelogfile](https://github.com/scientific-python/action-check-changelogfile)' -body = ''' -Ensure that added changelog entries conform to certain rules. -''' - -[[item]] -type = 'card' -header = '[action-towncrier-changelog](https://github.com/scientific-python/action-towncrier-changelog)' -body = ''' -Ensure that added changelog entries conform to certain rules. -''' - -[[item]] -type = 'card' -header = '[reverse-dependency-testing](https://github.com/scientific-python/reverse-dependency-testing)' -body = ''' -Query the conda-forge dependency tree and run test suites for packages that depend on your package. -''' - -[[item]] -type = 'card' -header = '[sync-teams-action](https://github.com/scientific-python/sync-teams-action)' -body = ''' -Manage teams and team membership for the Scientific Python GitHub organization. -''' - -[[item]] -type = 'card' -header = '[circleci-artifacts-redirector-action](https://github.com/scientific-python/circleci-artifacts-redirector-action)' -body = ''' -Add a GitHub status link directly to a CircleCI artifact. -''' - -[[item]] -type = 'card' -header = '[devstats-query-action](https://github.com/scientific-python/devstats-query-action)' -body = ''' -Download devstats for one or more GitHub repositories as an artifact. -''' - -[[item]] -type = 'card' -header = '[issue-from-pytest-log-action](https://github.com/scientific-python/issue-from-pytest-log-action)' -body = ''' -Create an issue for failed tests from a `pytest-reportlog` file or update an existing one if it already exists. -''' - -{{< /grid >}} - -## Bots - -The following bots for GitHub provide workflows that simplify various developer tasks. - -{{< grid columns="1 2 2 3" >}} - -[[item]] -type = 'card' -header = '[MeeseeksDev / Lumberbot (App)](https://github.com/scientific-python/MeeseeksDev)' -body = ''' -A stateless GitHub bot that can backport PRs and perform other repository actions. -''' - -{{< /grid >}} diff --git a/netlify.toml b/netlify.toml deleted file mode 100644 index 145e815..0000000 --- a/netlify.toml +++ /dev/null @@ -1,26 +0,0 @@ -[build.environment] - PYTHON_VERSION = "3.13" - HUGO_VERSION = "0.152.2" - DART_SASS_VERSION = "1.93.2" - DART_SASS_URL = "https://github.com/sass/dart-sass/releases/download/" - -[build] - base = "/" - publish = "public" - command = """\ - export DART_SASS_TARBALL="dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz" && \ - curl -LJO ${DART_SASS_URL}/${DART_SASS_VERSION}/${DART_SASS_TARBALL} && \ - tar -xf ${DART_SASS_TARBALL} && \ - rm ${DART_SASS_TARBALL} && \ - export PATH=/opt/build/repo/dart-sass:$PATH && \ - make html \ - """ - -[context.deploy-preview] - ignore = "false" - -[[plugins]] - package = "netlify-plugin-checklinks" - - [plugins.inputs] - skipPatterns = ['https://fonts.gstatic.com', 'https://fonts.googleapis.com'] diff --git a/content/about/_index.md b/site/about.md similarity index 89% rename from content/about/_index.md rename to site/about.md index 26bd47c..ecff8ae 100644 --- a/content/about/_index.md +++ b/site/about.md @@ -22,8 +22,11 @@ Community members must adhere to our [code of conduct](https://scientific-python ## People For more information, see our -[governance and decision making process](/about/governance). +[governance and decision making process](governance). ### Tools / Service Steering Committee -{{< grid file="tools-team.toml" columns="2 3 4 5" />}} +::::{grid} 2 2 3 5 +:::{include} team.md +::: +:::: diff --git a/content/analytics/index.md b/site/analytics.md similarity index 64% rename from content/analytics/index.md rename to site/analytics.md index b0d7c3b..bafb933 100644 --- a/content/analytics/index.md +++ b/site/analytics.md @@ -2,24 +2,19 @@ title: "Analytics" --- -{{< grid columns="1 2 2 2" >}} +::::{grid} 1 2 2 2 -[[item]] -type = 'card' -header = '[devstats.scientific-python.org](https://devstats.scientific-python.org)' -body = ''' +:::{card} +:header: [devstats.scientific-python.org](https://devstats.scientific-python.org) We generate developer statistics for various core packages using the [devstats](https://github.com/scientific-python/devstats) tool. [Data releases](https://github.com/scientific-python/devstats-data/releases) are made weekly. +::: -''' - -[[item]] -type = 'card' -header = '[views.scientific-python.org](https://views.scientific-python.org)' -body = ''' +:::{card} +:header: [views.scientific-python.org](https://views.scientific-python.org) A hosted plausible instance where library authors can track website visits. You can [enable this service](https://pydata-sphinx-theme.readthedocs.io/en/latest/user_guide/analytics.html#analytics-and-usage-services) in your pydata-sphinx-theme settings. -''' +::: -{{< /grid >}} +:::: diff --git a/content/community/index.md b/site/community.md similarity index 56% rename from content/community/index.md rename to site/community.md index f094cfc..14e2b89 100644 --- a/content/community/index.md +++ b/site/community.md @@ -2,29 +2,23 @@ title: "Community & organization" --- -{{< grid columns="1 2 2 3" >}} +::::{grid} 1 2 2 3 -[[item]] -type = 'card' -header = '[yaml2ics](https://github.com/scientific-python/yaml2ics)' -body = ''' +:::{card} +:header:[yaml2ics](https://github.com/scientific-python/yaml2ics) Convert plain-text descriptions of calendar events into ICS files that can be loaded into Google Calendar etc. Used to host the Scientific Python [community calendars](https://scientific-python.org/calendars). -''' +::: -[[item]] -type = 'card' -header = '[discuss.scientific-python.org](https://discuss.scientific-python.org)' -body = ''' +:::{card} +:header:[discuss.scientific-python.org](https://discuss.scientific-python.org) A Discourse discussion forum for the Scientific Python developer community. Also see the [Scientific Python blog](https://blog.scientific-python.org). -''' +::: -[[item]] -type = 'card' -header = '[vault-template](https://github.com/scientific-python/vault-template)' -body = ''' +:::{card} +:header:[vault-template](https://github.com/scientific-python/vault-template) A GPG-based password vault. See also [SPEC 6](https://github.com/scientific-python/specs/pull/168). -''' +::: -{{< /grid >}} +:::: diff --git a/site/favicon.ico b/site/favicon.ico new file mode 100644 index 0000000..6f3ca0b Binary files /dev/null and b/site/favicon.ico differ diff --git a/site/footer.md b/site/footer.md new file mode 100644 index 0000000..24f1440 --- /dev/null +++ b/site/footer.md @@ -0,0 +1,60 @@ +% This defines the footer of the site, and is not parsed as a regular "page" +% We point to it with the following in `myst.yml`: +% site: +% parts: +% footer: footer.md + +% Here we use `grid` to add a basic grid structure to the HTML, +% but the formatting column sizes are defined manually in css/footer.css +% see the `grid-template-columns` line. +:::::{grid} 1 3 5 5 +:class: footer-grid + +::::{div} +:class: logo +:::{image} ./logo.svg +::: +:::: + + +% This a _second_ grid embedded within the first one, to create nicer +% responsive design experience. This grid will have a single column on narrow screens, +% and fan out into three columns on wide screens. However, it always remains within +% its parent grid column. +::::{grid} 1 1 3 3 +:class: center-links + +:::{div} +- [About](/about) +- [Roadmap](/roadmap) +- [Code of Conduct](https://scientific-python.org/code_of_conduct/) +::: + +:::{div} +- [SPECs](https://scientific-python.org/specs/) +- [Summits](https://scientific-python.org/summits/) +- [Calendars](https://scientific-python.org/calendars/) +::: + +:::{div} +- [Press Kit](https://scientific-python.org/press-kit/) +::: + +:::: + +::::{div} +:class: social-links +[{scienceicon}`github`](http://github.com/scientific-python/) +[{scienceicon}`youtube`](https://www.youtube.com/c/ScientificPython-org) +[{scienceicon}`mastodon`](https://fosstodon.org/@scientific_python) +[{scienceicon}`discourse`](https://discuss.scientific-python.org/) +[{scienceicon}`discord`](https://discord.com/invite/vur45CbwMz) + +:::{div} +:class: copyright +© 2026. All rights reserved. +::: + +:::: + +::::: diff --git a/site/github.md b/site/github.md new file mode 100644 index 0000000..7530d7e --- /dev/null +++ b/site/github.md @@ -0,0 +1,69 @@ +--- +title: Github Actions and Bots +--- + +## Github Actions + +The following GitHub actions provide workflows that simplify various developer tasks. + +::::{grid}1 2 2 3 + +:::{card} +:header: [upload-nightly-action](https://github.com/scientific-python/upload-nightly-action) +Uploads nightly builds to the [scientific-python conda channel](https://anaconda.org/scientific-python-nightly-wheels) as described in [SPEC4](https://scientific-python.org/specs/spec-0004/). +::: + +:::{card} +:header: [attach-next-milestone-action](https://github.com/scientific-python/attach-next-milestone-action) +When a PR is merged, attach it to the next upcoming milestone. +::: + +:::{card} +:header: [action-check-changelogfile](https://github.com/scientific-python/action-check-changelogfile) +Ensure that added changelog entries conform to certain rules. +::: + +:::{card} +:header: [action-towncrier-changelog](https://github.com/scientific-python/action-towncrier-changelog) +Ensure that added changelog entries conform to certain rules. +::: + +:::{card} +:header: [reverse-dependency-testing](https://github.com/scientific-python/reverse-dependency-testing) +Query the conda-forge dependency tree and run test suites for packages that depend on your package. +::: + +:::{card} +:header: [sync-teams-action](https://github.com/scientific-python/sync-teams-action) +Manage teams and team membership for the Scientific Python GitHub organization. +::: + +:::{card} +:header: [circleci-artifacts-redirector-action](https://github.com/scientific-python/circleci-artifacts-redirector-action) +Add a GitHub status link directly to a CircleCI artifact. +::: + +:::{card} +:header: [devstats-query-action](https://github.com/scientific-python/devstats-query-action) +Download devstats for one or more GitHub repositories as an artifact. +::: + +:::{card} +:header: [issue-from-pytest-log-action](https://github.com/scientific-python/issue-from-pytest-log-action) +Create an issue for failed tests from a `pytest-reportlog` file or update an existing one if it already exists. +::: + +:::: + +## Bots + +The following bots for GitHub provide workflows that simplify various developer tasks. + +::::{grid} 1 2 2 3 + +:::{card} +:header: [MeeseeksDev / Lumberbot (App)](https://github.com/scientific-python/MeeseeksDev) +A stateless GitHub bot that can backport PRs and perform other repository actions. +::: + +:::: diff --git a/content/about/governance.md b/site/governance.md similarity index 100% rename from content/about/governance.md rename to site/governance.md diff --git a/content/_index.md b/site/index.md similarity index 75% rename from content/_index.md rename to site/index.md index 4e83f16..556cf9b 100644 --- a/content/_index.md +++ b/site/index.md @@ -1,56 +1,49 @@ --- -title: +title: "Community Tools & Services" --- -# Community Tools & Services We maintain a collection of tools that help projects across the ecosystem. We also offer a small selection of hosted services. -{{< grid columns="1 1 1 5" >}} +::::{grid} 1 1 3 5 + +:::{card} +:header: **Web** +:link: https://theme.scientific-python.org -[[item]] -type = 'card' -title = 'For Web' -link = 'https://theme.scientific-python.org' -body = ''' A [Hugo](https://gohugo.io/) theme used by [NumPy](https://numpy.org/), [SciPy](https://scipy.org/), [Scientific Python](https://scientific-python.org/), and other sites. -''' +::: + +:::{card} +:header: **Development** +:link: /utilities -[[item]] -type = 'card' -title = 'For Development' -link = '/utilities' -body = ''' Python developer tools used by packages across the ecosystem. -''' +::: -[[item]] -type = 'card' -title = 'For Organization' -link = '/community' -body = ''' +:::{card} +:header: **Organization** +:link: /community Calendar, forum, and other services for organizing the community. -''' +::: + +::: {card} +:header: **Insight** +:link: /analytics -[[item]] -type = 'card' -title = 'For Insight' -link = '/analytics' -body = ''' Through analytics, to better understand project development and community health. -''' +::: + +:::{card} +:header: **GitHub** +:link: /github -[[item]] -type = 'card' -title = 'For GitHub' -link = '/github' -body = ''' GitHub Actions and bots for automating various aspects of project development. -''' +::: -{{< /grid >}} +:::: ### New tools diff --git a/static/images/logo.svg b/site/logo.svg similarity index 100% rename from static/images/logo.svg rename to site/logo.svg diff --git a/site/myst.yml b/site/myst.yml new file mode 100644 index 0000000..ccea7cc --- /dev/null +++ b/site/myst.yml @@ -0,0 +1,35 @@ +# See docs at: https://mystmd.org/guide/frontmatter +version: 1 +project: + id: ee007168-b9a5-4dba-8823-1639a4aeb956 + abbreviations: + CSS: Cascading Style Sheet + plugins: + - scienceicons.mjs + +site: + template: book-theme + title: Scientific Python Tools and Services + + options: + hide_outline: true + hide_toc: true + hide_footer_links: true + favicon: favicon.ico + logo: logo.svg + logo_dark: logo.svg + logo_text: Scientific Python Tools and Services + style: site.css + + nav: + - title: Home + url: https://scientific-python.org/ + - title: Blog + url: https://blog.scientific-python.org/ + - title: Learn + url: https://learn.scientific-python.org/ + - title: Tools + url: /index + + parts: + footer: footer.md diff --git a/content/about/roadmap.md b/site/roadmap.md similarity index 100% rename from content/about/roadmap.md rename to site/roadmap.md diff --git a/site/scienceicons.mjs b/site/scienceicons.mjs new file mode 100644 index 0000000..a3deb7c --- /dev/null +++ b/site/scienceicons.mjs @@ -0,0 +1,118 @@ +// node_modules/nanoid/index.js +import { webcrypto as crypto } from "crypto"; +var POOL_SIZE_MULTIPLIER = 128; +var pool; +var poolOffset; +function fillPool(bytes) { + if (!pool || pool.length < bytes) { + pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER); + crypto.getRandomValues(pool); + poolOffset = 0; + } else if (poolOffset + bytes > pool.length) { + crypto.getRandomValues(pool); + poolOffset = 0; + } + poolOffset += bytes; +} +function random(bytes) { + fillPool(bytes |= 0); + return pool.subarray(poolOffset - bytes, poolOffset); +} +function customRandom(alphabet, defaultSize, getRandom) { + let mask = (2 << 31 - Math.clz32(alphabet.length - 1 | 1)) - 1; + let step = Math.ceil(1.6 * mask * defaultSize / alphabet.length); + return (size = defaultSize) => { + if (!size) return ""; + let id = ""; + while (true) { + let bytes = getRandom(step); + let i = step; + while (i--) { + id += alphabet[bytes[i] & mask] || ""; + if (id.length >= size) return id; + } + } + }; +} +function customAlphabet(alphabet, size = 21) { + return customRandom(alphabet, size, random); +} + +// node_modules/myst-common/dist/utils.js +function addMessageInfo(message, info) { + if (info?.note) + message.note = info.note; + if (info?.url) + message.url = info.url; + if (info?.ruleId) + message.ruleId = info.ruleId; + if (info?.key) + message.key = info.key; + if (info?.fatal) + message.fatal = true; + return message; +} +function fileWarn(file, message, opts) { + return addMessageInfo(file.message(message, opts?.node, opts?.source), opts); +} +var az = "abcdefghijklmnopqrstuvwxyz"; +var alpha = az + az.toUpperCase(); +var numbers = "0123456789"; +var nanoidAZ = customAlphabet(alpha, 1); +var nanoidAZ9 = customAlphabet(alpha + numbers, 9); + +// src/names.json +var names_default = [ + { name: "arxiv", componentName: "ArxivIcon" }, + { name: "binder", componentName: "BinderIcon" }, + { name: "cc-by", componentName: "CcByIcon" }, + { name: "cc-nc", componentName: "CcNcIcon" }, + { name: "cc-nd", componentName: "CcNdIcon" }, + { name: "cc-sa", componentName: "CcSaIcon" }, + { name: "cc-zero", componentName: "CcZeroIcon" }, + { name: "cc", componentName: "CcIcon" }, + { name: "curvenote", componentName: "CurvenoteIcon" }, + { name: "discord", componentName: "DiscordIcon" }, + { name: "discourse", componentName: "DiscourseIcon" }, + { name: "email", componentName: "EmailIcon" }, + { name: "github", componentName: "GithubIcon" }, + { name: "jupyter-book", componentName: "JupyterBookIcon" }, + { name: "jupyter-text", componentName: "JupyterTextIcon" }, + { name: "jupyter", componentName: "JupyterIcon" }, + { name: "linkedin", componentName: "LinkedinIcon" }, + { name: "mastodon", componentName: "MastodonIcon" }, + { name: "myst", componentName: "MystIcon" }, + { name: "open-access", componentName: "OpenAccessIcon" }, + { name: "orcid", componentName: "OrcidIcon" }, + { name: "osi", componentName: "OsiIcon" }, + { name: "ror", componentName: "RorIcon" }, + { name: "slack", componentName: "SlackIcon" }, + { name: "twitter", componentName: "TwitterIcon" }, + { name: "website", componentName: "WebsiteIcon" }, + { name: "youtube", componentName: "YoutubeIcon" } +]; + +// src/scienceicons.ts +var SUPPORTED_ICONS = names_default.map((icon) => icon.name); +var iconRole = { + name: "scienceicon", + alias: ["scicon"], + body: { + type: String, + required: true, + doc: "The kind of icon to display" + }, + run(data, vfile) { + if (!SUPPORTED_ICONS.includes(data.body)) { + fileWarn(vfile, `Unknown name of scienceicon: ${data.body}`); + return []; + } + return [{ type: "scienceicon", value: data.body, kind: data.body }]; + } +}; +var plugin = { name: "Science Icons by Curvenote", roles: [iconRole] }; +var scienceicons_default = plugin; +export { + scienceicons_default as default +}; +//# sourceMappingURL=scienceicons.mjs.map \ No newline at end of file diff --git a/site/site.css b/site/site.css new file mode 100644 index 0000000..f77202d --- /dev/null +++ b/site/site.css @@ -0,0 +1,109 @@ +html, +body { + height: 100%; +} + +.article.content { + /* Override 100vh from myst-theme:styles/typography.css so content div + * doesn't push the footer offscreen. + */ + min-height: 0vh; + grid-template-columns: 1fr; + margin-left: 15%; + margin-right: 15%; +} + +/* Sure would be nice if this thing had a dedicated CSS class + * (eg .myst-top-nav-links) + * */ +.myst-top-nav-bar > div:nth-child(2) > div { + white-space: nowrap; +} + +footer { + /* Make footer "sticky" to page bottom as described here: + * https://css-tricks.com/a-clever-sticky-footer-technique/ + */ + position: sticky; + top: 100vh; + background: #013243; + color: white; + padding-left: 15%; + padding-right: 15%; + + & li { + list-style: none; + } + + /* Outer content grid */ + & .footer-grid { + /* spacer, project description, spacer, link columns, spacer */ + align-items: center; + margin-bottom: 0rem; + grid-template-columns: 1fr 3fr 1fr; + } + + @media (max-width: 640px) { + & .footer-grid { + grid-template-columns: 1fr; + justify-items: start; + } + } + + & .logo { + width: 100%; + padding-left: 25px; + + & img { + width: 65px; + min-width: 65px; + } + } + + & .center-links { + width: 100%; + + & div { + min-width: 160px; + } + & ul { + padding-left: 10px; + } + } + @media (max-width: 640px) { + & .center-links { + left: -10px; + text-align: center; + } + } + + & .social-links { + width: 100%; + min-width: 250px; + text-align: center; + + & a { + margin-left: 14px; + } + & svg { + width: 2em; + height: 2em; + } + & .copyright { + font-size: 80%; + } + } +} + +.myst-card-header { + font-size: 110%; + color: revert; +} + +/* + * Hide the "Download" icon in the frontmatter. + */ +#skip-to-frontmatter > .items-center { + display: none; +} + diff --git a/site/team.md b/site/team.md new file mode 100644 index 0000000..f09805a --- /dev/null +++ b/site/team.md @@ -0,0 +1,42 @@ +:::{card} +:footer: Brigitta Sipőcz +:link: https://github.com/bsipocz +![Brigitta Sipőcz](https://avatars.githubusercontent.com/u/6788290?u=d9a388224b87d55106cb3e6199d02ebc1d8e0553&v=4) +::: + +:::{card} +:footer: M Bussonnier +:link: https://github.com/Carreau +![M Bussonnier](https://avatars.githubusercontent.com/u/335567?v=4) +::: + +:::{card} +:footer: Jake Bowhay +:link: https://github.com/j-bowhay +![Jake Bowhay](https://avatars.githubusercontent.com/u/60778417?u=6272842e4c0946308604a5f54cdaa8e6505adcbe&v=4) +::: + +:::{card} +:footer: Jarrod Millman +:link: https://github.com/jarrodmillman +![Jarrod Millman](https://avatars.githubusercontent.com/u/123428?v=4) +::: + +:::{card} +:footer: Lars Grüter +:link: https://github.com/lagru +![Lars Grüter](https://avatars.githubusercontent.com/u/20140352?u=fa6debadd435c15847d1435c49753f349e2d3526&v=4) +::: + +:::{card} +:footer: Eric Larson +:link: https://github.com/larsoner +![Eric Larson](https://avatars.githubusercontent.com/u/2365790?v=4) +::: + +:::{card} +:footer: Matthew Feickert +:link: https://github.com/matthewfeickert +![Matthew Feickert](https://avatars.githubusercontent.com/u/5142394?u=310e7999b329801a47ebc999c2243fc9f2b32434&v=4) +::: + diff --git a/site/team_query.py b/site/team_query.py new file mode 100755 index 0000000..573de92 --- /dev/null +++ b/site/team_query.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# Cribbed from https://github.com/scientific-python/scientific-python-hugo-theme/blob/main/tools/team_query.py +import os +import sys +import argparse +import string + +import requests + + +team_query = string.Template( + """ + query { + organization(login: "$org") { + team(slug: "$team") { + name, + members(first: 100, orderBy: {field: LOGIN, direction: ASC}) { + nodes { + login + name + url + avatarUrl + } + } + } + } + } +""" +) + + +def api(query): + request = requests.post( + "https://api.github.com/graphql", + json={"query": query}, + headers={"Authorization": f"bearer {token}"}, + ) + if request.status_code == 200: + return request.json() + else: + raise RuntimeError(f"Request received HTTP {request.status_code}: {query}") + + +parser = argparse.ArgumentParser(description="Generate team gallery from GitHub") +parser.add_argument("--org", required=True, help="GitHub organization name") +parser.add_argument("--team", required=True, help="Team name in the organization") +args = parser.parse_args() + +org = args.org +team = args.team + +token = os.environ.get("GH_TOKEN", None) +if token is None: + print( + "No token found. Please export a GH_TOKEN with permissions " + "to read team members.", + file=sys.stderr, + ) + sys.exit(-1) + + +resp = api(team_query.substitute(org=org, team=team)) +members = resp["data"]["organization"]["team"]["members"]["nodes"] +team_name = resp["data"]["organization"]["team"]["name"] + +member_template = string.Template( + """\ +:::{card} +:footer: ${name} +:link: ${url} +![${name}](${avatarUrl}) +::: +""" +) + +members_list = [] +for m in members: + m["name"] = m["name"] or m["login"] + members_list.append(member_template.substitute(**m)) + +print("\n".join(members_list).rstrip()) + diff --git a/content/utilities/index.md b/site/utilities.md similarity index 53% rename from content/utilities/index.md rename to site/utilities.md index 90a55d5..b5003c5 100644 --- a/content/utilities/index.md +++ b/site/utilities.md @@ -5,50 +5,38 @@ title: "Developer Utilities" The following Python packages provide functionality widely usable by packages across the ecosystem. Also see to the [Scientific Python Developer Guide](https://learn.scientific-python.org/development/). -{{< grid columns="1 2 2 3" >}} +::::{grid} 1 2 2 3 -[[item]] -type = 'card' -header = '[lazy-loader](https://github.com/scientific-python/lazy-loader/)' -body = ''' +:::{card} +:header: [lazy-loader](https://github.com/scientific-python/lazy-loader/) Implements lazy loading as described in [SPEC1](https://scientific-python.org/specs/spec-0001/). -''' +::: -[[item]] -type = 'card' -header = '[spin](https://github.com/scientific-python/spin)' -body = ''' +:::{card} +:header: [spin](https://github.com/scientific-python/spin) **S**cientific **P**ython **IN**cantations: an extendible tool that provides uniform aliases for build tasks across the ecosystem (`spin build`, `spin docs`, etc.). -''' +::: -[[item]] -type = 'card' -header = '[pytest-doctestplus](https://github.com/scientific-python/pytest-doctestplus)' -body = ''' +:::{card} +:header: [pytest-doctestplus](https://github.com/scientific-python/pytest-doctestplus) A plugin for the pytest framework that provides advanced doctest support and enables the testing of text file formats. -''' +::: -[[item]] -type = 'card' -header = '[repo-review](https://github.com/scientific-python/repo-review)' -body = ''' +:::{card} +:header: [repo-review](https://github.com/scientific-python/repo-review) A framework for building checks designed to check to see if a repository follows guideline. -''' +::: -[[item]] -type = 'card' -header = '[docstub](https://github.com/scientific-python/docstub/)' -body = ''' +:::{card} +:header: [docstub](https://github.com/scientific-python/docstub/) A tool for generating Python stub files from docstrings. -''' +::: -[[item]] -type = 'card' -header = '[changelist](https://github.com/scientific-python/changelist/)' -body = ''' +:::{card} +:header: [changelist](https://github.com/scientific-python/changelist/) A tool for automating release notes. -''' +::: -{{< /grid >}} +:::: diff --git a/themes/scientific-python-hugo-theme b/themes/scientific-python-hugo-theme deleted file mode 160000 index d8388d2..0000000 --- a/themes/scientific-python-hugo-theme +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d8388d2f417c63d3c2aa0a2f51687d34a0b56208