Unified · Split
| @@ -686,6 +686,11 @@ credits = [ · 685 unmodified lines | ||
| 686 | 686 | '2012-2018 The Qt Company Ltd', |
| 687 | 687 | 'GFDL', |
| 688 | 688 | 'https://doc.qt.io/qt-5/licensing.html' |
| 689 | + ], [ | |
| 690 | + 'R', | |
| 691 | + '1999–2012 R Foundation for Statistical Computing', | |
| 692 | + 'GPL', | |
| 693 | + 'https://svn.r-project.org/R/trunk/COPYING' | |
| 689 | 694 | ], [ |
| 690 | 695 | 'Ramda', |
| 691 | 696 | '2013-2020 Scott Sauyet and Michael Hurley', |
| @@ -0,0 +1,61 @@ | ||
| 1 | +module Docs | |
| 2 | + class R | |
| 3 | + class CleanHtmlFilter < Filter | |
| 4 | + def call | |
| 5 | + slug_parts = slug.split('/') | |
| 6 | + | |
| 7 | + if root_page? | |
| 8 | + css('a[href$="/00index"]').each do |pkg| | |
| 9 | + pkg['href'] = "/r-#{pkg['href'].split('/')[1]}/" | |
| 10 | + end | |
| 11 | + | |
| 12 | + elsif slug_parts[0] == 'library' | |
| 13 | + title = at_css('h2') | |
| 14 | + title.inner_html = "<code>#{slug_parts[3]}</code> #{title.content}" | |
| 15 | + | |
| 16 | + summary = at_css('table[summary]') | |
| 17 | + summary.remove if summary | |
| 18 | + | |
| 19 | + css('hr ~ *, hr').remove | |
| 20 | + | |
| 21 | + elsif slug_parts[-2] == 'manual' | |
| 22 | + css('table.menu, div.header, hr, h2.contents-heading, div.contents, table.index-cp, table.index-vr, table[summary]').remove | |
| 23 | + | |
| 24 | + css('h2').each do |node| | |
| 25 | + node.remove if node.content.end_with? ' index' | |
| 26 | + end | |
| 27 | + | |
| 28 | + css('span[id] + h1, span[id] + h2, span[id] + h3, span[id] + h4, span[id] + h5, span[id] + h6').each do |node| | |
| 29 | + # We need the first of the series of span with ids | |
| 30 | + span = node.previous_element | |
| 31 | + while span.previous | |
| 32 | + prev = span.previous_element | |
| 33 | + break unless prev.name == 'span' and prev['id'] | |
| 34 | + span.remove | |
| 35 | + span = prev | |
| 36 | + end | |
| 37 | + | |
| 38 | + node['id'] = span['id'] | |
| 39 | + span.remove | |
| 40 | + | |
| 41 | + css('div.example').each do |node| | |
| 42 | + node.replace(node.children) | |
| 43 | + end | |
| 44 | + end | |
| 45 | + | |
| 46 | + css('h1 + h1').remove | |
| 47 | + | |
| 48 | + css('.footnote h5').each do |node| | |
| 49 | + anchor = node.at_css('a[id]') | |
| 50 | + footnote = node.next_sibling | |
| 51 | + footnote.inner_html = "<strong>#{anchor.text}</strong> #{footnote.inner_html}" | |
| 52 | + footnote['id'] = anchor['id'] | |
| 53 | + node.remove | |
| 54 | + end | |
| 55 | + end | |
| 56 | + | |
| 57 | + doc | |
| 58 | + end | |
| 59 | + end | |
| 60 | + end | |
| 61 | +end | |
| @@ -0,0 +1,84 @@ | ||
| 1 | +module Docs | |
| 2 | + class R | |
| 3 | + class EntriesFilter < Docs::EntriesFilter | |
| 4 | + | |
| 5 | + PKG_INDEX_ENTRIES = Hash.new [] | |
| 6 | + | |
| 7 | + def call | |
| 8 | + if slug_parts[-1] == '00Index' | |
| 9 | + dir = File.dirname(result[:subpath]) | |
| 10 | + css('tr a').each do |link| | |
| 11 | + PKG_INDEX_ENTRIES[link['href']] += [link.text] | |
| 12 | + next if link['href'] == link.text | |
| 13 | + context[:replace_paths][File.join(dir, "#{link.text}.html")] = File.join(dir, "#{link['href']}.html") | |
| 14 | + end | |
| 15 | + end | |
| 16 | + | |
| 17 | + super | |
| 18 | + end | |
| 19 | + | |
| 20 | + def slug_parts | |
| 21 | + slug.split('/') | |
| 22 | + end | |
| 23 | + | |
| 24 | + def is_package? | |
| 25 | + slug_parts[0] == 'library' | |
| 26 | + end | |
| 27 | + | |
| 28 | + def is_manual? | |
| 29 | + slug_parts[1] == 'manual' | |
| 30 | + end | |
| 31 | + | |
| 32 | + def get_name | |
| 33 | + return at_css('h2').content if is_package? | |
| 34 | + title = at_css('h1.settitle') | |
| 35 | + title ? title.content : at_css('h1, h2').content | |
| 36 | + end | |
| 37 | + | |
| 38 | + def get_type | |
| 39 | + return slug_parts[1] if is_package? | |
| 40 | + return at_css('h1.settitle').content if is_manual? | |
| 41 | + end | |
| 42 | + | |
| 43 | + def include_default_entry? | |
| 44 | + is_package? and not slug_parts[-1] == '00Index' | |
| 45 | + end | |
| 46 | + | |
| 47 | + def manual_section(node) | |
| 48 | + title = node.content.sub /^((Appendix )?[A-Z]|[0-9]+)(\.[0-9]+)* /, '' | |
| 49 | + title unless ['References', 'Preface', 'Acknowledgements'].include?(title) or title.end_with?(' index') | |
| 50 | + end | |
| 51 | + | |
| 52 | + def additional_entries | |
| 53 | + if is_package? and slug_parts[-1] != '00Index' | |
| 54 | + page = slug_parts[-1] | |
| 55 | + return [page] + PKG_INDEX_ENTRIES.fetch(page, []) | |
| 56 | + end | |
| 57 | + | |
| 58 | + return [] unless is_manual? | |
| 59 | + | |
| 60 | + entries = [] | |
| 61 | + unless slug_parts[-1].downcase == 'r-intro' | |
| 62 | + # Single top-level category | |
| 63 | + css('div.contents > ul a').each do |link| | |
| 64 | + link_name = manual_section(link) | |
| 65 | + entries << [link_name, link['href'].split('#')[1], name] unless link_name.nil? | |
| 66 | + end | |
| 67 | + else | |
| 68 | + # Split 1st level of manual into different categories | |
| 69 | + css('div.contents > ul > li').each do |node| | |
| 70 | + type = manual_section(node.at_css('a')) | |
| 71 | + next if type.nil? | |
| 72 | + node.css('> ul a').each do |link| | |
| 73 | + link_name = link.content.sub /^[0-9A-Z]+(\.[0-9]+)* /, '' | |
| 74 | + entries << [link_name, link['href'].split('#')[1], type] | |
| 75 | + end | |
| 76 | + end | |
| 77 | + end | |
| 78 | + return entries | |
| 79 | + end | |
| 80 | + | |
| 81 | + private | |
| 82 | + end | |
| 83 | + end | |
| 84 | +end | |
| @@ -0,0 +1,53 @@ | ||
| 1 | +module Docs | |
| 2 | + class R < FileScraper | |
| 3 | + self.name = 'R' | |
| 4 | + self.slug = 'r' | |
| 5 | + self.type = 'simple' | |
| 6 | + self.release = '4.1.0' | |
| 7 | + self.links = { | |
| 8 | + home: 'https://www.r-project.org/', | |
| 9 | + code: 'https://svn.r-project.org/R/' | |
| 10 | + } | |
| 11 | + | |
| 12 | + self.root_path = 'doc/html/packages.html' | |
| 13 | + | |
| 14 | + html_filters.push 'r/entries', 'r/clean_html' | |
| 15 | + | |
| 16 | + options[:skip_links] = false | |
| 17 | + | |
| 18 | + options[:attribution] = <<-HTML | |
| 19 | + Copyright (©) 1999–2012 R Foundation for Statistical Computing.<br> | |
| 20 | + Licensed under the <a href="https://www.gnu.org/copyleft/gpl.html">GNU General Public License</a>. | |
| 21 | + HTML | |
| 22 | + | |
| 23 | + # Never want those | |
| 24 | + options[:skip_patterns] = [ | |
| 25 | + /\/DESCRIPTION$/, | |
| 26 | + /\/NEWS(\.[^\/]*)?$/, | |
| 27 | + /\/doc\/index\.html$/, | |
| 28 | + /\/demo$/, | |
| 29 | + /\.pdf$/ | |
| 30 | + ] | |
| 31 | + | |
| 32 | + options[:replace_paths] = { | |
| 33 | + ## We want to fix links like so − but only if the targets don’t exist: | |
| 34 | + # 'library/MASS/html/cov.mve.html' => 'library/MASS/html/cov.rob.html' | |
| 35 | + ## Paths for target packages or keywords that do not have their own file | |
| 36 | + ## are generated in the entries filter from 00Index.html files | |
| 37 | + } | |
| 38 | + | |
| 39 | + options[:skip] = %w( | |
| 40 | + doc/html/packages-head-utf8.html | |
| 41 | + doc/html/SearchOn.html | |
| 42 | + doc/html/Search.html | |
| 43 | + doc/html/UserManuals.html | |
| 44 | + doc/html/faq.html | |
| 45 | + doc/manual/R-FAQ.html | |
| 46 | + doc/manual/R-admin.html | |
| 47 | + doc/manual/R-exts.html | |
| 48 | + doc/manual/R-ints.html | |
| 49 | + doc/manual/R-lang.html | |
| 50 | + ) | |
| 51 | + | |
| 52 | + end | |
| 53 | +end | |
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1 @@ | ||
| 1 | +https://svn.r-project.org/R/trunk/doc/html/Rlogo.svg | |