History

Merge branch 'main' into add/threejs-docs

Simon Legner committed 1 year ago

Commit 74aa6612 parents 35b7c73 8f29e6070 files · +280 −117Browse files

Unified · Split

70 files
  1. .github/workflows/build.yml +2 −2
  2. .github/workflows/schedule-doc-report.yml +1 −1
  3. .github/workflows/test.yml +1 −1
  4. .ruby-version +1 −1
  5. .tool-versions +1 −1
  6. COPYRIGHT +1 −1
  7. Dockerfile +1 −1
  8. Dockerfile-alpine +1 −1
  9. Gemfile +1 −1
  10. Gemfile.lock +10 −6
  11. README.md +4 −4
  12. assets/javascripts/lib/license.js +1 −1
  13. assets/javascripts/lib/util.js +2 −20
  14. assets/javascripts/news.json +4 −0
  15. assets/javascripts/templates/pages/about_tmpl.js +1 −1
  16. assets/javascripts/views/content/entry_page.js +12 −20
  17. assets/stylesheets/application.css.scss +2 −1
  18. assets/stylesheets/pages/_mdn.scss +3 −0
  19. assets/stylesheets/pages/_openlayers.scss +10 −0
  20. docs/file-scrapers.md +11 −0
  21. lib/docs/filters/bazel/clean_html.rb +2 −0
  22. lib/docs/filters/core/normalize_urls.rb +1 −1
  23. lib/docs/filters/crystal/entries.rb +5 −1
  24. lib/docs/filters/elixir/clean_html.rb +3 −1
  25. lib/docs/filters/express/clean_html.rb +1 −1
  26. lib/docs/filters/openlayers/clean_html.rb +18 −0
  27. lib/docs/filters/openlayers/entries.rb +23 −0
  28. lib/docs/filters/phpunit/clean_html.rb +1 −1
  29. lib/docs/filters/rdoc/container.rb +5 −2
  30. lib/docs/filters/scala/entries_v2.rb +1 −1
  31. lib/docs/filters/scikit_image/entries.rb +2 −1
  32. lib/docs/filters/scikit_learn/clean_html.rb +1 −0
  33. lib/docs/filters/tensorflow/clean_html.rb +3 −0
  34. lib/docs/filters/vueuse/entries.rb +16 −0
  35. lib/docs/scrapers/bazel.rb +5 −0
  36. lib/docs/scrapers/crystal.rb +3 −2
  37. lib/docs/scrapers/docker.rb +1 −1
  38. lib/docs/scrapers/elixir.rb +12 −0
  39. lib/docs/scrapers/express.rb +1 −1
  40. lib/docs/scrapers/fastapi.rb +1 −1
  41. lib/docs/scrapers/flask.rb +5 −0
  42. lib/docs/scrapers/git.rb +1 −1
  43. lib/docs/scrapers/go.rb +11 −2
  44. lib/docs/scrapers/haskell.rb +1 −1
  45. lib/docs/scrapers/jquery/jquery_ui.rb +1 −1
  46. lib/docs/scrapers/mdn/dom.rb +1 −1
  47. lib/docs/scrapers/mdn/javascript.rb +1 −1
  48. lib/docs/scrapers/meteor.rb +1 −2
  49. lib/docs/scrapers/nix.rb +1 −3
  50. lib/docs/scrapers/openlayers.rb +24 −0
  51. lib/docs/scrapers/phpunit.rb +12 −3
  52. lib/docs/scrapers/rdoc/minitest.rb +1 −6
  53. lib/docs/scrapers/rdoc/rails.rb +4 −0
  54. lib/docs/scrapers/rdoc/ruby.rb +5 −1
  55. lib/docs/scrapers/redis.rb +1 −2
  56. lib/docs/scrapers/rust.rb +1 −1
  57. lib/docs/scrapers/sass.rb +4 −4
  58. lib/docs/scrapers/scikit_image.rb +5 −3
  59. lib/docs/scrapers/scikit_learn.rb +4 −4
  60. lib/docs/scrapers/tensorflow/tensorflow.rb +5 −0
  61. lib/docs/scrapers/tensorflow/tensorflow_cpp.rb +5 −0
  62. lib/docs/scrapers/trio.rb +2 −2
  63. lib/docs/scrapers/vite.rb +1 −1
  64. lib/docs/scrapers/vueuse.rb +1 −1
  65. lib/docs/scrapers/werkzeug.rb +5 −0
  66. lib/tasks/docs.thor +1 −1
  67. public/icons/docs/openlayers/16.png +0 −0
  68. public/icons/docs/openlayers/16@2x.png +0 −0
  69. public/icons/docs/openlayers/SOURCE +2 −0
  70. test/lib/docs/core/manifest_test.rb +1 −1
