History

Add nix and nixpkgs

This only adds a subset of nix and nixpkgs functions. Notably derivation, stdenv and language-specific functions are omitted for now as their formats differ significantly and will require more cleanup.

Thomas Dy committed 4 years ago

Commit f1dd2ac1 parent e1b6ade7 files · +170 −-2Browse files

Unified · Split

7 files
  1. assets/javascripts/templates/pages/about_tmpl.coffee +5 −0
  2. lib/docs/filters/nix/clean_html.rb +113 −0
  3. lib/docs/filters/nix/entries.rb +22 −0
  4. lib/docs/scrapers/nix.rb +31 −0
  5. public/icons/docs/nix/16.png +0 −0
  6. public/icons/docs/nix/16@2x.png +0 −0
  7. public/icons/docs/nix/SOURCE +1 −0
assets/javascripts/templates/pages/about_tmpl.coffee+5−0
@@ -587,6 +587,11 @@ credits = [ · 586 unmodified lines
587587 '2006-2021 Andreas Rumpf',
588588 'MIT',
589589 'https://github.com/nim-lang/Nim#license'
590+ ], [
591+ 'Nix',
592+ '2022 NixOS Contributors',
593+ 'LGPLv2.1',
594+ 'https://github.com/NixOS/nix#license'
590595 ], [
591596 'Node.js',
592597 'Joyent, Inc. and other Node contributors<br>Node.js is a trademark of Joyent, Inc.',
lib/docs/filters/nix/clean_html.rb+113−0
@@ -0,0 +1,113 @@
1+module Docs
2+ class Nix
3+ class CleanHtmlFilter < Filter
4+ def call
5+ if subpath == 'nixpkgs/stable/index.html'
6+ new_root = Nokogiri::XML::Node.new 'div', doc.document
7+
8+ # lib functions
9+ lib_sections = xpath("//*[@id='sec-functions-library']/ancestor::section[1]/section/section")
10+ lib_sections.css('.titlepage .title').each do |title|
11+ title.name = 'h2'
12+ strip_section_number(title.children)
13+ title['id'] = title.content.gsub(/[^a-zA-Z0-9]/, '-')
14+ end
15+ lib_sections.css('.example .title strong').each do |title|
16+ title.content = title.content.sub(/^Example ([0-9.]+)/, 'Example: ')
17+ end
18+ new_root.add_child(lib_sections)
19+
20+ # fetchers
21+ fetcher_sections = xpath("//*[@id='chap-pkgs-fetchers']/ancestor::section[1]/section[position()>1]")
22+ fetcher_sections.css('.titlepage .title').each do |title|
23+ strip_section_number(title.children)
24+ prefix_with(title, 'pkgs') if title.name == 'h2'
25+ end
26+ new_root.add_child(fetcher_sections)
27+
28+ # trivial builders
29+ trivial_sections = xpath("//*[@id='chap-trivial-builders']/ancestor::section[1]/section")
30+ trivial_sections.css('.titlepage .title').each do |title|
31+ strip_section_number(title.children)
32+ prefix_with(title, 'pkgs') if title.name == 'h2'
33+ end
34+ new_root.add_child(trivial_sections)
35+
36+ # special builders
37+ special_sections = xpath("//*[@id='chap-special']/ancestor::section[1]/section")
38+ special_sections.css('.titlepage .title').each do |title|
39+ strip_section_number(title.children)
40+ if title.name == 'h2'
41+ title.children[0].wrap('<code>')
42+ prefix_with(title, 'pkgs')
43+ end
44+ end
45+ new_root.add_child(special_sections)
46+
47+ # image builders
48+ image_sections = xpath("//*[@id='chap-images']/ancestor::section[1]/section")
49+ image_sections.css('.titlepage .title').each do |title|
50+ strip_section_number(title.children)
51+ title.children[0].wrap('<code>')
52+ end
53+ image_sections.each do |section|
54+ prefix = section.at_xpath('*[@class="titlepage"]//*[@class="title"]').content
55+ next unless ["pkgs.dockerTools", "pkgs.ociTools"].include?(prefix)
56+ section.xpath('section/*[@class="titlepage"]//*[@class="title"]').each do |title|
57+ prefix_with(title, prefix)
58+ title['data-add-to-index'] = ''
59+ end
60+ end
61+ new_root.add_child(image_sections)
62+
63+ new_root
64+ elsif subpath == 'nix/stable/expressions/builtins.html'
65+ @doc = doc.at_css('main dl')
66+
67+ # strip out the first entry, `derivation`, the actual documentation
68+ # exists in a separate page
69+ derivation_dt = doc.children.at_css('dt')
70+ if derivation_dt.content.starts_with?('derivation')
71+ derivation_dt.remove
72+ doc.children.at_css('dd').remove
73+ else
74+ raise RuntimeError.new('First entry is not derivation, update the scraper')
75+ end
76+
77+ doc.css('dt').each do |title|
78+ title.name = 'h2'
79+ unwrap(title.at_css('a'))
80+ title.children[0].children.before('builtins.')
81+ end
82+ doc.css('dd').each do |description|
83+ description.name = 'div'
84+ end
85+
86+ doc
87+ else
88+ doc
89+ end
90+ end
91+
92+ def strip_section_number(title_children)
93+ while title_children.first.content == ''
94+ title_children.shift.remove
95+ end
96+ first_text = title_children.first
97+ return unless first_text.text?
98+ first_text.content = first_text.content.sub(/[0-9.]+ ?/, '')
99+ first_text.remove if first_text.blank?
100+ end
101+
102+ def prefix_with(title_node, text)
103+ title_node.css('code').each do |code|
104+ code.content = "#{text}.#{code.content}" unless code.content.starts_with?("#{text}.")
105+ end
106+ end
107+
108+ def unwrap(node)
109+ node.replace(node.inner_html)
110+ end
111+ end
112+ end
113+end
lib/docs/filters/nix/entries.rb+22−0
@@ -0,0 +1,22 @@
1+module Docs
2+ class Nix
3+ class EntriesFilter < Docs::EntriesFilter
4+ def include_default_entry?
5+ false
6+ end
7+
8+ def additional_entries
9+ css('h2, h3[data-add-to-index]').flat_map do |node|
10+ node.css('code').map do |code|
11+ title = code.content
12+ index = title.rindex('.')
13+ type = title[0...index]
14+ name = title.match(/^[^\s]+/)[0]
15+
16+ [name, node['id'], type]
17+ end
18+ end
19+ end
20+ end
21+ end
22+end
lib/docs/scrapers/nix.rb+31−0
@@ -0,0 +1,31 @@
1+module Docs
2+ class Nix < UrlScraper
3+ self.type = 'simple'
4+ self.release = '2.8.0'
5+ self.base_url = 'https://nixos.org/manual/'
6+ self.root_path = 'nix/stable/expressions/builtins.html'
7+ self.initial_paths = %w(
8+ nix/stable/expressions/builtins.html
9+ nixpkgs/stable/index.html)
10+ self.links = {
11+ home: 'https://nixos.org/',
12+ code: 'https://github.com/NixOS/nix'
13+ }
14+
15+ html_filters.push 'nix/clean_html', 'nix/entries'
16+
17+ options[:skip_links] = true
18+
19+ options[:attribution] = <<-HTML
20+ &copy; 2022 NixOS Contributors<br>
21+ Licensed under the LGPL License.
22+ HTML
23+
24+ def get_latest_version(opts)
25+ doc = fetch_doc('https://nixos.org/manual/nix/stable/', opts)
26+ json = JSON.parse(doc.at_css('body')['data-nix-channels'])
27+ channel = json.find { |c| c['channel'] == 'stable' }
28+ channel['version']
29+ end
30+ end
31+end
public/icons/docs/nix/16.png+0−0

Binary file not shown.

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

Binary file not shown.

public/icons/docs/nix/SOURCE+1−0
@@ -0,0 +1 @@
1+https://github.com/NixOS/nixos-homepage/blob/master/logo/nixos-logo-only-hires.png