├── .editorconfig ├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE.txt ├── README.md ├── build.sh ├── config.toml ├── layouts └── index.html └── static ├── .nojekyll ├── favicon.png ├── main.css └── sorttable.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [Makefile] 12 | indent_style = tab 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Continuous integration 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | schedule: 8 | # Every day at midnight (UTC). 9 | # This keeps the class reference status page fresh. 10 | - cron: '0 0 * * *' 11 | 12 | jobs: 13 | deploy: 14 | name: Build and deploy to GitHub Pages 15 | runs-on: ubuntu-22.04 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | 20 | - name: Generate class reference table and build website 21 | env: 22 | HUGO_VERSION: '0.101.0' 23 | run: | 24 | curl -LO "https://github.com/gohugoio/hugo/releases/download/v$HUGO_VERSION/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz" 25 | tar xf "hugo_${HUGO_VERSION}_Linux-64bit.tar.gz" hugo 26 | sudo mv hugo /usr/local/bin/ 27 | ./build.sh 28 | 29 | - name: Deploy to GitHub Pages 🚀 30 | uses: JamesIves/github-pages-deploy-action@releases/v4 31 | # Only deploy from the `master` branch, and never deploy from pull requests. 32 | if: ${{ (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/master' }} 33 | with: 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 35 | # The branch the action should deploy to. 36 | BRANCH: gh-pages 37 | # The folder the action should deploy. 38 | FOLDER: public 39 | # Artifacts are large, don't keep the branch's history 40 | SINGLE_COMMIT: true 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Hugo's default output directory 2 | /public/ 3 | 4 | # Automatically generated by `build.sh` 5 | content/_index.md 6 | 7 | # Lockfile generated by Hugo 8 | .hugo_build.lock 9 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. 2 | Copyright (c) 2014-2020 Godot Engine contributors (cf. https://github.com/godotengine/godot/blob/master/AUTHORS.md). 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot class reference status 2 | 3 | View the completion status of the Godot class reference (updated daily). 4 | 5 | ## [View](https://godotengine.github.io/doc-status/) 6 | 7 | ## How it works 8 | 9 | - First, `build.sh` performs the following operations: 10 | - Clone the Godot Git repository to a temporary directory. 11 | - Run `doc/tools/doc_status.py` to generate a Markdown table, with the output 12 | redirected to a file. A static header is added at the beginning of the file 13 | as well. 14 | - Some text manipulation is done on the generated Markdown file to improve 15 | readability and visual grepping. 16 | - [Hugo](https://gohugo.io/) is used to build the HTML template with the 17 | referenced Markdown data into a static HTML page. 18 | - The generated website is deployed to GitHub Pages. 19 | 20 | Every day, there's a continuous integration step that runs the tasks above to 21 | keep the page up-to-date. 22 | 23 | ## Development 24 | 25 | Follow these instructions to set up this site locally for development purposes: 26 | 27 | - [Install Hugo](https://gohugo.io/getting-started/installing/) for your 28 | operating system. 29 | - Run the `build.sh` script to clone the Godot repository, generate a Markdown 30 | file and build the website. 31 | - On Windows 10, you should be able to run this script using the WSL. 32 | - Run `hugo server` while working on the website CSS/JavaScript. The local 33 | server will reload automatically on file changes. 34 | - If you need to regenerate `content/_index.md`, run `build.sh` again. You can 35 | do this while having the development server running. 36 | 37 | ## License 38 | 39 | - Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. 40 | - Copyright (c) 2014-2020 Godot Engine contributors 41 | (cf. ). 42 | 43 | Unless otherwise specified, files in this repository are licensed under the 44 | MIT license. See [LICENSE.txt](LICENSE.txt) for more information. 45 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | cd "$(dirname "${BASH_SOURCE[0]}")" 6 | 7 | GODOT_TMP_DIR="$(mktemp -d)" 8 | git clone --depth=1 https://github.com/godotengine/godot.git "$GODOT_TMP_DIR" 9 | 10 | # Generate a Markdown table of the class reference coverage. 11 | mkdir -p content/ 12 | rm -f content/_index.md 13 | 14 | # Add Git commit information to the generated page. 15 | COMMIT_HASH="$(git -C "$GODOT_TMP_DIR" rev-parse --short=9 HEAD)" 16 | COMMIT_DATE="$(git -C "$GODOT_TMP_DIR" log -1 --pretty=%cd --date=format:%Y-%m-%d)" 17 | echo -e "\nBuilding status page for Godot commit $COMMIT_HASH ($COMMIT_DATE):" 18 | echo "https://github.com/godotengine/godot/commit/$COMMIT_HASH" 19 | 20 | # This template must end with a blank line so the table that will be appended 21 | # can be parsed correctly. 22 | cat << EOF > content/_index.md 23 | # Godot class reference status 24 | 25 | Generated from Godot commit [\`$COMMIT_HASH\`](https://github.com/godotengine/godot/commit/$COMMIT_HASH) 26 | ($COMMIT_DATE). 27 | 28 | Interested in contributing? See 29 | [Contribute to the class reference](https://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html) 30 | in the documentation. To avoid conflicts with pending contributions, check 31 | [open documentation pull requests](https://github.com/godotengine/godot/pulls?q=is%3Apr+is%3Aopen+label%3Adocumentation) 32 | before starting to work on a class. 33 | 34 | EOF 35 | 36 | # Trim the first line of the output to get a valid Markdown table. 37 | # Ensure that module and platform documentation is also included in the report. 38 | NO_COLOR=1 python3 "$GODOT_TMP_DIR/doc/tools/doc_status.py" -u "$GODOT_TMP_DIR/doc/classes" "$GODOT_TMP_DIR"/modules/*/doc_classes "$GODOT_TMP_DIR"/platform/*/doc_classes | tail -n +2 >> content/_index.md 39 | 40 | # Fade out `0/0` completion ratios as they can't be completed (there's nothing to document). 41 | sed -i 's:0/0:0/0:g' content/_index.md 42 | 43 | # Add classes for completion percentages to style them for easier visual grepping. 44 | # Incomplete percentages (0-99%). 45 | sed -Ei 's:\s([0-9][0-9]?)%:\1%:g' content/_index.md 46 | # Complete percentages (100%). 47 | sed -Ei 's:100%:100%:g' content/_index.md 48 | 49 | # Shorten class links' text to decrease the table's width. 50 | sed -Ei 's:(https\:.+classes/(class_.+)\.html):[\2](\1):g' content/_index.md 51 | 52 | # Build the website with optimizations enabled. 53 | hugo --minify 54 | 55 | rm -rf "$GODOT_TMP_DIR" 56 | -------------------------------------------------------------------------------- /config.toml: -------------------------------------------------------------------------------- 1 | baseURL = "https://godotengine.github.io/doc-status/" 2 | languageCode = "en-us" 3 | title = "Godot class reference status" 4 | 5 | # This is a single-page website, no need to generate a sitemap and RSS feed. 6 | disableKinds = ["sitemap", "RSS", "taxonomyTerm"] 7 | 8 | [markup.goldmark.renderer] 9 | unsafe = true 10 | -------------------------------------------------------------------------------- /layouts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{ .Site.Title }} 10 | 11 | 12 | 13 | 14 | 15 | {{ .Content }} 16 | 17 | 18 | -------------------------------------------------------------------------------- /static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godotengine/doc-status/59ebd09831cbc46811cfc7aa2c27e501726de729/static/.nojekyll -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godotengine/doc-status/59ebd09831cbc46811cfc7aa2c27e501726de729/static/favicon.png -------------------------------------------------------------------------------- /static/main.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --body-background-color: hsl(0, 0%, 100%); 3 | --body-color: hsl(0, 0%, 25%); 4 | --table-sticky-background-color: hsl(0, 0%, 92%); 5 | --link-color: hsl(210, 90%, 50%); 6 | --completion-complete-color: hsl(125, 60%, 35%); 7 | } 8 | 9 | @media (prefers-color-scheme: dark) { 10 | :root { 11 | --body-background-color: hsl(180, 5%, 15%); 12 | --body-color: hsl(0, 0%, 80%); 13 | --table-sticky-background-color: hsl(180, 5%, 15%); 14 | --link-color: hsl(200, 50%, 60%); 15 | --completion-complete-color: hsl(125, 50%, 65%); 16 | } 17 | } 18 | 19 | body { 20 | background-color: var(--body-background-color); 21 | color: var(--body-color); 22 | /* Use a modern font stack inspired by Bootstrap 4. */ 23 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 24 | } 25 | 26 | h1, 27 | p { 28 | text-align: center; 29 | } 30 | 31 | a { 32 | color: var(--link-color); 33 | text-decoration: none; 34 | } 35 | 36 | a:hover { 37 | text-decoration: underline; 38 | } 39 | 40 | table { 41 | border-collapse: collapse; 42 | margin: 2rem auto 0 auto; 43 | } 44 | 45 | td { 46 | border: 1px solid hsla(0, 0%, 50%, 50%); 47 | padding: 0.25rem 0.5rem; 48 | /* Prefer horizontal scrolling to wrapping over several lines. */ 49 | white-space: nowrap; 50 | } 51 | 52 | tr:hover { 53 | background-color: hsla(210, 90%, 50%, 12.5%); 54 | } 55 | 56 | tr:nth-child(even) { 57 | background-color: hsla(0, 0%, 50%, 10%); 58 | } 59 | 60 | tr:nth-child(even):hover { 61 | background-color: hsla(210, 90%, 50%, 15%); 62 | } 63 | 64 | /* Align class names to the right for better readability and highlight them. */ 65 | td:first-child { 66 | font-weight: bold; 67 | text-align: right; 68 | } 69 | 70 | /* Sticky header for the table. */ 71 | th { 72 | background: var(--table-sticky-background-color); 73 | box-shadow: 0px 2px 2px 0px rgb(0, 0, 0, 25%); 74 | padding: 4px 2px; 75 | position: -webkit-sticky; 76 | position: sticky; 77 | z-index: 1; /* Show on top of table cells. */ 78 | top: 0; /* Stick to the top of the screen. */ 79 | cursor: pointer; /* Visually hint that headers can be interacted with. */ 80 | } 81 | th:first-child { 82 | border-left: 1px solid var(--table-sticky-background-color); /* Fixes left border during scroll; must have a valid color, transparent doesn't work. */ 83 | } 84 | 85 | .completion-complete { 86 | color: var(--completion-complete-color); 87 | } 88 | 89 | /* Dynamic coloring depending on the completion percentage. */ 90 | /* Will be fully red at (roughly) 50% completion, and black/white (depending on the theme) at 99%. */ 91 | .completion-incomplete { 92 | font-weight: bold; 93 | color: rgb(calc(320 - calc(var(--percentage) * 3.2)), 64, 64); 94 | } 95 | 96 | @media (prefers-color-scheme: dark) { 97 | .completion-incomplete { 98 | --green-blue: calc(80 + calc(var(--percentage) * 2)); 99 | color: rgb(255, var(--green-blue), var(--green-blue)); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /static/sorttable.js: -------------------------------------------------------------------------------- 1 | // Make the class reference table sortable in ascending or descending order 2 | // when a header is clicked. 3 | 4 | 5 | // Helper function to return the content from the idx-th cell of row tr 6 | const getCellValue = (tr, idx) => tr.children[idx].textContent; 7 | 8 | // Array sorting functions for different columns used by the comparer 9 | 10 | // Compares the Desc. and Brief Desc. columns 11 | // "MISSING" comes first in ascending order 12 | const descriptionComparer = function(v1, v2) { 13 | if(v1 == v2) return 0 14 | if(v1 == "OK") return 1 15 | return -1 16 | } 17 | 18 | // Compares the Name and Docs URL columns using a basic string sort 19 | const stringComparer = (new Intl.Collator()).compare 20 | 21 | // Compares the Overall column by completion percentage 22 | const overallComparer = function(v1, v2) { 23 | return Number(v1.replace("%", "")) - Number(v2.replace("%", "")) 24 | } 25 | 26 | // Compares the other columns (constructors, methods, members, etc.) 27 | // by the percentage they're finished. 28 | // If two have the same percentage, they're compared by denominator size. 29 | const fractionComparer = (asc) => function(v1, v2) { 30 | if(v1 == v2) return 0 31 | 32 | // Always send 0/0 values to the bottom 33 | // The "asc" parameter is needed for that purpose. 34 | if(v1 == "0/0") { 35 | return asc ? 1 : -1 36 | } 37 | 38 | if(v2 == "0/0") { 39 | return asc ? -1 : 1 40 | } 41 | 42 | var v1fraction = v1.split("/") 43 | var v2fraction = v2.split("/") 44 | 45 | var v1decimal = Number(v1fraction[0]) / Number(v1fraction[1]) 46 | var v2decimal = Number(v2fraction[0]) / Number(v2fraction[1]) 47 | if(v1decimal == v2decimal) return v1fraction[1] - v2fraction[1] 48 | 49 | return v1decimal - v2decimal 50 | } 51 | 52 | // Returns a function responsible for sorting a specific table column 53 | // (column = column object, asc = ascending order?). 54 | const comparer = function(column, asc) { 55 | 56 | // This is used by the array.sort() function... 57 | return function(a, b) { 58 | const colIdx = Array.from(column.parentNode.children).indexOf(column) 59 | const colName = column.textContent 60 | 61 | // Select a function based on which column is being called. 62 | var columnComparer 63 | switch(colName) { 64 | case "Brief Desc.": 65 | case "Desc.": 66 | columnComparer = descriptionComparer 67 | break 68 | case "Name": 69 | case "Docs URL": 70 | columnComparer = stringComparer 71 | break 72 | case "Overall": 73 | columnComparer = overallComparer 74 | break 75 | default: 76 | columnComparer = fractionComparer(column.asc) 77 | break 78 | } 79 | 80 | // Switch the order of the values depending on whether it's an ascending or descending sort. 81 | return columnComparer(getCellValue(asc ? a : b, colIdx), getCellValue(asc ? b : a, colIdx)); 82 | } 83 | }; 84 | 85 | const SKIP_END_ROWS = 5 // The number of footer rows generated by doc_status.py 86 | 87 | // Set up event listeners that will sort the table when headers are clicked. 88 | window.onload = function() 89 | { 90 | document.querySelectorAll('th') 91 | .forEach(th => 92 | th.addEventListener('click', (() => 93 | { 94 | const table = th.closest('table'); 95 | const tbody = table.querySelector('tbody') 96 | const trows = Array.from(tbody.querySelectorAll('tr')) 97 | trows.slice(0, -SKIP_END_ROWS) 98 | .sort(comparer(th, th.asc = !th.asc)) // Give each column an individual sort direction 99 | .concat(trows.splice(-SKIP_END_ROWS)) // Don't sort the last rows, as they are not class reference entries. 100 | .forEach(tr => tbody.appendChild(tr) ); 101 | }))); 102 | } 103 | --------------------------------------------------------------------------------