.github/workflows/build.yml+2−2
@@ -13,13 +13,13 @@ jobs: · 12 unmodified lines
13 steps:13 steps:
14 - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.014 - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
15 - name: Set up Ruby15 - name: Set up Ruby
16 uses: ruby/setup-ruby@540484a3c0f308b08619664ec40bf6c371d172c3 # v1.205.016 uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0
17 with:17 with:
18 bundler-cache: true # runs 'bundle install' and caches installed gems automatically18 bundler-cache: true # runs 'bundle install' and caches installed gems automatically
19 - name: Run tests19 - name: Run tests
20 run: bundle exec rake20 run: bundle exec rake
21 - name: Deploy to Heroku21 - name: Deploy to Heroku
22 uses: akhileshns/heroku-deploy@581dd286c962b6972d427fcf8980f60755c15520 # v3.13.1522 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"
.github/workflows/schedule-doc-report.yml+1−1
@@ -11,7 +11,7 @@ jobs: · 10 unmodified lines
11 steps:11 steps:
12 - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.012 - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
13 - name: Set up Ruby13 - name: Set up Ruby
14 uses: ruby/setup-ruby@540484a3c0f308b08619664ec40bf6c371d172c3 # v1.205.014 uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0
15 with:15 with:
16 bundler-cache: true # runs 'bundle install' and caches installed gems automatically16 bundler-cache: true # runs 'bundle install' and caches installed gems automatically
17 - name: Generate report17 - name: Generate report
.github/workflows/test.yml+1−1
@@ -11,7 +11,7 @@ jobs: · 10 unmodified lines
11 steps:11 steps:
12 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.212 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
13 - name: Set up Ruby13 - name: Set up Ruby
14 uses: ruby/setup-ruby@540484a3c0f308b08619664ec40bf6c371d172c3 # v1.205.014 uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0
15 with:15 with:
16 bundler-cache: true # runs 'bundle install' and caches installed gems automatically16 bundler-cache: true # runs 'bundle install' and caches installed gems automatically
17 - name: Run tests17 - name: Run tests
.ruby-version+1−1
@@ -1 +1 @@
13.3.613.4.2
.tool-versions+1−1
@@ -1 +1 @@
1ruby 3.3.61ruby 3.4.2
COPYRIGHT+1−1
@@ -1,4 +1,4 @@
1Copyright 2013-2024 Thibaut Courouble and other contributors1Copyright 2013-2025 Thibaut Courouble and other contributors
2 2
3 This Source Code Form is subject to the terms of the Mozilla Public3 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 this4 License, v. 2.0. If a copy of the MPL was not distributed with this
Dockerfile+1−1
@@ -1,4 +1,4 @@
1FROM ruby:3.3.61FROM ruby:3.4.2
2ENV LANG=C.UTF-82ENV LANG=C.UTF-8
3ENV ENABLE_SERVICE_WORKER=true3ENV ENABLE_SERVICE_WORKER=true
4 4
Dockerfile-alpine+1−1
@@ -1,4 +1,4 @@
1FROM ruby:3.3.6-alpine1FROM ruby:3.4.2-alpine
2 2
3ENV LANG=C.UTF-83ENV LANG=C.UTF-8
4ENV ENABLE_SERVICE_WORKER=true4ENV ENABLE_SERVICE_WORKER=true
Gemfile+1−1
@@ -1,5 +1,5 @@
1source 'https://rubygems.org'1source 'https://rubygems.org'
2ruby '3.3.6'2ruby '3.4.2'
3 3
4gem 'activesupport', require: false4gem 'activesupport', require: false
5gem 'html-pipeline'5gem 'html-pipeline'
Gemfile.lock+10−6
@@ -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-ruby191 yajl-ruby
188 192
189RUBY VERSION193RUBY VERSION
190 ruby 3.3.6p108194 ruby 3.4.2p28
191 195
192BUNDLED WITH196BUNDLED WITH
193 2.4.6197 2.4.6
README.md+4−4
@@ -25,12 +25,12 @@ Unless you wish to contribute to the project, we recommend using the hosted vers · 24 unmodified lines
25The easiest way to run DevDocs locally is using Docker:25The easiest way to run DevDocs locally is using Docker:
26 26
27```sh27```sh
28docker run --name devdocs -d -p 9292:9292 ghcr.io/freecodcamp/devdocs:latest28docker run --name devdocs -d -p 9292:9292 ghcr.io/freecodecamp/devdocs:latest
29```29```
30 30
31This will start DevDocs at [localhost:9292](http://localhost:9292). We provide both regular and Alpine-based images:31This will start DevDocs at [localhost:9292](http://localhost:9292). We provide both regular and Alpine-based images:
32- `ghcr.io/freecodcamp/devdocs:latest` - Standard image32- `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
35Images are automatically built and updated monthly with the latest documentation.35Images 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 / License196## Copyright / License
197 197
198Copyright 2013–2024 Thibaut Courouble and [other contributors](https://github.com/freeCodeCamp/devdocs/graphs/contributors)198Copyright 2013–2025 Thibaut Courouble and [other contributors](https://github.com/freeCodeCamp/devdocs/graphs/contributors)
199 199
200This software is licensed under the terms of the Mozilla Public License v2.0. See the [COPYRIGHT](./COPYRIGHT) and [LICENSE](./LICENSE) files.200This software is licensed under the terms of the Mozilla Public License v2.0. See the [COPYRIGHT](./COPYRIGHT) and [LICENSE](./LICENSE) files.
201 201
assets/javascripts/lib/license.js+1−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2013-2024 Thibaut Courouble and other contributors2 * Copyright 2013-2025 Thibaut Courouble and other contributors
3 *3 *
4 * This source code is licensed under the terms of the Mozilla4 * 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:
assets/javascripts/lib/util.js+2−20
@@ -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};
assets/javascripts/news.json+4−0
@@ -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>"
assets/javascripts/templates/pages/about_tmpl.js+1−1
@@ -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&ndash;2024 Thibaut Courouble and <a href="https://github.com/freeCodeCamp/devdocs/graphs/contributors">other contributors</a></strong><br>35 <strong>Copyright 2013&ndash;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>
assets/javascripts/views/content/entry_page.js+12−20
@@ -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));
assets/stylesheets/application.css.scss+2−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
3//= depend_on sprites/docs.json3//= depend_on sprites/docs.json
4 4
5/*!5/*!
6 * Copyright 2013-2024 Thibaut Courouble and other contributors6 * Copyright 2013-2025 Thibaut Courouble and other contributors
7 *7 *
8 * This source code is licensed under the terms of the Mozilla8 * 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',
assets/stylesheets/pages/_mdn.scss+3−0
@@ -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 202135 .notecard, // MDN 2021
33 .notice,36 .notice,
assets/stylesheets/pages/_openlayers.scss+10−0
@@ -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}
docs/file-scrapers.md+11−0
@@ -254,6 +254,17 @@ done · 253 unmodified lines
254 254
255### Nokogiri255### Nokogiri
256### Ruby / Minitest256### Ruby / Minitest
257
258```sh
259git clone https://github.com/seattlerb/minitest
260cd minitest/
261bundle install
262bundle add rdoc hoe
263bundle exec rak docs
264cd ..
265cp -r minitest/docs $DEVDOCS/docs/minitest
266```
267
257### Ruby on Rails268### 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`)
lib/docs/filters/bazel/clean_html.rb+2−0
@@ -7,8 +7,10 @@ module Docs · 6 unmodified lines
7 css('devsite-feature-tooltip').remove7 css('devsite-feature-tooltip').remove
8 css('devsite-thumb-rating').remove8 css('devsite-thumb-rating').remove
9 css('devsite-toc').remove9 css('devsite-toc').remove
10 css('devsite-feedback').remove
10 css('a.button-with-icon').remove11 css('a.button-with-icon').remove
11 css('button.devsite-heading-link').remove12 css('button.devsite-heading-link').remove
13 css('.devsite-article-body > span:first-child[style="float: right; line-height: 36px"]').remove
12 doc14 doc
13 end15 end
14 16
lib/docs/filters/core/normalize_urls.rb+1−1
@@ -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.downcase45 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]
lib/docs/filters/crystal/entries.rb+5−1
@@ -16,8 +16,12 @@ module Docs · 15 unmodified lines
16 name16 name
17 else17 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.strip19 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 name25 name
22 end26 end
23 end27 end
lib/docs/filters/elixir/clean_html.rb+3−1
@@ -34,7 +34,9 @@ module Docs · 33 unmodified lines
34 node.name = 'h3'34 node.name = 'h3'
35 node['id'] = id35 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_text41 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>)
lib/docs/filters/express/clean_html.rb+1−1
@@ -3,7 +3,7 @@ module Docs · 2 unmodified lines
3 class CleanHtmlFilter < Filter3 class CleanHtmlFilter < Filter
4 def call4 def call
5 i = 15 i = 1
6 n = at_css("#navmenu a[href='#{result[:path].split('/').last}']").parent6 n = at_css("#navmenu .submenu-content a[href='#{result[:path].split('/').last}']").parent
7 i += 1 while n && n = n.previous_element7 i += 1 while n && n = n.previous_element
8 at_css('h1')['data-level'] = i8 at_css('h1')['data-level'] = i
9 9
lib/docs/filters/openlayers/clean_html.rb+18−0
@@ -0,0 +1,18 @@
1module 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
18end
lib/docs/filters/openlayers/entries.rb+23−0
@@ -0,0 +1,23 @@
1module 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
23end
lib/docs/filters/phpunit/clean_html.rb+1−1
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
2 class Phpunit2 class Phpunit
3 class CleanHtmlFilter < Filter3 class CleanHtmlFilter < Filter
4 def call4 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'
lib/docs/filters/rdoc/container.rb+5−2
@@ -13,8 +13,11 @@ module Docs · 12 unmodified lines
13 meta = Nokogiri::XML::Node.new 'dl', doc.document13 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 end21 end
19 22
20 if includes = at_css('#includes-section')23 if includes = at_css('#includes-section')
lib/docs/filters/scala/entries_v2.rb+1−1
@@ -71,7 +71,7 @@ module Docs · 70 unmodified lines
71 # name from the HTML because companion object classes may be broken out into71 # 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 would74 # 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_name76 def package_name
77 name = package_drop_last(slug_parts)77 name = package_drop_last(slug_parts)
lib/docs/filters/scikit_image/entries.rb+2−1
@@ -3,7 +3,8 @@ module Docs · 2 unmodified lines
3 class EntriesFilter < Docs::EntriesFilter3 class EntriesFilter < Docs::EntriesFilter
4 def get_name4 def get_name
5 name = at_css('h1').content.strip5 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: '
lib/docs/filters/scikit_learn/clean_html.rb+1−0
@@ -2,6 +2,7 @@ module Docs · 1 unmodified line
2 class ScikitLearn2 class ScikitLearn
3 class CleanHtmlFilter < Filter3 class CleanHtmlFilter < Filter
4 def call4 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>'
lib/docs/filters/tensorflow/clean_html.rb+3−0
@@ -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 end47 end
48 48
49 css('span[slot="popout-heading"]').remove
50 css('span[slot="popout-contents"]').remove
51
49 doc52 doc
50 end53 end
51 end54 end
lib/docs/filters/vueuse/entries.rb+16−0
@@ -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/"
lib/docs/scrapers/bazel.rb+5−0
@@ -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 HTML13 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' do20 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/'
lib/docs/scrapers/crystal.rb+3−2
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
2 class Crystal < UrlScraper2 class Crystal < UrlScraper
3 include MultipleBaseUrls3 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 HTML35 HTML
35 else36 else
36 <<-HTML37 <<-HTML
37 &copy; 2012&ndash;2024 Manas Technology Solutions.<br>38 &copy; 2012&ndash;2025 Manas Technology Solutions.<br>
38 Licensed under the Apache License, Version 2.0.39 Licensed under the Apache License, Version 2.0.
39 HTML40 HTML
40 end41 end
lib/docs/scrapers/docker.rb+1−1
@@ -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.strip99 latest_version = doc.at_css('h2.scroll-mt-20 > a').content.strip
100 latest_version.rpartition(' ')[-1]100 latest_version.rpartition(' ')[-1]
101 end101 end
102 end102 end
lib/docs/scrapers/elixir.rb+12−0
@@ -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 end31 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' do45 version '1.17' do
34 self.release = '1.17.2'46 self.release = '1.17.2'
35 self.base_urls = [47 self.base_urls = [
lib/docs/scrapers/express.rb+1−1
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
2 class Express < UrlScraper2 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(
lib/docs/scrapers/fastapi.rb+1−1
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
2 class Fastapi < UrlScraper2 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 = {
lib/docs/scrapers/flask.rb+5−0
@@ -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 HTML19 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' do26 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}/"
lib/docs/scrapers/git.rb+1−1
@@ -1,7 +1,7 @@
1module Docs1module Docs
2 class Git < UrlScraper2 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 = {
lib/docs/scrapers/go.rb+11−2
@@ -1,7 +1,7 @@
1module Docs1module Docs
2 class Go < UrlScraper2 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.013 # podman run --net host --rm -it docker.io/golang:1.24.0
14 #podman# go install golang.org/x/tools/cmd/godoc@latest14 #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 -v16 #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'
lib/docs/scrapers/haskell.rb+1−1
@@ -59,7 +59,7 @@ module Docs · 58 unmodified lines
59 end59 end
60 60
61 version '9' do61 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 end65 end
lib/docs/scrapers/jquery/jquery_ui.rb+1−1
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
2 class JqueryUi < Jquery2 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
lib/docs/scrapers/mdn/dom.rb+1−1
@@ -1,6 +1,6 @@
1module Docs1module Docs
2 class Dom < Mdn2 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'
lib/docs/scrapers/mdn/javascript.rb+1−1
@@ -3,7 +3,7 @@ module Docs · 2 unmodified lines
3 prepend FixInternalUrlsBehavior3 prepend FixInternalUrlsBehavior
4 prepend FixRedirectionsBehavior4 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 = {
lib/docs/scrapers/meteor.rb+1−2
@@ -47,8 +47,7 @@ module Docs · 46 unmodified lines
47 end47 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 end51 end
53 end52 end
54end53end
lib/docs/scrapers/nix.rb+1−3
@@ -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 end27 end
30 end28 end
31end29end
lib/docs/scrapers/openlayers.rb+24−0
@@ -0,0 +1,24 @@
1module 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 &copy; 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
24end
lib/docs/scrapers/phpunit.rb+12−3
@@ -17,12 +17,21 @@ module Docs · 16 unmodified lines
17 options[:title] = false17 options[:title] = false
18 18
19 options[:attribution] = <<-HTML19 options[:attribution] = <<-HTML
20 &copy; 2005&ndash;2020 Sebastian Bergmann<br>20 &copy; 2005&ndash;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 HTML22 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' do35 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.strip89 label = doc.at_css('meta[name="readthedocs-version-slug"]')["content"]
81 label.scan(/v: ([0-9.]+)/)[0][0]90 label
82 end91 end
83 92
84 end93 end
lib/docs/scrapers/rdoc/minitest.rb+1−6
@@ -1,14 +1,9 @@
1module Docs1module Docs
2 class Minitest < Rdoc2 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 }
lib/docs/scrapers/rdoc/rails.rb+4−0
@@ -75,6 +75,10 @@ module Docs · 74 unmodified lines
75 end75 end
76 end76 end
77 77
78 version '8.0' do
79 self.release = '8.0.1'
80 end
81
78 version '7.2' do82 version '7.2' do
79 self.release = '7.2.1'83 self.release = '7.2.1'
80 end84 end
lib/docs/scrapers/rdoc/ruby.rb+5−1
@@ -63,12 +63,16 @@ module Docs · 62 unmodified lines
63 /\AXMP/]63 /\AXMP/]
64 64
65 options[:attribution] = <<-HTML65 options[:attribution] = <<-HTML
66 Ruby Core &copy; 1993&ndash;2022 Yukihiro Matsumoto<br>66 Ruby Core &copy; 1993&ndash;2024 Yukihiro Matsumoto<br>
67 Licensed under the Ruby License.<br>67 Licensed under the Ruby License.<br>
68 Ruby Standard Library &copy; contributors<br>68 Ruby Standard Library &copy; contributors<br>
69 Licensed under their own licenses.69 Licensed under their own licenses.
70 HTML70 HTML
71 71
72 version '3.4' do
73 self.release = '3.4.1'
74 end
75
72 version '3.3' do76 version '3.3' do
73 self.release = '3.3.0'77 self.release = '3.3.0'
74 end78 end
lib/docs/scrapers/redis.rb+1−2
@@ -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].join25 body.scan(/Redis Community Edition ([0-9.]+)/)[0][0]
26 body.scan(/Redis ([0-9.]+)/)[0][0]
27 end26 end
28 27
29 private28 private
lib/docs/scrapers/rust.rb+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
3module Docs3module Docs
4 class Rust < UrlScraper4 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(
lib/docs/scrapers/sass.rb+4−4
@@ -1,7 +1,7 @@
1module Docs1module Docs
2 class Sass < UrlScraper2 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] = false17 options[:trailing_slash] = false
18 18
19 options[:attribution] = <<-HTML19 options[:attribution] = <<-HTML
20 &copy; 2006&ndash;2024 the Sass team, and numerous contributors<br>20 &copy; 2006&ndash;2025 the Sass team, and numerous contributors<br>
21 Licensed under the MIT License.21 Licensed under the MIT License.
22 HTML22 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 end26 end
29 27
28 private
29
30 def parse(response)30 def parse(response)
31 response.body.gsub! '<span class="widont">&nbsp;</span>', '&nbsp;'31 response.body.gsub! '<span class="widont">&nbsp;</span>', '&nbsp;'
32 end32 end
lib/docs/scrapers/scikit_image.rb+5−3
@@ -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
lib/docs/scrapers/scikit_learn.rb+4−4
@@ -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 = true10 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.html18 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_00024 options[:max_image_size] = 256_000
25 25
26 options[:attribution] = <<-HTML26 options[:attribution] = <<-HTML
27 &copy; 2007&ndash;2022 The scikit-learn developers<br>27 &copy; 2007&ndash;2025 The scikit-learn developers<br>
28 Licensed under the 3-clause BSD License.28 Licensed under the 3-clause BSD License.
29 HTML29 HTML
30 30
lib/docs/scrapers/tensorflow/tensorflow.rb+5−0
@@ -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 HTML20 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' do27 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"
lib/docs/scrapers/tensorflow/tensorflow_cpp.rb+5−0
@@ -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' do11 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"
lib/docs/scrapers/trio.rb+2−2
@@ -1,7 +1,7 @@
1module Docs1module Docs
2 class Trio < UrlScraper2 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 end29 end
30 end30 end
31end31end
lib/docs/scrapers/vite.rb+1−1
@@ -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 do24 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 end27 end
28 28
lib/docs/scrapers/vueuse.rb+1−1
@@ -22,7 +22,7 @@ module Docs · 21 unmodified lines
22 Licensed under the MIT License.22 Licensed under the MIT License.
23 HTML23 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'
lib/docs/scrapers/werkzeug.rb+5−0
@@ -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 HTML18 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' do25 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}/"
lib/tasks/docs.thor+1−1
@@ -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 begin241 begin
242 URI.open(json) do |file|242 URI.open(json, "Accept-Encoding" => "identity") do |file|
243 mutex.synchronize do243 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)
public/icons/docs/openlayers/16.png+0−0

Binary file not shown.

public/icons/docs/openlayers/16@2x.png+0−0

Binary file not shown.

public/icons/docs/openlayers/SOURCE+2−0
@@ -0,0 +1,2 @@
1https://github.com/openlayers
2https://avatars.githubusercontent.com/u/240579?s=64
test/lib/docs/core/manifest_test.rb+1−1
@@ -64,7 +64,7 @@ class ManifestTest < Minitest::Spec · 63 unmodified lines
64 it "includes the doc's meta representation" do64 it "includes the doc's meta representation" do
65 json = manifest.as_json65 json = manifest.as_json
66 assert_equal 1, json.length66 assert_equal 1, json.length
67 assert_equal "{\"name\"=>\"Test\", \"db_size\"=>776533, :attribution=>\"foo\", :alias=>nil}", json[0].to_s67 assert_equal "{\"name\" => \"Test\", \"db_size\" => 776533, attribution: \"foo\", alias: nil}", json[0].to_s
68 end68 end
69 end69 end
70 70