Unified · Split
| @@ -13,13 +13,13 @@ jobs: · 12 unmodified lines | |||
| 13 | steps: | 13 | steps: |
| 14 | - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 | 14 | - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 |
| 15 | - name: Set up Ruby | 15 | - name: Set up Ruby |
| 16 | uses: ruby/setup-ruby@540484a3c0f308b08619664ec40bf6c371d172c3 # v1.205.0 | 16 | uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0 |
| 17 | with: | 17 | with: |
| 18 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically | 18 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically |
| 19 | - name: Run tests | 19 | - name: Run tests |
| 20 | run: bundle exec rake | 20 | run: bundle exec rake |
| 21 | - name: Deploy to Heroku | 21 | - name: Deploy to Heroku |
| 22 | uses: akhileshns/heroku-deploy@581dd286c962b6972d427fcf8980f60755c15520 # v3.13.15 | 22 | uses: akhileshns/heroku-deploy@e3eb99d45a8e2ec5dca08735e089607befa4bf28 # v3.14.15 |
| 23 | with: | 23 | with: |
| 24 | heroku_api_key: ${{secrets.HEROKU_API_KEY}} | 24 | heroku_api_key: ${{secrets.HEROKU_API_KEY}} |
| 25 | heroku_app_name: "devdocs" | 25 | heroku_app_name: "devdocs" |
| @@ -11,7 +11,7 @@ jobs: · 10 unmodified lines | |||
| 11 | steps: | 11 | steps: |
| 12 | - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 | 12 | - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 |
| 13 | - name: Set up Ruby | 13 | - name: Set up Ruby |
| 14 | uses: ruby/setup-ruby@540484a3c0f308b08619664ec40bf6c371d172c3 # v1.205.0 | 14 | uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0 |
| 15 | with: | 15 | with: |
| 16 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically | 16 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically |
| 17 | - name: Generate report | 17 | - name: Generate report |
| @@ -11,7 +11,7 @@ jobs: · 10 unmodified lines | |||
| 11 | steps: | 11 | steps: |
| 12 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | 12 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
| 13 | - name: Set up Ruby | 13 | - name: Set up Ruby |
| 14 | uses: ruby/setup-ruby@540484a3c0f308b08619664ec40bf6c371d172c3 # v1.205.0 | 14 | uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0 |
| 15 | with: | 15 | with: |
| 16 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically | 16 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically |
| 17 | - name: Run tests | 17 | - name: Run tests |
| @@ -1 +1 @@ | |||
| 1 | 3.3.6 | 1 | 3.4.2 |
| @@ -1 +1 @@ | |||
| 1 | ruby 3.3.6 | 1 | ruby 3.4.2 |
| @@ -1,4 +1,4 @@ | |||
| 1 | Copyright 2013-2024 Thibaut Courouble and other contributors | 1 | Copyright 2013-2025 Thibaut Courouble and other contributors |
| 2 | 2 | ||
| 3 | This Source Code Form is subject to the terms of the Mozilla Public | 3 | This Source Code Form is subject to the terms of the Mozilla Public |
| 4 | License, v. 2.0. If a copy of the MPL was not distributed with this | 4 | License, v. 2.0. If a copy of the MPL was not distributed with this |
| @@ -1,4 +1,4 @@ | |||
| 1 | FROM ruby:3.3.6 | 1 | FROM ruby:3.4.2 |
| 2 | ENV LANG=C.UTF-8 | 2 | ENV LANG=C.UTF-8 |
| 3 | ENV ENABLE_SERVICE_WORKER=true | 3 | ENV ENABLE_SERVICE_WORKER=true |
| 4 | 4 | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | FROM ruby:3.3.6-alpine | 1 | FROM ruby:3.4.2-alpine |
| 2 | 2 | ||
| 3 | ENV LANG=C.UTF-8 | 3 | ENV LANG=C.UTF-8 |
| 4 | ENV ENABLE_SERVICE_WORKER=true | 4 | ENV ENABLE_SERVICE_WORKER=true |
| @@ -1,5 +1,5 @@ | |||
| 1 | source 'https://rubygems.org' | 1 | source 'https://rubygems.org' |
| 2 | ruby '3.3.6' | 2 | ruby '3.4.2' |
| 3 | 3 | ||
| 4 | gem 'activesupport', require: false | 4 | gem 'activesupport', require: false |
| 5 | gem 'html-pipeline' | 5 | gem 'html-pipeline' |
| @@ -36,7 +36,8 @@ GEM · 35 unmodified lines | |||
| 36 | exifr (1.4.0) | 36 | exifr (1.4.0) |
| 37 | ffi (1.15.5) | 37 | ffi (1.15.5) |
| 38 | fspath (3.1.2) | 38 | fspath (3.1.2) |
| 39 | highline (2.0.3) | 39 | highline (3.1.2) |
| 40 | reline | ||
| 40 | html-pipeline (2.14.3) | 41 | html-pipeline (2.14.3) |
| 41 | activesupport (>= 2) | 42 | activesupport (>= 2) |
| 42 | nokogiri (>= 1.4) | 43 | nokogiri (>= 1.4) |
| @@ -53,6 +54,7 @@ GEM · 10 unmodified lines | |||
| 53 | image_optim (~> 0.19) | 54 | image_optim (~> 0.19) |
| 54 | image_size (3.3.0) | 55 | image_size (3.3.0) |
| 55 | in_threads (1.6.0) | 56 | in_threads (1.6.0) |
| 57 | io-console (0.8.0) | ||
| 56 | logger (1.6.2) | 58 | logger (1.6.2) |
| 57 | method_source (1.0.0) | 59 | method_source (1.0.0) |
| 58 | mini_portile2 (2.8.8) | 60 | mini_portile2 (2.8.8) |
| @@ -61,7 +63,7 @@ GEM · 2 unmodified lines | |||
| 61 | mustermann (3.0.3) | 63 | mustermann (3.0.3) |
| 62 | ruby2_keywords (~> 0.0.1) | 64 | ruby2_keywords (~> 0.0.1) |
| 63 | newrelic_rpm (8.16.0) | 65 | newrelic_rpm (8.16.0) |
| 64 | nokogiri (1.17.2) | 66 | nokogiri (1.18.3) |
| 65 | mini_portile2 (~> 2.8.2) | 67 | mini_portile2 (~> 2.8.2) |
| 66 | racc (~> 1.4) | 68 | racc (~> 1.4) |
| 67 | options (2.3.2) | 69 | options (2.3.2) |
| @@ -76,7 +78,7 @@ GEM · 8 unmodified lines | |||
| 76 | byebug (~> 11.0) | 78 | byebug (~> 11.0) |
| 77 | pry (>= 0.13, < 0.15) | 79 | pry (>= 0.13, < 0.15) |
| 78 | racc (1.8.1) | 80 | racc (1.8.1) |
| 79 | rack (2.2.10) | 81 | rack (2.2.11) |
| 80 | rack-protection (3.2.0) | 82 | rack-protection (3.2.0) |
| 81 | base64 (>= 0.1.0) | 83 | base64 (>= 0.1.0) |
| 82 | rack (~> 2.2, >= 2.2.4) | 84 | rack (~> 2.2, >= 2.2.4) |
| @@ -88,6 +90,8 @@ GEM · 5 unmodified lines | |||
| 88 | rb-inotify (0.10.1) | 90 | rb-inotify (0.10.1) |
| 89 | ffi (~> 1.0) | 91 | ffi (~> 1.0) |
| 90 | redcarpet (3.6.0) | 92 | redcarpet (3.6.0) |
| 93 | reline (0.6.0) | ||
| 94 | io-console (~> 0.5) | ||
| 91 | rexml (3.3.9) | 95 | rexml (3.3.9) |
| 92 | rouge (1.11.1) | 96 | rouge (1.11.1) |
| 93 | rr (3.1.1) | 97 | rr (3.1.1) |
| @@ -126,14 +130,14 @@ GEM · 32 unmodified lines | |||
| 126 | strings-ansi (0.2.0) | 130 | strings-ansi (0.2.0) |
| 127 | terminal-table (3.0.2) | 131 | terminal-table (3.0.2) |
| 128 | unicode-display_width (>= 1.1.1, < 3) | 132 | unicode-display_width (>= 1.1.1, < 3) |
| 129 | terser (1.2.4) | 133 | terser (1.2.5) |
| 130 | execjs (>= 0.3.0, < 3) | 134 | execjs (>= 0.3.0, < 3) |
| 131 | thin (1.8.2) | 135 | thin (1.8.2) |
| 132 | daemons (~> 1.0, >= 1.0.9) | 136 | daemons (~> 1.0, >= 1.0.9) |
| 133 | eventmachine (~> 1.0, >= 1.0.4) | 137 | eventmachine (~> 1.0, >= 1.0.4) |
| 134 | rack (>= 1, < 3) | 138 | rack (>= 1, < 3) |
| 135 | thor (1.3.2) | 139 | thor (1.3.2) |
| 136 | tilt (2.4.0) | 140 | tilt (2.6.0) |
| 137 | tty-pager (0.14.0) | 141 | tty-pager (0.14.0) |
| 138 | strings (~> 0.2.0) | 142 | strings (~> 0.2.0) |
| 139 | tty-screen (~> 0.8) | 143 | tty-screen (~> 0.8) |
| @@ -187,7 +191,7 @@ DEPENDENCIES · 47 unmodified lines | |||
| 187 | yajl-ruby | 191 | yajl-ruby |
| 188 | 192 | ||
| 189 | RUBY VERSION | 193 | RUBY VERSION |
| 190 | ruby 3.3.6p108 | 194 | ruby 3.4.2p28 |
| 191 | 195 | ||
| 192 | BUNDLED WITH | 196 | BUNDLED WITH |
| 193 | 2.4.6 | 197 | 2.4.6 |
| @@ -25,12 +25,12 @@ Unless you wish to contribute to the project, we recommend using the hosted vers · 24 unmodified lines | |||
| 25 | The easiest way to run DevDocs locally is using Docker: | 25 | The easiest way to run DevDocs locally is using Docker: |
| 26 | 26 | ||
| 27 | ```sh | 27 | ```sh |
| 28 | docker run --name devdocs -d -p 9292:9292 ghcr.io/freecodcamp/devdocs:latest | 28 | docker run --name devdocs -d -p 9292:9292 ghcr.io/freecodecamp/devdocs:latest |
| 29 | ``` | 29 | ``` |
| 30 | 30 | ||
| 31 | This will start DevDocs at [localhost:9292](http://localhost:9292). We provide both regular and Alpine-based images: | 31 | This will start DevDocs at [localhost:9292](http://localhost:9292). We provide both regular and Alpine-based images: |
| 32 | - `ghcr.io/freecodcamp/devdocs:latest` - Standard image | 32 | - `ghcr.io/freecodecamp/devdocs:latest` - Standard image |
| 33 | - `ghcr.io/freecodcamp/devdocs:latest-alpine` - Alpine-based (smaller size) | 33 | - `ghcr.io/freecodecamp/devdocs:latest-alpine` - Alpine-based (smaller size) |
| 34 | 34 | ||
| 35 | Images are automatically built and updated monthly with the latest documentation. | 35 | Images are automatically built and updated monthly with the latest documentation. |
| 36 | 36 | ||
| @@ -195,7 +195,7 @@ Made something cool? Feel free to open a PR to add a new row to this table! You · 158 unmodified lines | |||
| 195 | 195 | ||
| 196 | ## Copyright / License | 196 | ## Copyright / License |
| 197 | 197 | ||
| 198 | Copyright 2013–2024 Thibaut Courouble and [other contributors](https://github.com/freeCodeCamp/devdocs/graphs/contributors) | 198 | Copyright 2013–2025 Thibaut Courouble and [other contributors](https://github.com/freeCodeCamp/devdocs/graphs/contributors) |
| 199 | 199 | ||
| 200 | This software is licensed under the terms of the Mozilla Public License v2.0. See the [COPYRIGHT](./COPYRIGHT) and [LICENSE](./LICENSE) files. | 200 | This software is licensed under the terms of the Mozilla Public License v2.0. See the [COPYRIGHT](./COPYRIGHT) and [LICENSE](./LICENSE) files. |
| 201 | 201 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright 2013-2024 Thibaut Courouble and other contributors | 2 | * Copyright 2013-2025 Thibaut Courouble and other contributors |
| 3 | * | 3 | * |
| 4 | * This source code is licensed under the terms of the Mozilla | 4 | * This source code is licensed under the terms of the Mozilla |
| 5 | * Public License, v. 2.0, a copy of which may be obtained at: | 5 | * Public License, v. 2.0, a copy of which may be obtained at: |
| @@ -457,13 +457,13 @@ $.noop = function () {}; · 456 unmodified lines | |||
| 457 | 457 | ||
| 458 | $.popup = function (value) { | 458 | $.popup = function (value) { |
| 459 | try { | 459 | try { |
| 460 | window.open(value.href || value, "_blank", "noopener"); | ||
| 461 | } catch (error) { | ||
| 460 | const win = window.open(); | 462 | const win = window.open(); |
| 461 | if (win.opener) { | 463 | if (win.opener) { |
| 462 | win.opener = null; | 464 | win.opener = null; |
| 463 | } | 465 | } |
| 464 | win.location = value.href || value; | 466 | win.location = value.href || value; |
| 465 | } catch (error) { | ||
| 466 | window.open(value.href || value, "_blank"); | ||
| 467 | } | 467 | } |
| 468 | }; | 468 | }; |
| 469 | 469 | ||
| @@ -526,21 +526,3 @@ $.highlight = function (el, options) { · 56 unmodified lines | |||
| 526 | el.classList.add(options.className); | 526 | el.classList.add(options.className); |
| 527 | setTimeout(() => el.classList.remove(options.className), options.delay); | 527 | setTimeout(() => el.classList.remove(options.className), options.delay); |
| 528 | }; | 528 | }; |
| 529 | |||
| 530 | $.copyToClipboard = function (string) { | ||
| 531 | let result; | ||
| 532 | const textarea = document.createElement("textarea"); | ||
| 533 | textarea.style.position = "fixed"; | ||
| 534 | textarea.style.opacity = 0; | ||
| 535 | textarea.value = string; | ||
| 536 | document.body.appendChild(textarea); | ||
| 537 | try { | ||
| 538 | textarea.select(); | ||
| 539 | result = !!document.execCommand("copy"); | ||
| 540 | } catch (error) { | ||
| 541 | result = false; | ||
| 542 | } finally { | ||
| 543 | document.body.removeChild(textarea); | ||
| 544 | } | ||
| 545 | return result; | ||
| 546 | }; | ||
| @@ -1,4 +1,8 @@ | |||
| 1 | [ | 1 | [ |
| 2 | [ | ||
| 3 | "2025-02-16", | ||
| 4 | "New documentation: <a href=\"/openlayers/\">OpenLayers</a>" | ||
| 5 | ], | ||
| 2 | [ | 6 | [ |
| 3 | "2024-11-23", | 7 | "2024-11-23", |
| 4 | "New documentation: <a href=\"/duckdb/\">DuckDB</a>" | 8 | "New documentation: <a href=\"/duckdb/\">DuckDB</a>" |
| @@ -32,7 +32,7 @@ app.templates.aboutPage = function () { · 31 unmodified lines | |||
| 32 | 32 | ||
| 33 | <h2 class="_block-heading" id="copyright">Copyright and License</h2> | 33 | <h2 class="_block-heading" id="copyright">Copyright and License</h2> |
| 34 | <p class="_note"> | 34 | <p class="_note"> |
| 35 | <strong>Copyright 2013–2024 Thibaut Courouble and <a href="https://github.com/freeCodeCamp/devdocs/graphs/contributors">other contributors</a></strong><br> | 35 | <strong>Copyright 2013–2025 Thibaut Courouble and <a href="https://github.com/freeCodeCamp/devdocs/graphs/contributors">other contributors</a></strong><br> |
| 36 | This software is licensed under the terms of the Mozilla Public License v2.0.<br> | 36 | This software is licensed under the terms of the Mozilla Public License v2.0.<br> |
| 37 | You may obtain a copy of the source code at <a href="https://github.com/freeCodeCamp/devdocs">github.com/freeCodeCamp/devdocs</a>.<br> | 37 | You may obtain a copy of the source code at <a href="https://github.com/freeCodeCamp/devdocs">github.com/freeCodeCamp/devdocs</a>.<br> |
| 38 | For more information, see the <a href="https://github.com/freeCodeCamp/devdocs/blob/main/COPYRIGHT">COPYRIGHT</a> | 38 | For more information, see the <a href="https://github.com/freeCodeCamp/devdocs/blob/main/COPYRIGHT">COPYRIGHT</a> |
| @@ -96,16 +96,9 @@ app.views.EntryPage = class EntryPage extends app.View { · 95 unmodified lines | |||
| 96 | return content; | 96 | return content; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | const links = (() => { | 99 | const links = Object.entries(this.entry.doc.links).map(([link, url]) => { |
| 100 | const result = []; | 100 | return `<a href="${url}" class="_links-link">${EntryPage.LINKS[link]}</a>`; |
| 101 | for (var link in this.entry.doc.links) { | 101 | }); |
| 102 | var url = this.entry.doc.links[link]; | ||
| 103 | result.push( | ||
| 104 | `<a href="${url}" class="_links-link">${EntryPage.LINKS[link]}</a>`, | ||
| 105 | ); | ||
| 106 | } | ||
| 107 | return result; | ||
| 108 | })(); | ||
| 109 | 102 | ||
| 110 | return `<p class="_links">${links.join("")}</p>${content}`; | 103 | return `<p class="_links">${links.join("")}</p>${content}`; |
| 111 | } | 104 | } |
| @@ -203,8 +196,8 @@ app.views.EntryPage = class EntryPage extends app.View { · 91 unmodified lines | |||
| 203 | } | 196 | } |
| 204 | 197 | ||
| 205 | restore() { | 198 | restore() { |
| 206 | let path; | 199 | const path = this.entry.filePath(); |
| 207 | if (this.cacheMap[(path = this.entry.filePath())]) { | 200 | if (this.cacheMap[[path]]) { |
| 208 | this.render(this.cacheMap[path], true); | 201 | this.render(this.cacheMap[path], true); |
| 209 | return true; | 202 | return true; |
| 210 | } | 203 | } |
| @@ -217,18 +210,17 @@ app.views.EntryPage = class EntryPage extends app.View { · 6 unmodified lines | |||
| 217 | this.load(); | 210 | this.load(); |
| 218 | } else if (target.classList.contains("_pre-clip")) { | 211 | } else if (target.classList.contains("_pre-clip")) { |
| 219 | $.stopEvent(event); | 212 | $.stopEvent(event); |
| 220 | target.classList.add( | 213 | navigator.clipboard.writeText(target.parentNode.textContent).then( |
| 221 | $.copyToClipboard(target.parentNode.textContent) | 214 | () => target.classList.add("_pre-clip-success"), |
| 222 | ? "_pre-clip-success" | 215 | () => target.classList.add("_pre-clip-error"), |
| 223 | : "_pre-clip-error", | ||
| 224 | ); | 216 | ); |
| 225 | setTimeout(() => (target.className = "_pre-clip"), 2000); | 217 | setTimeout(() => (target.className = "_pre-clip"), 2000); |
| 226 | } | 218 | } |
| 227 | } | 219 | } |
| 228 | 220 | ||
| 229 | onAltC() { | 221 | onAltC() { |
| 230 | let link; | 222 | const link = this.find("._attribution:last-child ._attribution-link"); |
| 231 | if (!(link = this.find("._attribution:last-child ._attribution-link"))) { | 223 | if (!link) { |
| 232 | return; | 224 | return; |
| 233 | } | 225 | } |
| 234 | console.log(link.href + location.hash); | 226 | console.log(link.href + location.hash); |
| @@ -236,8 +228,8 @@ app.views.EntryPage = class EntryPage extends app.View { · 1 unmodified line | |||
| 236 | } | 228 | } |
| 237 | 229 | ||
| 238 | onAltO() { | 230 | onAltO() { |
| 239 | let link; | 231 | const link = this.find("._attribution:last-child ._attribution-link"); |
| 240 | if (!(link = this.find("._attribution:last-child ._attribution-link"))) { | 232 | if (!link) { |
| 241 | return; | 233 | return; |
| 242 | } | 234 | } |
| 243 | this.delay(() => $.popup(link.href + location.hash)); | 235 | this.delay(() => $.popup(link.href + location.hash)); |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | |||
| 3 | //= depend_on sprites/docs.json | 3 | //= depend_on sprites/docs.json |
| 4 | 4 | ||
| 5 | /*! | 5 | /*! |
| 6 | * Copyright 2013-2024 Thibaut Courouble and other contributors | 6 | * Copyright 2013-2025 Thibaut Courouble and other contributors |
| 7 | * | 7 | * |
| 8 | * This source code is licensed under the terms of the Mozilla | 8 | * This source code is licensed under the terms of the Mozilla |
| 9 | * Public License, v. 2.0, a copy of which may be obtained at: | 9 | * Public License, v. 2.0, a copy of which may be obtained at: |
| @@ -97,6 +97,7 @@ · 87 unmodified lines | |||
| 97 | 'pages/nushell', | 97 | 'pages/nushell', |
| 98 | 'pages/octave', | 98 | 'pages/octave', |
| 99 | 'pages/openjdk', | 99 | 'pages/openjdk', |
| 100 | 'pages/openlayers', | ||
| 100 | 'pages/perl', | 101 | 'pages/perl', |
| 101 | 'pages/phalcon', | 102 | 'pages/phalcon', |
| 102 | 'pages/phaser', | 103 | 'pages/phaser', |
| @@ -28,6 +28,9 @@ · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | p > code, li > code { @extend %label; } | 29 | p > code, li > code { @extend %label; } |
| 30 | 30 | ||
| 31 | details { @extend %box; } | ||
| 32 | summary > div { display: inline; } | ||
| 33 | |||
| 31 | > .note, | 34 | > .note, |
| 32 | .notecard, // MDN 2021 | 35 | .notecard, // MDN 2021 |
| 33 | .notice, | 36 | .notice, |
| @@ -0,0 +1,10 @@ | |||
| 1 | ._openlayers { | ||
| 2 | @extend %simple; | ||
| 3 | .nameContainer { | ||
| 4 | @extend %block-label; | ||
| 5 | > * { display: inline-block; margin: 0; } | ||
| 6 | > .tag-source { float: right; } | ||
| 7 | } | ||
| 8 | .card { @extend %box; margin-bottom: 1rem; padding: 1rem; } | ||
| 9 | .signature, .type-signature { @extend %code; } | ||
| 10 | } | ||
| @@ -254,6 +254,17 @@ done · 253 unmodified lines | |||
| 254 | 254 | ||
| 255 | ### Nokogiri | 255 | ### Nokogiri |
| 256 | ### Ruby / Minitest | 256 | ### Ruby / Minitest |
| 257 | |||
| 258 | ```sh | ||
| 259 | git clone https://github.com/seattlerb/minitest | ||
| 260 | cd minitest/ | ||
| 261 | bundle install | ||
| 262 | bundle add rdoc hoe | ||
| 263 | bundle exec rak docs | ||
| 264 | cd .. | ||
| 265 | cp -r minitest/docs $DEVDOCS/docs/minitest | ||
| 266 | ``` | ||
| 267 | |||
| 257 | ### Ruby on Rails | 268 | ### Ruby on Rails |
| 258 | * Download a release at https://github.com/rails/rails/releases or clone https://github.com/rails/rails.git (checkout to the branch of the rails' version that is going to be scraped) | 269 | * Download a release at https://github.com/rails/rails/releases or clone https://github.com/rails/rails.git (checkout to the branch of the rails' version that is going to be scraped) |
| 259 | * Open `railties/lib/rails/api/task.rb` and comment out any code related to sdoc (`configure_sdoc`) | 270 | * Open `railties/lib/rails/api/task.rb` and comment out any code related to sdoc (`configure_sdoc`) |
| @@ -7,8 +7,10 @@ module Docs · 6 unmodified lines | |||
| 7 | css('devsite-feature-tooltip').remove | 7 | css('devsite-feature-tooltip').remove |
| 8 | css('devsite-thumb-rating').remove | 8 | css('devsite-thumb-rating').remove |
| 9 | css('devsite-toc').remove | 9 | css('devsite-toc').remove |
| 10 | css('devsite-feedback').remove | ||
| 10 | css('a.button-with-icon').remove | 11 | css('a.button-with-icon').remove |
| 11 | css('button.devsite-heading-link').remove | 12 | css('button.devsite-heading-link').remove |
| 13 | css('.devsite-article-body > span:first-child[style="float: right; line-height: 36px"]').remove | ||
| 12 | doc | 14 | doc |
| 13 | end | 15 | end |
| 14 | 16 | ||
| @@ -42,7 +42,7 @@ module Docs · 41 unmodified lines | |||
| 42 | def fix_url(url) | 42 | def fix_url(url) |
| 43 | if context[:redirections] | 43 | if context[:redirections] |
| 44 | url = URL.parse(url) | 44 | url = URL.parse(url) |
| 45 | path = url.path.downcase | 45 | path = url.path ? url.path.downcase : nil |
| 46 | 46 | ||
| 47 | if context[:redirections].key?(path) | 47 | if context[:redirections].key?(path) |
| 48 | url.path = context[:redirections][path] | 48 | url.path = context[:redirections][path] |
| @@ -16,8 +16,12 @@ module Docs · 15 unmodified lines | |||
| 16 | name | 16 | name |
| 17 | else | 17 | else |
| 18 | return at_css('h1').content.strip unless at_css('.type-name') | 18 | return at_css('h1').content.strip unless at_css('.type-name') |
| 19 | name = at_css('.type-name').children.last.content.strip | 19 | name = at_css('.type-name').children.reject { |n| n.matches?('.kind') } |
| 20 | name.map! { |n| n.text.strip } | ||
| 21 | name.reject! &:empty? | ||
| 22 | name = name.join | ||
| 20 | name.remove! %r{\(.*\)} | 23 | name.remove! %r{\(.*\)} |
| 24 | name.strip! | ||
| 21 | name | 25 | name |
| 22 | end | 26 | end |
| 23 | end | 27 | end |
| @@ -34,7 +34,9 @@ module Docs · 33 unmodified lines | |||
| 34 | node.name = 'h3' | 34 | node.name = 'h3' |
| 35 | node['id'] = id | 35 | node['id'] = id |
| 36 | 36 | ||
| 37 | source_href = node.at_css('a.icon-action[title="View Source"]').attr('href') | 37 | a = node.at_css('a.icon-action[title="View Source"]') |
| 38 | a ||= node.at_css('a.icon-action[aria-label="View Source"]') | ||
| 39 | source_href = a.attr('href') | ||
| 38 | 40 | ||
| 39 | node.content = node.at_css('.signature').inner_text | 41 | node.content = node.at_css('.signature').inner_text |
| 40 | node << %(<a href="#{source_href}" class="source">Source</a>) | 42 | node << %(<a href="#{source_href}" class="source">Source</a>) |
| @@ -3,7 +3,7 @@ module Docs · 2 unmodified lines | |||
| 3 | class CleanHtmlFilter < Filter | 3 | class CleanHtmlFilter < Filter |
| 4 | def call | 4 | def call |
| 5 | i = 1 | 5 | i = 1 |
| 6 | n = at_css("#navmenu a[href='#{result[:path].split('/').last}']").parent | 6 | n = at_css("#navmenu .submenu-content a[href='#{result[:path].split('/').last}']").parent |
| 7 | i += 1 while n && n = n.previous_element | 7 | i += 1 while n && n = n.previous_element |
| 8 | at_css('h1')['data-level'] = i | 8 | at_css('h1')['data-level'] = i |
| 9 | 9 | ||
| @@ -0,0 +1,18 @@ | |||
| 1 | module Docs | ||
| 2 | class Openlayers | ||
| 3 | class CleanHtmlFilter < Filter | ||
| 4 | def call | ||
| 5 | @doc = at_css('section') | ||
| 6 | |||
| 7 | at_css('h2').name = 'h1' if at_css('h2') | ||
| 8 | |||
| 9 | css('pre.prettyprint').each do |node| | ||
| 10 | node['data-language'] = node['class'].include?('html') ? 'html' : 'js' | ||
| 11 | node.content = node.content | ||
| 12 | end | ||
| 13 | |||
| 14 | doc | ||
| 15 | end | ||
| 16 | end | ||
| 17 | end | ||
| 18 | end | ||
| @@ -0,0 +1,23 @@ | |||
| 1 | module Docs | ||
| 2 | class Openlayers | ||
| 3 | class EntriesFilter < Docs::EntriesFilter | ||
| 4 | def get_name | ||
| 5 | at_css('h2').text.split('~').last.strip | ||
| 6 | end | ||
| 7 | |||
| 8 | def get_type | ||
| 9 | slug[/ol_([^_]+)_/, 1] or 'ol' | ||
| 10 | end | ||
| 11 | |||
| 12 | def additional_entries | ||
| 13 | css('h4.name').each_with_object [] do |node, entries| | ||
| 14 | node['id'] = node.previous_element['id'] | ||
| 15 | next if node.at_css('.inherited') | ||
| 16 | name = node.children.find {|n| n.text? }.text.strip | ||
| 17 | name.prepend "#{self.name}." | ||
| 18 | entries << [name, node['id']] | ||
| 19 | end | ||
| 20 | end | ||
| 21 | end | ||
| 22 | end | ||
| 23 | end | ||
| @@ -2,7 +2,7 @@ module Docs · 1 unmodified line | |||
| 2 | class Phpunit | 2 | class Phpunit |
| 3 | class CleanHtmlFilter < Filter | 3 | class CleanHtmlFilter < Filter |
| 4 | def call | 4 | def call |
| 5 | @doc = at_css('.section') if not root_page? | 5 | @doc = at_css('section') if not root_page? |
| 6 | 6 | ||
| 7 | css('pre').each do |node| | 7 | css('pre').each do |node| |
| 8 | node['class'] = 'highlight' | 8 | node['class'] = 'highlight' |
| @@ -13,8 +13,11 @@ module Docs · 12 unmodified lines | |||
| 13 | meta = Nokogiri::XML::Node.new 'dl', doc.document | 13 | meta = Nokogiri::XML::Node.new 'dl', doc.document |
| 14 | meta['class'] = 'meta' | 14 | meta['class'] = 'meta' |
| 15 | 15 | ||
| 16 | if parent = at_css('#parent-class-section') | 16 | parent = at_css('#parent-class-section') |
| 17 | meta << %(<dt>Parent:</dt><dd class="meta-parent">#{parent.at_css('.link').inner_html.strip}</dd>) | 17 | if parent && link = parent.at_css('.link') |
| 18 | meta << %(<dt>Parent:</dt><dd class="meta-parent">#{link.inner_html.strip}</dd>) | ||
| 19 | elsif parent && link = parent.at_css('a') | ||
| 20 | meta << %(<dt>Parent:</dt><dd class="meta-parent">#{link.to_html}</dd>) | ||
| 18 | end | 21 | end |
| 19 | 22 | ||
| 20 | if includes = at_css('#includes-section') | 23 | if includes = at_css('#includes-section') |
| @@ -71,7 +71,7 @@ module Docs · 70 unmodified lines | |||
| 71 | # name from the HTML because companion object classes may be broken out into | 71 | # name from the HTML because companion object classes may be broken out into |
| 72 | # their own entries (by the source documentation). When that happens, | 72 | # their own entries (by the source documentation). When that happens, |
| 73 | # we want to group these classes (like `scala.reflect.api.Annotations.Annotation`) | 73 | # we want to group these classes (like `scala.reflect.api.Annotations.Annotation`) |
| 74 | # under the package name, and not the fully-qualfied name which would | 74 | # under the package name, and not the fully-qualified name which would |
| 75 | # include the companion object. | 75 | # include the companion object. |
| 76 | def package_name | 76 | def package_name |
| 77 | name = package_drop_last(slug_parts) | 77 | name = package_drop_last(slug_parts) |
| @@ -3,7 +3,8 @@ module Docs · 2 unmodified lines | |||
| 3 | class EntriesFilter < Docs::EntriesFilter | 3 | class EntriesFilter < Docs::EntriesFilter |
| 4 | def get_name | 4 | def get_name |
| 5 | name = at_css('h1').content.strip | 5 | name = at_css('h1').content.strip |
| 6 | name.remove! "\u{00b6}" | 6 | name.delete_suffix! "¶" |
| 7 | name.delete_suffix! "#" | ||
| 7 | 8 | ||
| 8 | if slug.start_with?('api') | 9 | if slug.start_with?('api') |
| 9 | name.remove! 'Module: ' | 10 | name.remove! 'Module: ' |
| @@ -2,6 +2,7 @@ module Docs · 1 unmodified line | |||
| 2 | class ScikitLearn | 2 | class ScikitLearn |
| 3 | class CleanHtmlFilter < Filter | 3 | class CleanHtmlFilter < Filter |
| 4 | def call | 4 | def call |
| 5 | @doc = at_css('main article', 'main') | ||
| 5 | if root_page? | 6 | if root_page? |
| 6 | css('.row').each do |node| | 7 | css('.row').each do |node| |
| 7 | html = '<dl>' | 8 | html = '<dl>' |
| @@ -46,6 +46,9 @@ module Docs · 45 unmodified lines | |||
| 46 | node.replace("<p>#{node.to_html}</p>") | 46 | node.replace("<p>#{node.to_html}</p>") |
| 47 | end | 47 | end |
| 48 | 48 | ||
| 49 | css('span[slot="popout-heading"]').remove | ||
| 50 | css('span[slot="popout-contents"]').remove | ||
| 51 | |||
| 49 | doc | 52 | doc |
| 50 | end | 53 | end |
| 51 | end | 54 | end |
| @@ -248,6 +248,10 @@ module Docs · 247 unmodified lines | |||
| 248 | "text": "usePreferredReducedMotion", | 248 | "text": "usePreferredReducedMotion", |
| 249 | "link": "/core/usePreferredReducedMotion/" | 249 | "link": "/core/usePreferredReducedMotion/" |
| 250 | }, | 250 | }, |
| 251 | { | ||
| 252 | "text": "usePreferredReducedTransparency", | ||
| 253 | "link": "/core/usePreferredReducedTransparency/" | ||
| 254 | }, | ||
| 251 | { | 255 | { |
| 252 | "text": "useScreenOrientation", | 256 | "text": "useScreenOrientation", |
| 253 | "link": "/core/useScreenOrientation/" | 257 | "link": "/core/useScreenOrientation/" |
| @@ -264,6 +268,10 @@ module Docs · 10 unmodified lines | |||
| 264 | "text": "useShare", | 268 | "text": "useShare", |
| 265 | "link": "/core/useShare/" | 269 | "link": "/core/useShare/" |
| 266 | }, | 270 | }, |
| 271 | { | ||
| 272 | "text": "useSSRWidth", | ||
| 273 | "link": "/core/useSSRWidth/" | ||
| 274 | }, | ||
| 267 | { | 275 | { |
| 268 | "text": "useStyleTag", | 276 | "text": "useStyleTag", |
| 269 | "link": "/core/useStyleTag/" | 277 | "link": "/core/useStyleTag/" |
| @@ -313,6 +321,10 @@ module Docs · 43 unmodified lines | |||
| 313 | "text": "onClickOutside", | 321 | "text": "onClickOutside", |
| 314 | "link": "/core/onClickOutside/" | 322 | "link": "/core/onClickOutside/" |
| 315 | }, | 323 | }, |
| 324 | { | ||
| 325 | "text": "onElementRemoval", | ||
| 326 | "link": "/core/onElementRemoval/" | ||
| 327 | }, | ||
| 316 | { | 328 | { |
| 317 | "text": "onKeyStroke", | 329 | "text": "onKeyStroke", |
| 318 | "link": "/core/onKeyStroke/" | 330 | "link": "/core/onKeyStroke/" |
| @@ -788,6 +800,10 @@ module Docs · 469 unmodified lines | |||
| 788 | { | 800 | { |
| 789 | "text": "Time", | 801 | "text": "Time", |
| 790 | "items": [ | 802 | "items": [ |
| 803 | { | ||
| 804 | "text": "useCountdown", | ||
| 805 | "link": "/core/useCountdown/" | ||
| 806 | }, | ||
| 791 | { | 807 | { |
| 792 | "text": "useDateFormat", | 808 | "text": "useDateFormat", |
| 793 | "link": "/shared/useDateFormat/" | 809 | "link": "/shared/useDateFormat/" |
| @@ -12,6 +12,11 @@ module Docs · 11 unmodified lines | |||
| 12 | Licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. | 12 | Licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. |
| 13 | HTML | 13 | HTML |
| 14 | 14 | ||
| 15 | version '8.0' do | ||
| 16 | self.release = '8.0.0' | ||
| 17 | self.base_url = 'https://bazel.build/versions/8.0.0/reference/be/' | ||
| 18 | end | ||
| 19 | |||
| 15 | version '7.0' do | 20 | version '7.0' do |
| 16 | self.release = '7.0.0' | 21 | self.release = '7.0.0' |
| 17 | self.base_url = 'https://bazel.build/versions/7.0.0/reference/be/' | 22 | self.base_url = 'https://bazel.build/versions/7.0.0/reference/be/' |
| @@ -2,7 +2,7 @@ module Docs · 1 unmodified line | |||
| 2 | class Crystal < UrlScraper | 2 | class Crystal < UrlScraper |
| 3 | include MultipleBaseUrls | 3 | include MultipleBaseUrls |
| 4 | self.type = 'crystal' | 4 | self.type = 'crystal' |
| 5 | self.release = '1.14.0' | 5 | self.release = '1.15.1' |
| 6 | self.base_urls = [ | 6 | self.base_urls = [ |
| 7 | "https://crystal-lang.org/api/#{release}/", | 7 | "https://crystal-lang.org/api/#{release}/", |
| 8 | "https://crystal-lang.org/reference/#{release[0..2]}/", | 8 | "https://crystal-lang.org/reference/#{release[0..2]}/", |
| @@ -21,6 +21,7 @@ module Docs · 12 unmodified lines | |||
| 21 | 21 | ||
| 22 | options[:skip_patterns] = [ | 22 | options[:skip_patterns] = [ |
| 23 | %r{\ACrystal/System/}, | 23 | %r{\ACrystal/System/}, |
| 24 | %r{\ACrystal/PointerPairingHeap/}, | ||
| 24 | %r{\AIO/Evented.html\z}, | 25 | %r{\AIO/Evented.html\z}, |
| 25 | %r{\ARegex/PCRE2.html\z} | 26 | %r{\ARegex/PCRE2.html\z} |
| 26 | ] | 27 | ] |
| @@ -34,7 +35,7 @@ module Docs · 7 unmodified lines | |||
| 34 | HTML | 35 | HTML |
| 35 | else | 36 | else |
| 36 | <<-HTML | 37 | <<-HTML |
| 37 | © 2012–2024 Manas Technology Solutions.<br> | 38 | © 2012–2025 Manas Technology Solutions.<br> |
| 38 | Licensed under the Apache License, Version 2.0. | 39 | Licensed under the Apache License, Version 2.0. |
| 39 | HTML | 40 | HTML |
| 40 | end | 41 | end |
| @@ -96,7 +96,7 @@ module Docs · 95 unmodified lines | |||
| 96 | 96 | ||
| 97 | def get_latest_version(opts) | 97 | def get_latest_version(opts) |
| 98 | doc = fetch_doc('https://docs.docker.com/engine/release-notes/', opts) | 98 | doc = fetch_doc('https://docs.docker.com/engine/release-notes/', opts) |
| 99 | latest_version = doc.at_css('.DocSearch-content > h2 > a').content.strip | 99 | latest_version = doc.at_css('h2.scroll-mt-20 > a').content.strip |
| 100 | latest_version.rpartition(' ')[-1] | 100 | latest_version.rpartition(' ')[-1] |
| 101 | end | 101 | end |
| 102 | end | 102 | end |
| @@ -30,6 +30,18 @@ module Docs · 29 unmodified lines | |||
| 30 | "https://hexdocs.pm/mix/#{self.class.release}/Mix.html" ] | 30 | "https://hexdocs.pm/mix/#{self.class.release}/Mix.html" ] |
| 31 | end | 31 | end |
| 32 | 32 | ||
| 33 | version '1.18' do | ||
| 34 | self.release = '1.18.1' | ||
| 35 | self.base_urls = [ | ||
| 36 | "https://hexdocs.pm/elixir/#{release}/", | ||
| 37 | "https://hexdocs.pm/eex/#{release}/", | ||
| 38 | "https://hexdocs.pm/ex_unit/#{release}/", | ||
| 39 | "https://hexdocs.pm/iex/#{release}/", | ||
| 40 | "https://hexdocs.pm/logger/#{release}/", | ||
| 41 | "https://hexdocs.pm/mix/#{release}/" | ||
| 42 | ] | ||
| 43 | end | ||
| 44 | |||
| 33 | version '1.17' do | 45 | version '1.17' do |
| 34 | self.release = '1.17.2' | 46 | self.release = '1.17.2' |
| 35 | self.base_urls = [ | 47 | self.base_urls = [ |
| @@ -2,7 +2,7 @@ module Docs · 1 unmodified line | |||
| 2 | class Express < UrlScraper | 2 | class Express < UrlScraper |
| 3 | self.name = 'Express' | 3 | self.name = 'Express' |
| 4 | self.type = 'express' | 4 | self.type = 'express' |
| 5 | self.release = '4.18.1' | 5 | self.release = '4.21.2' |
| 6 | self.base_url = 'https://expressjs.com/en/' | 6 | self.base_url = 'https://expressjs.com/en/' |
| 7 | self.root_path = '4x/api.html' | 7 | self.root_path = '4x/api.html' |
| 8 | self.initial_paths = %w( | 8 | self.initial_paths = %w( |
| @@ -2,7 +2,7 @@ module Docs · 1 unmodified line | |||
| 2 | class Fastapi < UrlScraper | 2 | class Fastapi < UrlScraper |
| 3 | self.name = 'FastAPI' | 3 | self.name = 'FastAPI' |
| 4 | self.type = 'fastapi' | 4 | self.type = 'fastapi' |
| 5 | self.release = '0.111.1' | 5 | self.release = '0.115.6' |
| 6 | self.base_url = 'https://fastapi.tiangolo.com/' | 6 | self.base_url = 'https://fastapi.tiangolo.com/' |
| 7 | self.root_path = '/' | 7 | self.root_path = '/' |
| 8 | self.links = { | 8 | self.links = { |
| @@ -18,6 +18,11 @@ module Docs · 17 unmodified lines | |||
| 18 | Licensed under the BSD 3-clause License. | 18 | Licensed under the BSD 3-clause License. |
| 19 | HTML | 19 | HTML |
| 20 | 20 | ||
| 21 | version do | ||
| 22 | self.release = '3.1.1' | ||
| 23 | self.base_url = "https://flask.palletsprojects.com/en/stable/" | ||
| 24 | end | ||
| 25 | |||
| 21 | version '3.0' do | 26 | version '3.0' do |
| 22 | self.release = '3.0.x' | 27 | self.release = '3.0.x' |
| 23 | self.base_url = "https://flask.palletsprojects.com/en/#{self.release}/" | 28 | self.base_url = "https://flask.palletsprojects.com/en/#{self.release}/" |
| @@ -1,7 +1,7 @@ | |||
| 1 | module Docs | 1 | module Docs |
| 2 | class Git < UrlScraper | 2 | class Git < UrlScraper |
| 3 | self.type = 'git' | 3 | self.type = 'git' |
| 4 | self.release = '2.47.1' | 4 | self.release = '2.48.1' |
| 5 | self.base_url = 'https://git-scm.com/docs' | 5 | self.base_url = 'https://git-scm.com/docs' |
| 6 | self.initial_paths = %w(/git.html) | 6 | self.initial_paths = %w(/git.html) |
| 7 | self.links = { | 7 | self.links = { |
| @@ -1,7 +1,7 @@ | |||
| 1 | module Docs | 1 | module Docs |
| 2 | class Go < UrlScraper | 2 | class Go < UrlScraper |
| 3 | self.type = 'go' | 3 | self.type = 'go' |
| 4 | self.release = '1.23.0' | 4 | self.release = '1.24.0' |
| 5 | self.base_url = 'https://golang.org/pkg/' | 5 | self.base_url = 'https://golang.org/pkg/' |
| 6 | self.links = { | 6 | self.links = { |
| 7 | home: 'https://golang.org/', | 7 | home: 'https://golang.org/', |
| @@ -10,10 +10,19 @@ module Docs · 2 unmodified lines | |||
| 10 | 10 | ||
| 11 | # Run godoc locally, since https://golang.org/pkg/ redirects to https://pkg.go.dev/std with rate limiting / scraping protection. | 11 | # Run godoc locally, since https://golang.org/pkg/ redirects to https://pkg.go.dev/std with rate limiting / scraping protection. |
| 12 | 12 | ||
| 13 | # podman run --net host --rm -it docker.io/golang:1.23.0 | 13 | # podman run --net host --rm -it docker.io/golang:1.24.0 |
| 14 | #podman# go install golang.org/x/tools/cmd/godoc@latest | 14 | #podman# go install golang.org/x/tools/cmd/godoc@latest |
| 15 | #podman# rm -r /usr/local/go/test/ | 15 | #podman# rm -r /usr/local/go/test/ |
| 16 | #podman# godoc -http 0.0.0.0:6060 -v | 16 | #podman# godoc -http 0.0.0.0:6060 -v |
| 17 | |||
| 18 | # or using alpine | ||
| 19 | # podman run --net host --rm -it alpine:latest | ||
| 20 | #podman# apk add curl | ||
| 21 | #podman# curl -LO https://go.dev/dl/go1.24.0.linux-amd64.tar.gz | ||
| 22 | #podman# tar xf go1.24.0.linux-amd64.tar.gz | ||
| 23 | #podman# go/bin/go install golang.org/x/tools/cmd/godoc@latest | ||
| 24 | #podman# /root/go/bin/godoc -http 0.0.0.0:6060 -v | ||
| 25 | |||
| 17 | self.base_url = 'http://localhost:6060/pkg/' | 26 | self.base_url = 'http://localhost:6060/pkg/' |
| 18 | 27 | ||
| 19 | html_filters.push 'clean_local_urls' | 28 | html_filters.push 'clean_local_urls' |
| @@ -59,7 +59,7 @@ module Docs · 58 unmodified lines | |||
| 59 | end | 59 | end |
| 60 | 60 | ||
| 61 | version '9' do | 61 | version '9' do |
| 62 | self.release = '9.4.2' | 62 | self.release = '9.12.1' |
| 63 | self.base_url = "https://downloads.haskell.org/~ghc/#{release}/docs/" | 63 | self.base_url = "https://downloads.haskell.org/~ghc/#{release}/docs/" |
| 64 | options[:container] = ->(filter) {filter.subpath.start_with?('users_guide') ? '.document' : '#content'} | 64 | options[:container] = ->(filter) {filter.subpath.start_with?('users_guide') ? '.document' : '#content'} |
| 65 | end | 65 | end |
| @@ -2,7 +2,7 @@ module Docs · 1 unmodified line | |||
| 2 | class JqueryUi < Jquery | 2 | class JqueryUi < Jquery |
| 3 | self.name = 'jQuery UI' | 3 | self.name = 'jQuery UI' |
| 4 | self.slug = 'jqueryui' | 4 | self.slug = 'jqueryui' |
| 5 | self.release = '1.13.0' | 5 | self.release = '1.14.1' |
| 6 | self.base_url = 'https://api.jqueryui.com' | 6 | self.base_url = 'https://api.jqueryui.com' |
| 7 | self.root_path = '/category/all' | 7 | self.root_path = '/category/all' |
| 8 | 8 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | module Docs | 1 | module Docs |
| 2 | class Dom < Mdn | 2 | class Dom < Mdn |
| 3 | # release = '2023-08-20' | 3 | # release = '2025-01-30' |
| 4 | self.name = 'Web APIs' | 4 | self.name = 'Web APIs' |
| 5 | self.slug = 'dom' | 5 | self.slug = 'dom' |
| 6 | self.base_url = 'https://developer.mozilla.org/en-US/docs/Web/API' | 6 | self.base_url = 'https://developer.mozilla.org/en-US/docs/Web/API' |
| @@ -3,7 +3,7 @@ module Docs · 2 unmodified lines | |||
| 3 | prepend FixInternalUrlsBehavior | 3 | prepend FixInternalUrlsBehavior |
| 4 | prepend FixRedirectionsBehavior | 4 | prepend FixRedirectionsBehavior |
| 5 | 5 | ||
| 6 | # release = '2024-11-18' | 6 | # release = '2025-01-30' |
| 7 | self.name = 'JavaScript' | 7 | self.name = 'JavaScript' |
| 8 | self.base_url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference' | 8 | self.base_url = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference' |
| 9 | self.links = { | 9 | self.links = { |
| @@ -47,8 +47,7 @@ module Docs · 46 unmodified lines | |||
| 47 | end | 47 | end |
| 48 | 48 | ||
| 49 | def get_latest_version(opts) | 49 | def get_latest_version(opts) |
| 50 | doc = fetch_doc('https://docs.meteor.com/#/full/', opts) | 50 | get_npm_version('meteor', opts) |
| 51 | doc.at_css('select.version-select > option').content | ||
| 52 | end | 51 | end |
| 53 | end | 52 | end |
| 54 | end | 53 | end |
| @@ -23,9 +23,7 @@ module Docs · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | def get_latest_version(opts) | 24 | def get_latest_version(opts) |
| 25 | doc = fetch_doc('https://nixos.org/manual/nix/stable/', opts) | 25 | doc = fetch_doc('https://nixos.org/manual/nix/stable/', opts) |
| 26 | json = JSON.parse(doc.at_css('body')['data-nix-channels']) | 26 | doc.at_css('a.active')['href'].scan(/([0-9.]+)/)[0][0] |
| 27 | channel = json.find { |c| c['channel'] == 'stable' } | ||
| 28 | channel['version'] | ||
| 29 | end | 27 | end |
| 30 | end | 28 | end |
| 31 | end | 29 | end |
| @@ -0,0 +1,24 @@ | |||
| 1 | module Docs | ||
| 2 | class Openlayers < UrlScraper | ||
| 3 | self.name = 'OpenLayers' | ||
| 4 | self.type = 'openlayers' | ||
| 5 | self.slug = 'openlayers' | ||
| 6 | self.release = '10.4.0' | ||
| 7 | self.base_url = "https://openlayers.org/en/latest/apidoc/" | ||
| 8 | self.links = { | ||
| 9 | home: 'https://openlayers.org/', | ||
| 10 | code: 'https://github.com/openlayers/openlayers' | ||
| 11 | } | ||
| 12 | |||
| 13 | html_filters.push 'openlayers/entries', 'openlayers/clean_html' | ||
| 14 | |||
| 15 | options[:attribution] = <<-HTML | ||
| 16 | © 2005-present, OpenLayers Contributors All rights reserved. | ||
| 17 | Licensed under the BSD 2-Clause License. | ||
| 18 | HTML | ||
| 19 | |||
| 20 | def get_latest_version(opts) | ||
| 21 | get_npm_version('ol', opts) | ||
| 22 | end | ||
| 23 | end | ||
| 24 | end | ||
| @@ -17,12 +17,21 @@ module Docs · 16 unmodified lines | |||
| 17 | options[:title] = false | 17 | options[:title] = false |
| 18 | 18 | ||
| 19 | options[:attribution] = <<-HTML | 19 | options[:attribution] = <<-HTML |
| 20 | © 2005–2020 Sebastian Bergmann<br> | 20 | © 2005–2025 Sebastian Bergmann<br> |
| 21 | Licensed under the Creative Commons Attribution 3.0 Unported License. | 21 | Licensed under the Creative Commons Attribution 3.0 Unported License. |
| 22 | HTML | 22 | HTML |
| 23 | 23 | ||
| 24 | FILTERS = %w(phpunit/clean_html phpunit/entries title) | 24 | FILTERS = %w(phpunit/clean_html phpunit/entries title) |
| 25 | 25 | ||
| 26 | version do | ||
| 27 | self.release = '12.0' | ||
| 28 | self.base_url = "https://docs.phpunit.de/en/#{release}/" | ||
| 29 | |||
| 30 | html_filters.push FILTERS | ||
| 31 | |||
| 32 | options[:container] = '.document' | ||
| 33 | end | ||
| 34 | |||
| 26 | version '9' do | 35 | version '9' do |
| 27 | self.release = '9.5' | 36 | self.release = '9.5' |
| 28 | self.base_url = "https://phpunit.readthedocs.io/en/#{release}/" | 37 | self.base_url = "https://phpunit.readthedocs.io/en/#{release}/" |
| @@ -77,8 +86,8 @@ module Docs · 48 unmodified lines | |||
| 77 | 86 | ||
| 78 | def get_latest_version(opts) | 87 | def get_latest_version(opts) |
| 79 | doc = fetch_doc('https://phpunit.readthedocs.io/', opts) | 88 | doc = fetch_doc('https://phpunit.readthedocs.io/', opts) |
| 80 | label = doc.at_css('.rst-current-version').content.strip | 89 | label = doc.at_css('meta[name="readthedocs-version-slug"]')["content"] |
| 81 | label.scan(/v: ([0-9.]+)/)[0][0] | 90 | label |
| 82 | end | 91 | end |
| 83 | 92 | ||
| 84 | end | 93 | end |
| @@ -1,14 +1,9 @@ | |||
| 1 | module Docs | 1 | module Docs |
| 2 | class Minitest < Rdoc | 2 | class Minitest < Rdoc |
| 3 | # Instructions: | ||
| 4 | # 1. Run "gem update rdoc hoe" | ||
| 5 | # 2. Download the source code at https://github.com/seattlerb/minitest | ||
| 6 | # 3. Run "rake docs" (in the Minitest directory) | ||
| 7 | # 4. Copy the "docs" directory to "docs/minitest" | ||
| 8 | 3 | ||
| 9 | self.name = 'Ruby / Minitest' | 4 | self.name = 'Ruby / Minitest' |
| 10 | self.slug = 'minitest' | 5 | self.slug = 'minitest' |
| 11 | self.release = '5.20.0' | 6 | self.release = '5.25.4' |
| 12 | self.links = { | 7 | self.links = { |
| 13 | code: 'https://github.com/minitest/minitest' | 8 | code: 'https://github.com/minitest/minitest' |
| 14 | } | 9 | } |
| @@ -75,6 +75,10 @@ module Docs · 74 unmodified lines | |||
| 75 | end | 75 | end |
| 76 | end | 76 | end |
| 77 | 77 | ||
| 78 | version '8.0' do | ||
| 79 | self.release = '8.0.1' | ||
| 80 | end | ||
| 81 | |||
| 78 | version '7.2' do | 82 | version '7.2' do |
| 79 | self.release = '7.2.1' | 83 | self.release = '7.2.1' |
| 80 | end | 84 | end |
| @@ -63,12 +63,16 @@ module Docs · 62 unmodified lines | |||
| 63 | /\AXMP/] | 63 | /\AXMP/] |
| 64 | 64 | ||
| 65 | options[:attribution] = <<-HTML | 65 | options[:attribution] = <<-HTML |
| 66 | Ruby Core © 1993–2022 Yukihiro Matsumoto<br> | 66 | Ruby Core © 1993–2024 Yukihiro Matsumoto<br> |
| 67 | Licensed under the Ruby License.<br> | 67 | Licensed under the Ruby License.<br> |
| 68 | Ruby Standard Library © contributors<br> | 68 | Ruby Standard Library © contributors<br> |
| 69 | Licensed under their own licenses. | 69 | Licensed under their own licenses. |
| 70 | HTML | 70 | HTML |
| 71 | 71 | ||
| 72 | version '3.4' do | ||
| 73 | self.release = '3.4.1' | ||
| 74 | end | ||
| 75 | |||
| 72 | version '3.3' do | 76 | version '3.3' do |
| 73 | self.release = '3.3.0' | 77 | self.release = '3.3.0' |
| 74 | end | 78 | end |
| @@ -22,8 +22,7 @@ module Docs · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | def get_latest_version(opts) | 23 | def get_latest_version(opts) |
| 24 | body = fetch('http://download.redis.io/redis-stable/00-RELEASENOTES', opts) | 24 | body = fetch('http://download.redis.io/redis-stable/00-RELEASENOTES', opts) |
| 25 | body = body.lines[1..-1].join | 25 | body.scan(/Redis Community Edition ([0-9.]+)/)[0][0] |
| 26 | body.scan(/Redis ([0-9.]+)/)[0][0] | ||
| 27 | end | 26 | end |
| 28 | 27 | ||
| 29 | private | 28 | private |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | |||
| 3 | module Docs | 3 | module Docs |
| 4 | class Rust < UrlScraper | 4 | class Rust < UrlScraper |
| 5 | self.type = 'rust' | 5 | self.type = 'rust' |
| 6 | self.release = '1.83.0' | 6 | self.release = '1.84.1' |
| 7 | self.base_url = 'https://doc.rust-lang.org/' | 7 | self.base_url = 'https://doc.rust-lang.org/' |
| 8 | self.root_path = 'book/index.html' | 8 | self.root_path = 'book/index.html' |
| 9 | self.initial_paths = %w( | 9 | self.initial_paths = %w( |
| @@ -1,7 +1,7 @@ | |||
| 1 | module Docs | 1 | module Docs |
| 2 | class Sass < UrlScraper | 2 | class Sass < UrlScraper |
| 3 | self.type = 'yard' | 3 | self.type = 'yard' |
| 4 | self.release = '1.82.9' | 4 | self.release = '1.85.0' |
| 5 | self.base_url = 'https://sass-lang.com/documentation' | 5 | self.base_url = 'https://sass-lang.com/documentation' |
| 6 | self.root_path = 'index.html' | 6 | self.root_path = 'index.html' |
| 7 | self.links = { | 7 | self.links = { |
| @@ -17,16 +17,16 @@ module Docs · 9 unmodified lines | |||
| 17 | options[:trailing_slash] = false | 17 | options[:trailing_slash] = false |
| 18 | 18 | ||
| 19 | options[:attribution] = <<-HTML | 19 | options[:attribution] = <<-HTML |
| 20 | © 2006–2024 the Sass team, and numerous contributors<br> | 20 | © 2006–2025 the Sass team, and numerous contributors<br> |
| 21 | Licensed under the MIT License. | 21 | Licensed under the MIT License. |
| 22 | HTML | 22 | HTML |
| 23 | |||
| 24 | private | ||
| 25 | 23 | ||
| 26 | def get_latest_version(opts) | 24 | def get_latest_version(opts) |
| 27 | get_npm_version('sass', opts) | 25 | get_npm_version('sass', opts) |
| 28 | end | 26 | end |
| 29 | 27 | ||
| 28 | private | ||
| 29 | |||
| 30 | def parse(response) | 30 | def parse(response) |
| 31 | response.body.gsub! '<span class="widont"> </span>', ' ' | 31 | response.body.gsub! '<span class="widont"> </span>', ' ' |
| 32 | end | 32 | end |
| @@ -3,8 +3,10 @@ module Docs · 2 unmodified lines | |||
| 3 | self.name = 'scikit-image' | 3 | self.name = 'scikit-image' |
| 4 | self.slug = 'scikit_image' | 4 | self.slug = 'scikit_image' |
| 5 | self.type = 'sphinx' | 5 | self.type = 'sphinx' |
| 6 | self.release = '0.18.1' | 6 | self.release = '0.25.0' |
| 7 | self.base_url = 'https://scikit-image.org/docs/0.18.x/' | 7 | v = self.release[/\d+\.\d+/] |
| 8 | self.base_url = "https://scikit-image.org/docs/#{v}.x/" | ||
| 9 | self.initial_paths = %w(/ /api/ /user_guide/) | ||
| 8 | self.links = { | 10 | self.links = { |
| 9 | home: 'https://scikit-image.org/', | 11 | home: 'https://scikit-image.org/', |
| 10 | code: 'https://github.com/scikit-image/scikit-image' | 12 | code: 'https://github.com/scikit-image/scikit-image' |
| @@ -12,7 +14,7 @@ module Docs · 1 unmodified line | |||
| 12 | 14 | ||
| 13 | html_filters.push 'scikit_image/entries', 'sphinx/clean_html' | 15 | html_filters.push 'scikit_image/entries', 'sphinx/clean_html' |
| 14 | 16 | ||
| 15 | options[:container] = '.span9' | 17 | options[:container] = 'main article' |
| 16 | options[:skip] = %w(api_changes.html) | 18 | options[:skip] = %w(api_changes.html) |
| 17 | options[:only_patterns] = [/\Aapi/, /\Auser_guide/] | 19 | options[:only_patterns] = [/\Aapi/, /\Auser_guide/] |
| 18 | 20 | ||
| @@ -3,8 +3,9 @@ module Docs · 2 unmodified lines | |||
| 3 | self.name = 'scikit-learn' | 3 | self.name = 'scikit-learn' |
| 4 | self.slug = 'scikit_learn' | 4 | self.slug = 'scikit_learn' |
| 5 | self.type = 'sphinx' | 5 | self.type = 'sphinx' |
| 6 | self.release = '1.1.3' | 6 | self.release = '1.6.1' |
| 7 | self.base_url = "https://scikit-learn.org/1.1/" | 7 | v = self.release[/\d+\.\d+/] |
| 8 | self.base_url = "https://scikit-learn.org/#{v}/" | ||
| 8 | self.root_path = 'index.html' | 9 | self.root_path = 'index.html' |
| 9 | self.force_gzip = true | 10 | self.force_gzip = true |
| 10 | self.links = { | 11 | self.links = { |
| @@ -14,7 +15,6 @@ module Docs · 3 unmodified lines | |||
| 14 | 15 | ||
| 15 | html_filters.push 'scikit_learn/entries', 'scikit_learn/clean_html', 'sphinx/clean_html', 'title' | 16 | html_filters.push 'scikit_learn/entries', 'scikit_learn/clean_html', 'sphinx/clean_html', 'title' |
| 16 | 17 | ||
| 17 | options[:container] = ->(filter) { filter.root_page? ? 'body > .container' : '#sk-page-content-wrapper > .body' } | ||
| 18 | options[:skip] = %w(modules/generated/sklearn.experimental.enable_iterative_imputer.html | 18 | options[:skip] = %w(modules/generated/sklearn.experimental.enable_iterative_imputer.html |
| 19 | modules/generated/sklearn.experimental.enable_hist_gradient_boosting.html) | 19 | modules/generated/sklearn.experimental.enable_hist_gradient_boosting.html) |
| 20 | options[:only_patterns] = [/\Amodules/, /\Adatasets/, /\Atutorial/, /\Aauto_examples/] | 20 | options[:only_patterns] = [/\Amodules/, /\Adatasets/, /\Atutorial/, /\Aauto_examples/] |
| @@ -24,7 +24,7 @@ module Docs · 3 unmodified lines | |||
| 24 | options[:max_image_size] = 256_000 | 24 | options[:max_image_size] = 256_000 |
| 25 | 25 | ||
| 26 | options[:attribution] = <<-HTML | 26 | options[:attribution] = <<-HTML |
| 27 | © 2007–2022 The scikit-learn developers<br> | 27 | © 2007–2025 The scikit-learn developers<br> |
| 28 | Licensed under the 3-clause BSD License. | 28 | Licensed under the 3-clause BSD License. |
| 29 | HTML | 29 | HTML |
| 30 | 30 | ||
| @@ -19,6 +19,11 @@ module Docs · 18 unmodified lines | |||
| 19 | Code samples licensed under the Apache 2.0 License. | 19 | Code samples licensed under the Apache 2.0 License. |
| 20 | HTML | 20 | HTML |
| 21 | 21 | ||
| 22 | version do | ||
| 23 | self.release = "2.18.0" | ||
| 24 | self.base_url = "https://www.tensorflow.org/api_docs/python/tf" | ||
| 25 | end | ||
| 26 | |||
| 22 | version '2.9' do | 27 | version '2.9' do |
| 23 | self.release = "2.9.1" | 28 | self.release = "2.9.1" |
| 24 | self.base_url = "https://www.tensorflow.org/versions/r#{version}/api_docs/python/tf" | 29 | self.base_url = "https://www.tensorflow.org/versions/r#{version}/api_docs/python/tf" |
| @@ -3,6 +3,11 @@ module Docs · 2 unmodified lines | |||
| 3 | self.name = 'TensorFlow C++' | 3 | self.name = 'TensorFlow C++' |
| 4 | self.slug = 'tensorflow_cpp' | 4 | self.slug = 'tensorflow_cpp' |
| 5 | 5 | ||
| 6 | version do | ||
| 7 | self.release = "2.18.0" | ||
| 8 | self.base_url = "https://www.tensorflow.org/api_docs/cc" | ||
| 9 | end | ||
| 10 | |||
| 6 | version '2.9' do | 11 | version '2.9' do |
| 7 | self.release = "2.9.1" | 12 | self.release = "2.9.1" |
| 8 | self.base_url = "https://www.tensorflow.org/versions/r#{version}/api_docs/cc" | 13 | self.base_url = "https://www.tensorflow.org/versions/r#{version}/api_docs/cc" |
| @@ -1,7 +1,7 @@ | |||
| 1 | module Docs | 1 | module Docs |
| 2 | class Trio < UrlScraper | 2 | class Trio < UrlScraper |
| 3 | self.type = 'simple' | 3 | self.type = 'simple' |
| 4 | self.release = '0.22.2' | 4 | self.release = '0.29.0' |
| 5 | self.base_url = "https://trio.readthedocs.io/en/v#{self.release}/" | 5 | self.base_url = "https://trio.readthedocs.io/en/v#{self.release}/" |
| 6 | self.root_path = 'index.html' | 6 | self.root_path = 'index.html' |
| 7 | self.links = { | 7 | self.links = { |
| @@ -25,7 +25,7 @@ module Docs · 17 unmodified lines | |||
| 25 | 25 | ||
| 26 | def get_latest_version(opts) | 26 | def get_latest_version(opts) |
| 27 | doc = fetch_doc('https://trio.readthedocs.io/en/stable/', opts) | 27 | doc = fetch_doc('https://trio.readthedocs.io/en/stable/', opts) |
| 28 | doc.at_css('.rst-other-versions a[href^="/en/v"]').content[1..-1] | 28 | doc.at_css('div.trio-version').content[0..-1] |
| 29 | end | 29 | end |
| 30 | end | 30 | end |
| 31 | end | 31 | end |
| @@ -22,7 +22,7 @@ module Docs · 21 unmodified lines | |||
| 22 | html_filters.push 'vite/entries', 'vite/clean_html' | 22 | html_filters.push 'vite/entries', 'vite/clean_html' |
| 23 | 23 | ||
| 24 | version do | 24 | version do |
| 25 | self.release = '6.0.1' | 25 | self.release = '6.1.0' |
| 26 | self.base_url = 'https://vite.dev/' | 26 | self.base_url = 'https://vite.dev/' |
| 27 | end | 27 | end |
| 28 | 28 | ||
| @@ -22,7 +22,7 @@ module Docs · 21 unmodified lines | |||
| 22 | Licensed under the MIT License. | 22 | Licensed under the MIT License. |
| 23 | HTML | 23 | HTML |
| 24 | 24 | ||
| 25 | self.release = '12.0.0' | 25 | self.release = '12.5.0' |
| 26 | self.base_url = 'https://vueuse.org/' | 26 | self.base_url = 'https://vueuse.org/' |
| 27 | self.initial_paths = %w(functions.html) | 27 | self.initial_paths = %w(functions.html) |
| 28 | html_filters.push 'vueuse/entries', 'vite/clean_html', 'vueuse/clean_html' | 28 | html_filters.push 'vueuse/entries', 'vite/clean_html', 'vueuse/clean_html' |
| @@ -17,6 +17,11 @@ module Docs · 16 unmodified lines | |||
| 17 | Licensed under the BSD 3-clause License. | 17 | Licensed under the BSD 3-clause License. |
| 18 | HTML | 18 | HTML |
| 19 | 19 | ||
| 20 | version do | ||
| 21 | self.release = '3.1.1' | ||
| 22 | self.base_url = "https://werkzeug.palletsprojects.com/en/latest/" | ||
| 23 | end | ||
| 24 | |||
| 20 | version '3.0' do | 25 | version '3.0' do |
| 21 | self.release = '3.0.x' | 26 | self.release = '3.0.x' |
| 22 | self.base_url = "https://werkzeug.palletsprojects.com/en/#{self.release}/" | 27 | self.base_url = "https://werkzeug.palletsprojects.com/en/#{self.release}/" |
| @@ -239,7 +239,7 @@ class DocsCLI < Thor · 238 unmodified lines | |||
| 239 | ['index.json', 'meta.json'].each do |filename| | 239 | ['index.json', 'meta.json'].each do |filename| |
| 240 | json = "https://documents.devdocs.io/#{doc.path}/#{filename}?#{time}" | 240 | json = "https://documents.devdocs.io/#{doc.path}/#{filename}?#{time}" |
| 241 | begin | 241 | begin |
| 242 | URI.open(json) do |file| | 242 | URI.open(json, "Accept-Encoding" => "identity") do |file| |
| 243 | mutex.synchronize do | 243 | mutex.synchronize do |
| 244 | path = File.join(dir, filename) | 244 | path = File.join(dir, filename) |
| 245 | File.write(path, file.read) | 245 | File.write(path, file.read) |
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,2 @@ | |||
| 1 | https://github.com/openlayers | ||
| 2 | https://avatars.githubusercontent.com/u/240579?s=64 | ||
| @@ -64,7 +64,7 @@ class ManifestTest < Minitest::Spec · 63 unmodified lines | |||
| 64 | it "includes the doc's meta representation" do | 64 | it "includes the doc's meta representation" do |
| 65 | json = manifest.as_json | 65 | json = manifest.as_json |
| 66 | assert_equal 1, json.length | 66 | assert_equal 1, json.length |
| 67 | assert_equal "{\"name\"=>\"Test\", \"db_size\"=>776533, :attribution=>\"foo\", :alias=>nil}", json[0].to_s | 67 | assert_equal "{\"name\" => \"Test\", \"db_size\" => 776533, attribution: \"foo\", alias: nil}", json[0].to_s |
| 68 | end | 68 | end |
| 69 | end | 69 | end |
| 70 | 70 | ||