diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 6feda1f8..3bb2512d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
- name: Set up Ruby
- uses: ruby/setup-ruby@d5fb7a202fc07872cb44f00ba8e6197b70cb0c55 # v1.179.0
+ uses: ruby/setup-ruby@ff740bc00a01b3a50fffc55a1071b1060eeae9dc # v1.180.0
with:
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Run tests
diff --git a/.github/workflows/schedule-doc-report.yml b/.github/workflows/schedule-doc-report.yml
index 154146ed..8c4ecb09 100644
--- a/.github/workflows/schedule-doc-report.yml
+++ b/.github/workflows/schedule-doc-report.yml
@@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
- name: Set up Ruby
- uses: ruby/setup-ruby@d5fb7a202fc07872cb44f00ba8e6197b70cb0c55 # v1.179.0
+ uses: ruby/setup-ruby@ff740bc00a01b3a50fffc55a1071b1060eeae9dc # v1.180.0
with:
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Generate report
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ef693b33..f5dd454b 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Set up Ruby
- uses: ruby/setup-ruby@d5fb7a202fc07872cb44f00ba8e6197b70cb0c55 # v1.179.0
+ uses: ruby/setup-ruby@ff740bc00a01b3a50fffc55a1071b1060eeae9dc # v1.180.0
with:
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Run tests
diff --git a/Gemfile.lock b/Gemfile.lock
index 93007c9d..43f62c70 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
- activesupport (7.1.3.3)
+ activesupport (7.1.3.4)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
@@ -125,7 +125,7 @@ GEM
strings-ansi (0.2.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
- terser (1.2.2)
+ terser (1.2.3)
execjs (>= 0.3.0, < 3)
thin (1.8.2)
daemons (~> 1.0, >= 1.0.9)
diff --git a/README.md b/README.md
index ea7d3720..a54f4992 100644
--- a/README.md
+++ b/README.md
@@ -172,6 +172,7 @@ Made something cool? Feel free to open a PR to add a new row to this table! You
| [mohamed3nan/DevDocs-Tab](https://github.com/mohamed3nan/DevDocs-Tab) | VS Code extension (view as tab) | ![Latest GitHub commit](https://img.shields.io/github/last-commit/mohamed3nan/DevDocs-Tab?logo=github&label) | ![GitHub stars](https://img.shields.io/github/stars/mohamed3nan/DevDocs-Tab?logo=github&label) |
| [deibit/vscode-devdocs](https://marketplace.visualstudio.com/items?itemName=deibit.devdocs) | VS Code extension (open the browser) | ![Latest GitHub commit](https://img.shields.io/github/last-commit/deibit/vscode-devdocs?logo=github&label) | ![GitHub stars](https://img.shields.io/github/stars/deibit/vscode-devdocs?logo=github&label) |
| [mdh34/quickDocs](https://github.com/mdh34/quickDocs) | Vala/Python based viewer | ![Latest GitHub commit](https://img.shields.io/github/last-commit/mdh34/quickDocs?logo=github&label) | ![GitHub stars](https://img.shields.io/github/stars/mdh34/quickDocs?logo=github&label) |
+| [girishji/devdocs.vim](https://github.com/girishji/devdocs.vim) | Vim plugin & TUI (browse inside Vim) | ![Latest GitHub commit](https://img.shields.io/github/last-commit/girishji/devdocs.vim?logo=github&label) | ![GitHub stars](https://img.shields.io/github/stars/girishji/devdocs.vim?logo=github&label) |
| [romainl/vim-devdocs](https://github.com/romainl/vim-devdocs) | Vim plugin | ![Latest GitHub commit](https://img.shields.io/github/last-commit/romainl/vim-devdocs?logo=github&label) | ![GitHub stars](https://img.shields.io/github/stars/romainl/vim-devdocs?logo=github&label) |
| [waiting-for-dev/vim-www](https://github.com/waiting-for-dev/vim-www) | Vim plugin | ![Latest GitHub commit](https://img.shields.io/github/last-commit/waiting-for-dev/vim-www?logo=github&label) | ![GitHub stars](https://img.shields.io/github/stars/waiting-for-dev/vim-www?logo=github&label) |
| [luckasRanarison/nvim-devdocs](https://github.com/luckasRanarison/nvim-devdocs) | Neovim plugin | ![Latest GitHub commit](https://img.shields.io/github/last-commit/luckasRanarison/nvim-devdocs?logo=github&label) | ![GitHub stars](https://img.shields.io/github/stars/luckasRanarison/nvim-devdocs?logo=github&label) |
diff --git a/assets/javascripts/news.json b/assets/javascripts/news.json
index 38dd4bc4..07dc5645 100644
--- a/assets/javascripts/news.json
+++ b/assets/javascripts/news.json
@@ -1,4 +1,8 @@
[
+ [
+ "2024-02-20",
+ "New documentations: Next.js, click"
+ ],
[
"2024-01-24",
"New documentation: Playwright"
diff --git a/lib/docs/filters/click/entries.rb b/lib/docs/filters/click/entries.rb
new file mode 100644
index 00000000..01fa1a72
--- /dev/null
+++ b/lib/docs/filters/click/entries.rb
@@ -0,0 +1,58 @@
+module Docs
+ class Click
+ class EntriesFilter < Docs::EntriesFilter
+ TYPE_BY_SLUG = {}
+
+ def call
+ if root_page?
+ css('section').each do |node|
+ next if ['documentation', 'api-reference'].include?(node['id'])
+ type = node.at_css('h2').content.strip
+ node.css('li > a').each do |toclink|
+ slug = toclink['href'].split('/')[-2]
+ TYPE_BY_SLUG[slug] = type
+ end
+ end
+ end
+ super
+ end
+
+ def get_name
+ return at_css('h1').content.strip
+ end
+
+ def get_type
+ TYPE_BY_SLUG[slug.split('/').first] || at_css('h1').content.strip
+ end
+
+ def include_default_entry?
+ TYPE_BY_SLUG.include?(slug.split('/').first)
+ end
+
+ def additional_entries
+ return [] if root_page? || TYPE_BY_SLUG.include?(slug.split('/').first)
+
+ if slug == 'api/'
+ entries = []
+ doc.css('> section').each do |section|
+ title = section.at_css('h2').content.strip
+ section.css('dl.py > dt[id]').each do |dt|
+ name = dt['id'].split('.')[1..].join('.')
+ name << '()' if dt.parent.classes.intersect?(['function', 'method', 'classmethod', 'staticmethod'])
+ entries << [name, dt['id'], title]
+ end
+ end
+ return entries
+ end
+
+ (doc.css('> section') || []).map do |section|
+ title = section.at_css('h2').content.strip
+ [title, section['id']]
+ end
+ end
+
+ private
+
+ end
+ end
+end
diff --git a/lib/docs/filters/click/pre_clean_html.rb b/lib/docs/filters/click/pre_clean_html.rb
new file mode 100644
index 00000000..e0552a6a
--- /dev/null
+++ b/lib/docs/filters/click/pre_clean_html.rb
@@ -0,0 +1,11 @@
+module Docs
+ class Click
+ class PreCleanHtmlFilter < Filter
+ def call
+ # Remove ΒΆ character from headers
+ css('.headerlink').remove
+ doc
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/elisp/entries.rb b/lib/docs/filters/elisp/entries.rb
index 9ccacb59..a699c7b0 100644
--- a/lib/docs/filters/elisp/entries.rb
+++ b/lib/docs/filters/elisp/entries.rb
@@ -2,7 +2,7 @@ module Docs
class Elisp
class EntriesFilter < Docs::EntriesFilter
def get_name
- # remove numbers at the beginnig
+ # remove numbers at the beginning
name = at_css('.chapter', '.section', '.subsection', '.subsubsection', '.appendix').content.slice(/[[:alpha:]]...*/)
# remove 'Appendix' word
diff --git a/lib/docs/filters/gtk/entries.rb b/lib/docs/filters/gtk/entries.rb
index 5cb3d27a..b51f1544 100644
--- a/lib/docs/filters/gtk/entries.rb
+++ b/lib/docs/filters/gtk/entries.rb
@@ -4,7 +4,7 @@ module Docs
# The GTK documentation paths are "flat" and while the contents of each
# page provides a way to determine the direct parent relationship, we
# really need a full hierarchy of pages *a priori* to be able to fully
- # categorize all pages and entries. So we're going to recursivly generate
+ # categorize all pages and entries. So we're going to recursively generate
# a full map of page -> parent relationships from the table of contents...
PARENT_BY_PATH = {}
diff --git a/lib/docs/filters/kubectl/entries.rb b/lib/docs/filters/kubectl/entries.rb
index 2a15d508..0d335c05 100644
--- a/lib/docs/filters/kubectl/entries.rb
+++ b/lib/docs/filters/kubectl/entries.rb
@@ -15,7 +15,7 @@ module Docs
group = 'kubectl'
commands = css('h1').to_a()
commands.map do |node|
- # handle titles differnetly by converting them into sidebar groups (types)
+ # handle titles differently by converting them into sidebar groups (types)
new_group = at_css("##{node['id']} > strong")
if new_group
group = new_group.content.titleize
diff --git a/lib/docs/filters/nextjs/clean_html.rb b/lib/docs/filters/nextjs/clean_html.rb
new file mode 100644
index 00000000..99523bdd
--- /dev/null
+++ b/lib/docs/filters/nextjs/clean_html.rb
@@ -0,0 +1,30 @@
+module Docs
+ class Nextjs
+ class CleanHtmlFilter < Filter
+ def call
+ @doc = at_css('.prose')
+
+ css('.zola-anchor').remove
+ doc.prepend_child("
NextJS2
") if root_page?
+ css('div:contains("NEWS:")').remove
+ css('h2:contains("sponsors"), #sponsor-table').remove
+ css('div.sticky').remove #remove the floating menu
+ css('div.-mt-4').remove #remove the navigation line
+ css('footer').remove
+ css('div.feedback_inlineTriggerWrapper__o7yUx').remove
+ css('header').remove #remove links from the top of the page
+ css('nav').remove
+
+ css('h1, h2, h3, h4').each { |node| node.content = node.content }
+
+ css('pre > code').each do |node|
+ node.parent['data-language'] = 'typescript'
+ node.parent.content = node.parent.content
+ end
+ css('div[class^="code-block_header"]').remove
+
+ doc
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/nextjs/entries.rb b/lib/docs/filters/nextjs/entries.rb
new file mode 100644
index 00000000..03c6bc09
--- /dev/null
+++ b/lib/docs/filters/nextjs/entries.rb
@@ -0,0 +1,43 @@
+module Docs
+ class Nextjs
+ class EntriesFilter < Docs::EntriesFilter
+ def get_name
+ name = at_css('h1').content
+ name.strip!
+ #name
+ subpath_items = subpath.split('/', -1)
+ if subpath_items.length >= 5
+ subpath_items[3].capitalize + ': ' + name # e.g. Routing: Defining Routes
+ else
+ name
+ end
+ end
+
+ def get_type
+ if slug.start_with?('architecture')
+ 'Architecture'
+ elsif slug.start_with?('community')
+ 'Community'
+ elsif slug.start_with?('getting-started')
+ 'Getting Started'
+ elsif slug.start_with?('messages')
+ 'Messages'
+ elsif slug.start_with?('app/building-your-application')
+ 'Using App Router: Building your application'
+ elsif slug.start_with?('app/api-reference')
+ 'Using App Router: api-reference'
+ elsif slug.start_with?('app')
+ 'Using App Router'
+ elsif slug.start_with?('pages/building-your-application')
+ 'Using Pages Router: Building your application'
+ elsif slug.start_with?('pages/api-reference')
+ 'Using Pages Router: api-reference'
+ elsif slug.start_with?('pages')
+ 'Using Pages Router'
+ else
+ get_name
+ end
+ end
+ end
+ end
+end
diff --git a/lib/docs/scrapers/click.rb b/lib/docs/scrapers/click.rb
new file mode 100644
index 00000000..71c2a423
--- /dev/null
+++ b/lib/docs/scrapers/click.rb
@@ -0,0 +1,30 @@
+module Docs
+ class Click < UrlScraper
+ self.name = 'click'
+ self.type = 'sphinx'
+ self.root_path = 'index.html'
+ self.links = {
+ home: 'https://click.palletsprojects.com/',
+ code: 'https://github.com/pallets/click'
+ }
+
+ html_filters.push 'click/pre_clean_html', 'click/entries', 'sphinx/clean_html'
+
+ options[:container] = '.body > section'
+ options[:skip] = ['changes/', 'genindex/', 'py-modindex/']
+ options[:title] = false
+
+ options[:attribution] = <<-HTML
+ © Copyright 2014 Pallets.
+ Licensed under the BSD 3-Clause License.
+ We are not supported nor endorsed by Pallets.
+ HTML
+
+ self.release = '8.1.x'
+ self.base_url = "https://click.palletsprojects.com/en/#{self.release}/"
+
+ def get_latest_version(opts)
+ get_latest_github_release('pallets', 'click', opts)
+ end
+ end
+end
diff --git a/lib/docs/scrapers/crystal.rb b/lib/docs/scrapers/crystal.rb
index ed26c585..94da0e29 100644
--- a/lib/docs/scrapers/crystal.rb
+++ b/lib/docs/scrapers/crystal.rb
@@ -36,7 +36,7 @@ module Docs
def get_latest_version(opts)
doc = fetch_doc('https://crystal-lang.org/', opts)
- doc.at_css('.latest-release').content.scan(/([0-9.]+)/)[0][0]
+ doc.at_css('.latest-release-info > a > strong').content.scan(/([0-9.]+)/)[0][0]
end
end
end
diff --git a/lib/docs/scrapers/docker.rb b/lib/docs/scrapers/docker.rb
index 5d01341d..070796ae 100644
--- a/lib/docs/scrapers/docker.rb
+++ b/lib/docs/scrapers/docker.rb
@@ -96,7 +96,7 @@ module Docs
def get_latest_version(opts)
doc = fetch_doc('https://docs.docker.com/engine/release-notes/', opts)
- latest_version = doc.at_css('.content > section > h2').content.strip
+ latest_version = doc.at_css('.DocSearch-content > h2 > a').content.strip
latest_version.rpartition(' ')[-1]
end
end
diff --git a/lib/docs/scrapers/nextjs.rb b/lib/docs/scrapers/nextjs.rb
new file mode 100644
index 00000000..99d3f5ca
--- /dev/null
+++ b/lib/docs/scrapers/nextjs.rb
@@ -0,0 +1,26 @@
+module Docs
+ class Nextjs < UrlScraper
+ self.name = 'Next.js'
+ self.slug = 'nextjs'
+ self.type = 'simple'
+ self.release = '14.2.4'
+ self.base_url = 'https://nextjs.org/docs'
+ self.initial_paths = %w(reference/)
+ self.links = {
+ home: 'https://www.nextjs.org/',
+ code: 'https://github.com/vercel/next.js'
+ }
+
+ html_filters.push 'nextjs/entries', 'nextjs/clean_html'
+ options[:download_images] = false
+
+ options[:attribution] = <<-HTML
+ © 2024 Vercel, Inc.
+ Licensed under the MIT License.
+ HTML
+
+ def get_latest_version(opts)
+ get_npm_version('next', opts)
+ end
+ end
+end
diff --git a/lib/docs/scrapers/node.rb b/lib/docs/scrapers/node.rb
index 60a89677..c41f82b1 100644
--- a/lib/docs/scrapers/node.rb
+++ b/lib/docs/scrapers/node.rb
@@ -74,8 +74,8 @@ module Docs
end
def get_latest_version(opts)
- doc = fetch_doc('https://nodejs.org/en/', opts)
- doc.at_css('#home-intro > .home-downloadblock:last-of-type > a')['data-version'][1..-1]
+ tags = get_github_tags('nodejs', 'node', opts)
+ tags[0]['name'][1..-1]
end
end
end
diff --git a/lib/docs/scrapers/octave.rb b/lib/docs/scrapers/octave.rb
index fa9103fc..def6541e 100644
--- a/lib/docs/scrapers/octave.rb
+++ b/lib/docs/scrapers/octave.rb
@@ -51,7 +51,7 @@ module Docs
def get_latest_version(opts)
doc = fetch_doc('https://octave.org/doc/interpreter/', opts)
- doc.at_css('h1').content.scan(/([0-9.]+)/)[0][0]
+ doc.at_css('#SEC_Top + p').content.scan(/([0-9.]+)/)[1][0][0..-2]
end
end
diff --git a/lib/docs/scrapers/phalcon.rb b/lib/docs/scrapers/phalcon.rb
index c6ca63f2..a0fa8e06 100644
--- a/lib/docs/scrapers/phalcon.rb
+++ b/lib/docs/scrapers/phalcon.rb
@@ -31,8 +31,8 @@ module Docs
end
def get_latest_version(opts)
- doc = fetch_doc('https://docs.phalconphp.com/', opts)
- doc.at_css('.header__lang.expand > div > ul > li > a').content
+ tags = get_github_tags('phalcon', 'cphalcon', opts)
+ tags[0]['name'][1..-1]
end
end
end
diff --git a/lib/docs/scrapers/sanctuary_type_classes.rb b/lib/docs/scrapers/sanctuary_type_classes.rb
index 5156e689..87f4410f 100644
--- a/lib/docs/scrapers/sanctuary_type_classes.rb
+++ b/lib/docs/scrapers/sanctuary_type_classes.rb
@@ -23,7 +23,7 @@ module Docs
HTML
def get_latest_version(opts)
- get-npm-version("sanctuary-type-classes", opts)
+ get_npm_version("sanctuary-type-classes", opts)
end
end
end
diff --git a/lib/docs/scrapers/vite.rb b/lib/docs/scrapers/vite.rb
index 46309fa7..e63b1454 100644
--- a/lib/docs/scrapers/vite.rb
+++ b/lib/docs/scrapers/vite.rb
@@ -22,7 +22,7 @@ module Docs
html_filters.push 'vite/entries', 'vite/clean_html'
version do
- self.release = '5.0.11'
+ self.release = '5.2.13'
self.base_url = 'https://vitejs.dev/'
end
diff --git a/lib/docs/scrapers/vue.rb b/lib/docs/scrapers/vue.rb
index 7fac3ce6..25a21011 100644
--- a/lib/docs/scrapers/vue.rb
+++ b/lib/docs/scrapers/vue.rb
@@ -19,7 +19,7 @@ module Docs
HTML
version '3' do
- self.release = '3.4.5'
+ self.release = '3.4.27'
self.base_url = 'https://vuejs.org/'
self.initial_paths = %w(guide/introduction.html)
html_filters.push 'vue/entries_v3', 'vue/clean_html'
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..c77b993a
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6 @@
+{
+ "name": "devdocs",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {}
+}
diff --git a/public/icons/docs/click/16.png b/public/icons/docs/click/16.png
new file mode 100644
index 00000000..d1497c30
Binary files /dev/null and b/public/icons/docs/click/16.png differ
diff --git a/public/icons/docs/click/16@2x.png b/public/icons/docs/click/16@2x.png
new file mode 100644
index 00000000..3bc91ffb
Binary files /dev/null and b/public/icons/docs/click/16@2x.png differ
diff --git a/public/icons/docs/click/SOURCE b/public/icons/docs/click/SOURCE
new file mode 100644
index 00000000..be844957
--- /dev/null
+++ b/public/icons/docs/click/SOURCE
@@ -0,0 +1 @@
+https://github.com/pallets/click/blob/main/docs/_static/click-icon.png
diff --git a/public/icons/docs/nextjs/16.png b/public/icons/docs/nextjs/16.png
new file mode 100644
index 00000000..41e7ff4d
Binary files /dev/null and b/public/icons/docs/nextjs/16.png differ
diff --git a/public/icons/docs/nextjs/16@2x.png b/public/icons/docs/nextjs/16@2x.png
new file mode 100644
index 00000000..e35d18e2
Binary files /dev/null and b/public/icons/docs/nextjs/16@2x.png differ
diff --git a/public/icons/docs/nextjs/SOURCE b/public/icons/docs/nextjs/SOURCE
new file mode 100644
index 00000000..178b8630
--- /dev/null
+++ b/public/icons/docs/nextjs/SOURCE
@@ -0,0 +1,2 @@
+https://assets.vercel.com/image/upload/v1662130559/nextjs/Icon_dark_background.png
+https://github.com/vercel/next.js/blob/canary/examples/cms-enterspeed/public/favicon/favicon.ico
\ No newline at end of file