diff --git a/lib/docs/filters/pytorch/entries.rb b/lib/docs/filters/pytorch/entries.rb
index 85d2f06418..7b31d037d4 100644
--- a/lib/docs/filters/pytorch/entries.rb
+++ b/lib/docs/filters/pytorch/entries.rb
@@ -2,6 +2,9 @@ module Docs
class Pytorch
class EntriesFilter < Docs::EntriesFilter
def get_breadcrumbs
+ breadcrumbs = schema_breadcrumbs
+ return breadcrumbs unless breadcrumbs.empty?
+
breadcrumbs = if at_css('.pytorch-breadcrumbs')
css('.pytorch-breadcrumbs > li').map { |node|
node.content.delete_suffix(' >').strip
@@ -26,15 +29,19 @@ def get_name
end
def get_type
- if at_css('.pytorch-breadcrumbs')
- get_breadcrumbs[1]
+ breadcrumbs = get_breadcrumbs
+
+ if schema_breadcrumbs.any?
+ breadcrumbs.size > 2 ? breadcrumbs[-2] : breadcrumbs[-1]
+ elsif at_css('.pytorch-breadcrumbs')
+ breadcrumbs[1]
else
- get_breadcrumbs.size > 2 ? get_breadcrumbs[2] : get_breadcrumbs[1]
+ breadcrumbs.size > 2 ? breadcrumbs[2] : breadcrumbs[1]
end
end
def include_default_entry?
- !get_breadcrumbs.nil? && get_breadcrumbs.size >= 2
+ schema_breadcrumbs.any? || get_breadcrumbs.size >= 2
end
def additional_entries
@@ -61,6 +68,22 @@ def additional_entries
entries
end
+
+ private
+
+ def schema_breadcrumbs
+ @schema_breadcrumbs ||= css(
+ '[itemtype="https://schema.org/BreadcrumbList"] [itemprop="itemListElement"]'
+ ).filter_map do |node|
+ name = node.at_css('[itemprop="name"]')
+ next unless name
+
+ text = Nokogiri::HTML.fragment(name['content'] || name.content).text.strip
+ dangling_text = node.text.strip.delete_suffix('">') if name['content']
+ text = "#{text} #{dangling_text}" if dangling_text.present?
+ text
+ end.reject(&:empty?)
+ end
end
end
end
diff --git a/lib/docs/scrapers/pytorch.rb b/lib/docs/scrapers/pytorch.rb
index e45ac3b096..3e9c3b67be 100644
--- a/lib/docs/scrapers/pytorch.rb
+++ b/lib/docs/scrapers/pytorch.rb
@@ -1,8 +1,9 @@
module Docs
- class Pytorch < UrlScraper
+ class Pytorch < FileScraper
self.name = 'PyTorch'
self.slug = 'pytorch'
self.type = 'sphinx'
+ self.root_path = 'index.html'
self.links = {
home: 'https://pytorch.org/',
code: 'https://github.com/pytorch/pytorch'
@@ -11,14 +12,45 @@ class Pytorch < UrlScraper
html_filters.push 'pytorch/entries', 'pytorch/clean_html', 'sphinx/clean_html'
options[:skip] = ['cpp_index.html', 'deploy.html', 'packages.html', 'py-modindex.html', 'genindex.html']
- options[:skip_patterns] = [/\Acommunity/, /\A_modules/, /\Anotes/, /\Aorg\/pytorch\//]
+ options[:skip_patterns] = [
+ /.*(?
+ © 2026, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
HTML
+ version '2.14' do
+ self.release = '2.14'
+ self.base_url = "https://docs.pytorch.org/docs/#{release}/"
+ end
+
+ version '2.13' do
+ self.release = '2.13'
+ self.base_url = "https://docs.pytorch.org/docs/#{release}/"
+ end
+
+ version '2.12' do
+ self.release = '2.12'
+ self.base_url = "https://docs.pytorch.org/docs/#{release}/"
+ end
+
+ version '2.11' do
+ self.release = '2.11'
+ self.base_url = "https://docs.pytorch.org/docs/#{release}/"
+ end
+
+ version '2.10' do
+ self.release = '2.10'
+ self.base_url = "https://docs.pytorch.org/docs/#{release}/"
+ end
+
version '2.9' do
self.release = '2.9'
self.base_url = "https://docs.pytorch.org/docs/#{release}/"
@@ -77,5 +109,28 @@ class Pytorch < UrlScraper
def get_latest_version(opts)
get_latest_github_release('pytorch', 'pytorch', opts)
end
+
+ private
+
+ # There is no documentation archive, the files have to be taken from the
+ # repository hosting https://docs.pytorch.org.
+ def download_source
+ require 'tmpdir'
+
+ Dir.mktmpdir do |directory|
+ repository = File.join(directory, 'docs')
+
+ instrument 'info.doc', msg: %(Cloning the PyTorch #{self.class.version} documentation...)
+ # The "site" branch holds the rendered documentation of every version,
+ # of which only the one being scraped is checked out.
+ system('git', 'clone', '--branch', 'site', '--depth', '1', '--filter=blob:none', '--sparse',
+ 'https://github.com/pytorch/docs', repository)
+ system('git', '-C', repository, 'sparse-checkout', 'set', self.class.version)
+
+ instrument 'info.doc', msg: %(Moving the documentation files to "#{source_directory}"...)
+ FileUtils.mkpath(File.dirname(source_directory))
+ FileUtils.mv(File.join(repository, self.class.version), source_directory)
+ end
+ end
end
end