diff --git a/assets/javascripts/templates/pages/about_tmpl.coffee b/assets/javascripts/templates/pages/about_tmpl.coffee index a366449a..6fdba573 100644 --- a/assets/javascripts/templates/pages/about_tmpl.coffee +++ b/assets/javascripts/templates/pages/about_tmpl.coffee @@ -587,6 +587,11 @@ credits = [ '2006-2021 Andreas Rumpf', 'MIT', 'https://github.com/nim-lang/Nim#license' + ], [ + 'Nix', + '2022 NixOS Contributors', + 'LGPLv2.1', + 'https://github.com/NixOS/nix#license' ], [ 'Node.js', 'Joyent, Inc. and other Node contributors
Node.js is a trademark of Joyent, Inc.', diff --git a/lib/docs/filters/nix/clean_html.rb b/lib/docs/filters/nix/clean_html.rb new file mode 100644 index 00000000..731fc0cf --- /dev/null +++ b/lib/docs/filters/nix/clean_html.rb @@ -0,0 +1,113 @@ +module Docs + class Nix + class CleanHtmlFilter < Filter + def call + if subpath == 'nixpkgs/stable/index.html' + new_root = Nokogiri::XML::Node.new 'div', doc.document + + # lib functions + lib_sections = xpath("//*[@id='sec-functions-library']/ancestor::section[1]/section/section") + lib_sections.css('.titlepage .title').each do |title| + title.name = 'h2' + strip_section_number(title.children) + title['id'] = title.content.gsub(/[^a-zA-Z0-9]/, '-') + end + lib_sections.css('.example .title strong').each do |title| + title.content = title.content.sub(/^Example ([0-9.]+)/, 'Example: ') + end + new_root.add_child(lib_sections) + + # fetchers + fetcher_sections = xpath("//*[@id='chap-pkgs-fetchers']/ancestor::section[1]/section[position()>1]") + fetcher_sections.css('.titlepage .title').each do |title| + strip_section_number(title.children) + prefix_with(title, 'pkgs') if title.name == 'h2' + end + new_root.add_child(fetcher_sections) + + # trivial builders + trivial_sections = xpath("//*[@id='chap-trivial-builders']/ancestor::section[1]/section") + trivial_sections.css('.titlepage .title').each do |title| + strip_section_number(title.children) + prefix_with(title, 'pkgs') if title.name == 'h2' + end + new_root.add_child(trivial_sections) + + # special builders + special_sections = xpath("//*[@id='chap-special']/ancestor::section[1]/section") + special_sections.css('.titlepage .title').each do |title| + strip_section_number(title.children) + if title.name == 'h2' + title.children[0].wrap('') + prefix_with(title, 'pkgs') + end + end + new_root.add_child(special_sections) + + # image builders + image_sections = xpath("//*[@id='chap-images']/ancestor::section[1]/section") + image_sections.css('.titlepage .title').each do |title| + strip_section_number(title.children) + title.children[0].wrap('') + end + image_sections.each do |section| + prefix = section.at_xpath('*[@class="titlepage"]//*[@class="title"]').content + next unless ["pkgs.dockerTools", "pkgs.ociTools"].include?(prefix) + section.xpath('section/*[@class="titlepage"]//*[@class="title"]').each do |title| + prefix_with(title, prefix) + title['data-add-to-index'] = '' + end + end + new_root.add_child(image_sections) + + new_root + elsif subpath == 'nix/stable/expressions/builtins.html' + @doc = doc.at_css('main dl') + + # strip out the first entry, `derivation`, the actual documentation + # exists in a separate page + derivation_dt = doc.children.at_css('dt') + if derivation_dt.content.starts_with?('derivation') + derivation_dt.remove + doc.children.at_css('dd').remove + else + raise RuntimeError.new('First entry is not derivation, update the scraper') + end + + doc.css('dt').each do |title| + title.name = 'h2' + unwrap(title.at_css('a')) + title.children[0].children.before('builtins.') + end + doc.css('dd').each do |description| + description.name = 'div' + end + + doc + else + doc + end + end + + def strip_section_number(title_children) + while title_children.first.content == '' + title_children.shift.remove + end + first_text = title_children.first + return unless first_text.text? + first_text.content = first_text.content.sub(/[0-9.]+ ?/, '') + first_text.remove if first_text.blank? + end + + def prefix_with(title_node, text) + title_node.css('code').each do |code| + code.content = "#{text}.#{code.content}" unless code.content.starts_with?("#{text}.") + end + end + + def unwrap(node) + node.replace(node.inner_html) + end + end + end +end diff --git a/lib/docs/filters/nix/entries.rb b/lib/docs/filters/nix/entries.rb new file mode 100644 index 00000000..f4ff093a --- /dev/null +++ b/lib/docs/filters/nix/entries.rb @@ -0,0 +1,22 @@ +module Docs + class Nix + class EntriesFilter < Docs::EntriesFilter + def include_default_entry? + false + end + + def additional_entries + css('h2, h3[data-add-to-index]').flat_map do |node| + node.css('code').map do |code| + title = code.content + index = title.rindex('.') + type = title[0...index] + name = title.match(/^[^\s]+/)[0] + + [name, node['id'], type] + end + end + end + end + end +end diff --git a/lib/docs/scrapers/nix.rb b/lib/docs/scrapers/nix.rb new file mode 100644 index 00000000..ae549818 --- /dev/null +++ b/lib/docs/scrapers/nix.rb @@ -0,0 +1,31 @@ +module Docs + class Nix < UrlScraper + self.type = 'simple' + self.release = '2.8.0' + self.base_url = 'https://nixos.org/manual/' + self.root_path = 'nix/stable/expressions/builtins.html' + self.initial_paths = %w( + nix/stable/expressions/builtins.html + nixpkgs/stable/index.html) + self.links = { + home: 'https://nixos.org/', + code: 'https://github.com/NixOS/nix' + } + + html_filters.push 'nix/clean_html', 'nix/entries' + + options[:skip_links] = true + + options[:attribution] = <<-HTML + © 2022 NixOS Contributors
+ Licensed under the LGPL License. + HTML + + def get_latest_version(opts) + doc = fetch_doc('https://nixos.org/manual/nix/stable/', opts) + json = JSON.parse(doc.at_css('body')['data-nix-channels']) + channel = json.find { |c| c['channel'] == 'stable' } + channel['version'] + end + end +end diff --git a/public/icons/docs/nix/16.png b/public/icons/docs/nix/16.png new file mode 100644 index 00000000..13ad550b Binary files /dev/null and b/public/icons/docs/nix/16.png differ diff --git a/public/icons/docs/nix/16@2x.png b/public/icons/docs/nix/16@2x.png new file mode 100644 index 00000000..5c1d1368 Binary files /dev/null and b/public/icons/docs/nix/16@2x.png differ diff --git a/public/icons/docs/nix/SOURCE b/public/icons/docs/nix/SOURCE new file mode 100644 index 00000000..c2f6c583 --- /dev/null +++ b/public/icons/docs/nix/SOURCE @@ -0,0 +1 @@ +https://github.com/NixOS/nixos-homepage/blob/master/logo/nixos-logo-only-hires.png