diff --git a/lib/docs/filters/coffeescript/clean_html.rb b/lib/docs/filters/coffeescript/clean_html.rb index fe8406e6..75fc949a 100644 --- a/lib/docs/filters/coffeescript/clean_html.rb +++ b/lib/docs/filters/coffeescript/clean_html.rb @@ -2,52 +2,24 @@ module Docs class Coffeescript class CleanHtmlFilter < Filter def call - css('#top', '.minibutton', '.clear').remove + @doc = at_css('main') - # Set id attributes on actual elements instead of an empty - css('.bookmark').each do |node| - node.next_element['id'] = node['id'] - node.remove - end - - # Remove Books, Screencasts, etc. - while doc.children.last['id'] != 'resources' - doc.children.last.remove - end - doc.children.last.remove - - # Make proper headings - css('.header').each do |node| - node.parent.before(node) - node.name = 'h3' - node['id'] ||= node.content.strip.parameterize - node.remove_attribute 'class' - end - - # Remove "Latest Version" paragraph - css('b').each do |node| - if node.content =~ /Latest Version/i - node.parent.next_element.remove - node.parent.remove - break - end - end + css('> header', '#resources', '#changelog').remove - # Remove "examples can be run" paragraph - css('i').each do |node| - if node.content =~ /examples can be run/i - node.parent.remove - break - end + css('section').each do |node| + node.first_element_child['id'] = node['id'] + node.before(node.children).remove end - # Remove code highlighting - css('pre').each do |node| - node.content = node.content + css('.uneditable-code-block').each do |node| + node.before(node.children).remove end - css('blockquote > pre:first-child:last-child').each do |node| - node.parent.before(node).remove + css('aside.code-example').each do |node| + node.name = 'div' + node['class'] = 'code' + node.children = node.css('pre') + node.remove_attribute('data-example') end css('.code pre:first-child').each do |node| @@ -58,8 +30,12 @@ module Docs node['data-language'] = 'javascript' end - css('tt').each do |node| - node.name = 'code' + css('pre').each do |node| + content = node.content + node.content = content + unless content.start_with?('coffee ') || content.start_with?('npm ') + node['data-language'] ||= 'coffeescript' + end end doc diff --git a/lib/docs/filters/coffeescript/clean_html_v1.rb b/lib/docs/filters/coffeescript/clean_html_v1.rb new file mode 100644 index 00000000..07173a7f --- /dev/null +++ b/lib/docs/filters/coffeescript/clean_html_v1.rb @@ -0,0 +1,69 @@ +module Docs + class Coffeescript + class CleanHtmlV1Filter < Filter + def call + css('#top', '.minibutton', '.clear').remove + + # Set id attributes on actual elements instead of an empty + css('.bookmark').each do |node| + node.next_element['id'] = node['id'] + node.remove + end + + # Remove Books, Screencasts, etc. + while doc.children.last['id'] != 'resources' + doc.children.last.remove + end + doc.children.last.remove + + # Make proper headings + css('.header').each do |node| + node.parent.before(node) + node.name = 'h3' + node['id'] ||= node.content.strip.parameterize + node.remove_attribute 'class' + end + + # Remove "Latest Version" paragraph + css('b').each do |node| + if node.content =~ /Latest Version/i + node.parent.next_element.remove + node.parent.remove + break + end + end + + # Remove "examples can be run" paragraph + css('i').each do |node| + if node.content =~ /examples can be run/i + node.parent.remove + break + end + end + + # Remove code highlighting + css('pre').each do |node| + node.content = node.content + end + + css('blockquote > pre:first-child:last-child').each do |node| + node.parent.before(node).remove + end + + css('.code pre:first-child').each do |node| + node['data-language'] = 'coffeescript' + end + + css('.code pre:last-child').each do |node| + node['data-language'] = 'javascript' + end + + css('tt').each do |node| + node.name = 'code' + end + + doc + end + end + end +end diff --git a/lib/docs/filters/coffeescript/entries.rb b/lib/docs/filters/coffeescript/entries.rb index 9201b9dd..44aeba24 100644 --- a/lib/docs/filters/coffeescript/entries.rb +++ b/lib/docs/filters/coffeescript/entries.rb @@ -2,12 +2,9 @@ module Docs class Coffeescript class EntriesFilter < Docs::EntriesFilter ENTRIES = [ - ['coffee command', 'usage', 'Miscellaneous'], - ['Literate mode', 'literate', 'Miscellaneous'], - ['Functions', 'literals', 'Language'], - ['->', 'literals', 'Statements'], - ['Objects and arrays', 'objects_and_arrays', 'Language'], - ['Lexical scoping', 'lexical-scope', 'Language'], + ['coffee command', 'cli', 'Miscellaneous'], + ['->', 'functions', 'Statements'], + ['await', 'async-functions', 'Statements'], ['if...then...else', 'conditionals', 'Statements'], ['unless', 'conditionals', 'Statements'], ['... splats', 'splats', 'Language'], @@ -19,56 +16,58 @@ module Docs ['until', 'loops', 'Statements'], ['loop', 'loops', 'Statements'], ['do', 'loops', 'Statements'], - ['Array slicing and splicing', 'slices', 'Language'], ['Ranges', 'slices', 'Language'], - ['Expressions', 'expressions', 'Language'], ['?', 'existential-operator', 'Operators'], ['?=', 'existential-operator', 'Operators'], ['?.', 'existential-operator', 'Operators'], ['class', 'classes', 'Statements'], - ['extends', 'classes', 'Operators'], + ['extends', 'classes', 'Statements'], ['super', 'classes', 'Statements'], - ['::', 'classes', 'Operators'], - ['Destructuring assignment', 'destructuring', 'Language'], - ['Bound Functions', 'fat-arrow', 'Language'], - ['Generator Functions', 'fat-arrow', 'Language'], + ['::', 'prototypal-inheritance', 'Operators'], ['=>', 'fat-arrow', 'Statements'], - ['yield', 'fat-arrow', 'Statements'], - ['for...from', 'fat-arrow', 'Statements'], - ['Embedded JavaScript', 'embedded', 'Language'], + ['yield', 'generators', 'Statements'], ['switch...when...else', 'switch', 'Statements'], - ['try...catch...finally', 'try-catch', 'Statements'], - ['Chained comparisons', 'comparisons', 'Language'], + ['try...catch...finally', 'try', 'Statements'], ['#{} interpolation', 'strings', 'Language'], ['Block strings', 'strings', 'Language'], ['"""', 'strings', 'Language'], - ['Block comments', 'strings', 'Language'], - ['###', 'strings', 'Language'], - ['Tagged Template Literals', 'tagged-template-literals', 'Language'], - ['Block regexes', 'regexes', 'Language'], + ['###', 'comments', 'Language'], + ['###::', 'type-annotations', 'Language'], ['///', 'regexes', 'Language'], - ['Modules', 'modules', 'Language'], ['import', 'modules', 'Language'], - ['export', 'modules', 'Language'], - ['cake command', 'cake', 'Miscellaneous'], - ['Cakefile', 'cake', 'Miscellaneous'], - ['Source maps', 'source-maps', 'Miscellaneous'] + ['export', 'modules', 'Language'] ] def additional_entries - entries = ENTRIES.dup + entries = [] - # Operators - at_css('#operators ~ table').css('td:first-child > code').each do |node| - node.content.split(', ').each do |name| - next if %w(true false yes no on off this).include?(name) - name.sub! %r{\Aa (.+) b\z}, '\1' - id = name_to_id(name) - node['id'] = id - entries << [name, id, 'Operators'] + ENTRIES.each do |entry| + raise "entry not found: #{entry.inspect}" unless at_css("[id='#{entry[1]}']") + entries << entry + end + + css('.navbar > nav > .nav-link').each do |node| + name = node.content.strip + next if name.in?(%w(Overview Changelog)) || !node['href'].start_with?('#') + entries << [name, node['href'].remove('#'), 'Miscellaneous'] + + if name == 'Language Reference' + node.next_element.css('.nav-link').each do |n| + entries << [n.content, n['href'].remove('#'), name] + end end end + at_css('#operators table').css('td:first-child > code').each do |node| + name = node.content.strip + next if %w(true false yes no on off this).include?(name) + name.sub! %r{\Aa (.+) b\z}, '\1' + name = 'for...from' if name == 'for a from b' + id = name_to_id(name) + node['id'] = id + entries << [name, id, 'Operators'] + end + entries end diff --git a/lib/docs/filters/coffeescript/entries_v1.rb b/lib/docs/filters/coffeescript/entries_v1.rb new file mode 100644 index 00000000..4f3aa9b7 --- /dev/null +++ b/lib/docs/filters/coffeescript/entries_v1.rb @@ -0,0 +1,86 @@ +module Docs + class Coffeescript + class EntriesV1Filter < Docs::EntriesFilter + ENTRIES = [ + ['coffee command', 'usage', 'Miscellaneous'], + ['Literate mode', 'literate', 'Miscellaneous'], + ['Functions', 'literals', 'Language'], + ['->', 'literals', 'Statements'], + ['Objects and arrays', 'objects-and-arrays', 'Language'], + ['Lexical scoping', 'lexical-scope', 'Language'], + ['if...then...else', 'conditionals', 'Statements'], + ['unless', 'conditionals', 'Statements'], + ['... splats', 'splats', 'Language'], + ['for...in', 'loops', 'Statements'], + ['for...in...by', 'loops', 'Statements'], + ['for...in...when', 'loops', 'Statements'], + ['for...of', 'loops', 'Statements'], + ['while', 'loops', 'Statements'], + ['until', 'loops', 'Statements'], + ['loop', 'loops', 'Statements'], + ['do', 'loops', 'Statements'], + ['Array slicing and splicing', 'slices', 'Language'], + ['Ranges', 'slices', 'Language'], + ['Expressions', 'expressions', 'Language'], + ['?', 'existential-operator', 'Operators'], + ['?=', 'existential-operator', 'Operators'], + ['?.', 'existential-operator', 'Operators'], + ['class', 'classes', 'Statements'], + ['extends', 'classes', 'Operators'], + ['super', 'classes', 'Statements'], + ['::', 'classes', 'Operators'], + ['Destructuring assignment', 'destructuring', 'Language'], + ['Bound Functions', 'fat-arrow', 'Language'], + ['Generator Functions', 'fat-arrow', 'Language'], + ['=>', 'fat-arrow', 'Statements'], + ['yield', 'fat-arrow', 'Statements'], + ['for...from', 'fat-arrow', 'Statements'], + ['Embedded JavaScript', 'embedded', 'Language'], + ['switch...when...else', 'switch', 'Statements'], + ['try...catch...finally', 'try-catch', 'Statements'], + ['Chained comparisons', 'comparisons', 'Language'], + ['#{} interpolation', 'strings', 'Language'], + ['Block strings', 'strings', 'Language'], + ['"""', 'strings', 'Language'], + ['Block comments', 'strings', 'Language'], + ['###', 'strings', 'Language'], + ['Tagged Template Literals', 'tagged-template-literals', 'Language'], + ['Block regexes', 'regexes', 'Language'], + ['///', 'regexes', 'Language'], + ['Modules', 'modules', 'Language'], + ['import', 'modules', 'Language'], + ['export', 'modules', 'Language'], + ['cake command', 'cake', 'Miscellaneous'], + ['Cakefile', 'cake', 'Miscellaneous'], + ['Source maps', 'source-maps', 'Miscellaneous'] + ] + + def additional_entries + entries = ENTRIES.dup + + # Operators + at_css('#operators ~ table').css('td:first-child > code').each do |node| + node.content.split(', ').each do |name| + next if %w(true false yes no on off this).include?(name) + name.sub! %r{\Aa (.+) b\z}, '\1' + id = name_to_id(name) + node['id'] = id + entries << [name, id, 'Operators'] + end + end + + entries + end + + def name_to_id(name) + case name + when '**' then 'pow' + when '//' then 'floor' + when '%%' then 'mod' + when '@' then 'this' + else name.parameterize + end + end + end + end +end diff --git a/lib/docs/scrapers/coffeescript.rb b/lib/docs/scrapers/coffeescript.rb index 49f29e87..ff87a534 100644 --- a/lib/docs/scrapers/coffeescript.rb +++ b/lib/docs/scrapers/coffeescript.rb @@ -2,22 +2,33 @@ module Docs class Coffeescript < UrlScraper self.name = 'CoffeeScript' self.type = 'coffeescript' - self.release = '1.12.6' - self.base_url = 'http://coffeescript.org' self.links = { home: 'http://coffeescript.org', code: 'https://github.com/jashkenas/coffeescript' } - html_filters.push 'coffeescript/clean_html', 'coffeescript/entries', 'title' - options[:title] = 'CoffeeScript' - options[:container] = '.container' options[:skip_links] = true options[:attribution] = <<-HTML © 2009–2017 Jeremy Ashkenas
Licensed under the MIT License. HTML + + version '2' do + self.release = '2.0.1' + self.base_url = 'http://coffeescript.org/' + + html_filters.push 'coffeescript/entries', 'coffeescript/clean_html', 'title' + end + + version '1' do + self.release = '1.12.6' + self.base_url = 'http://coffeescript.org/v1/' + + html_filters.push 'coffeescript/clean_html_v1', 'coffeescript/entries_v1', 'title' + + options[:container] = '.container' + end end end