Unified · Split
| @@ -109,6 +109,7 @@ · 108 unmodified lines | |||
| 109 | 'pages/qt', | 109 | 'pages/qt', |
| 110 | 'pages/ramda', | 110 | 'pages/ramda', |
| 111 | 'pages/rdoc', | 111 | 'pages/rdoc', |
| 112 | 'pages/react', | ||
| 112 | 'pages/react_native', | 113 | 'pages/react_native', |
| 113 | 'pages/reactivex', | 114 | 'pages/reactivex', |
| 114 | 'pages/redis', | 115 | 'pages/redis', |
| @@ -0,0 +1,24 @@ | |||
| 1 | ._react { | ||
| 2 | @extend %simple; | ||
| 3 | |||
| 4 | .note { | ||
| 5 | @extend %note; | ||
| 6 | h4 { | ||
| 7 | margin-top: .25rem; | ||
| 8 | margin-bottom: .5rem; | ||
| 9 | } | ||
| 10 | } | ||
| 11 | |||
| 12 | .note-orange { | ||
| 13 | @extend %note-orange; | ||
| 14 | } | ||
| 15 | |||
| 16 | .note-blue { | ||
| 17 | @extend %note-blue; | ||
| 18 | } | ||
| 19 | |||
| 20 | .note-green { | ||
| 21 | @extend %note-green; | ||
| 22 | } | ||
| 23 | |||
| 24 | } | ||
| @@ -13,7 +13,7 @@ Adding a documentation may look like a daunting task but once you get the hang o · 12 unmodified lines | |||
| 13 | 6. Generate the full documentation using the `thor docs:generate [my_doc] --force` command. Additionally, you can use the `--verbose` option to see which files are being created/updated/deleted (useful to see what changed since the last run), and the `--debug` option to see which URLs are being requested and added to the queue (useful to pin down which page adds unwanted URLs to the queue). | 13 | 6. Generate the full documentation using the `thor docs:generate [my_doc] --force` command. Additionally, you can use the `--verbose` option to see which files are being created/updated/deleted (useful to see what changed since the last run), and the `--debug` option to see which URLs are being requested and added to the queue (useful to pin down which page adds unwanted URLs to the queue). |
| 14 | 7. Start the server, open the app, enable the documentation, and see how everything plays out. | 14 | 7. Start the server, open the app, enable the documentation, and see how everything plays out. |
| 15 | 8. Tweak the scraper/filters and repeat 5) and 6) until the pages and metadata are ok. | 15 | 8. Tweak the scraper/filters and repeat 5) and 6) until the pages and metadata are ok. |
| 16 | 9. To customize the pages' styling, create an SCSS file in the `assets/stylesheets/pages/` directory and import it in both `application.css.scss` AND `application-dark.css.scss`. Both the file and CSS class should be named `_[type]` where [type] is equal to the scraper's `type` attribute (documentations with the same type share the same custom CSS and JS). Setting the type to `simple` will apply the general styling rules in `assets/stylesheets/pages/_simple.scss`, which can be used for documentations where little to no CSS changes are needed. | 16 | 9. To customize the pages' styling, create an SCSS file in the `assets/stylesheets/pages/` directory and import it in `application.css.scss`. Both the file and CSS class should be named `_[type]` where [type] is equal to the scraper's `type` attribute (documentations with the same type share the same custom CSS and JS). Setting the type to `simple` will apply the general styling rules in `assets/stylesheets/pages/_simple.scss`, which can be used for documentations where little to no CSS changes are needed. |
| 17 | 10. To add syntax highlighting or execute custom JavaScript on the pages, create a file in the `assets/javascripts/views/pages/` directory (take a look at the other files to see how it works). | 17 | 10. To add syntax highlighting or execute custom JavaScript on the pages, create a file in the `assets/javascripts/views/pages/` directory (take a look at the other files to see how it works). |
| 18 | 11. Add the documentation's icon in the `public/icons/docs/[my_doc]/` directory, in both 16x16 and 32x32-pixels formats. The icon spritesheet is automatically generated when you (re)start your local DevDocs instance. | 18 | 11. Add the documentation's icon in the `public/icons/docs/[my_doc]/` directory, in both 16x16 and 32x32-pixels formats. The icon spritesheet is automatically generated when you (re)start your local DevDocs instance. |
| 19 | 12. Add the documentation's copyright details to `options[:attribution]`. This is the data shown in the table on the [about](https://devdocs.io/about) page, and is ordered alphabetically. Please see an existing scraper for the typesetting. | 19 | 12. Add the documentation's copyright details to `options[:attribution]`. This is the data shown in the table on the [about](https://devdocs.io/about) page, and is ordered alphabetically. Please see an existing scraper for the typesetting. |
| @@ -0,0 +1,77 @@ | |||
| 1 | module Docs | ||
| 2 | class React | ||
| 3 | class CleanHtmlReactDevFilter < Filter | ||
| 4 | def call | ||
| 5 | @doc = at_css('article') | ||
| 6 | |||
| 7 | # Remove breadcrumbs before h1 | ||
| 8 | css('h1').each do |node| | ||
| 9 | if node.previous | ||
| 10 | node.previous.remove | ||
| 11 | end | ||
| 12 | end | ||
| 13 | |||
| 14 | remove_selectors = [ | ||
| 15 | 'div.grid > a', # prev-next links | ||
| 16 | 'button', # "show more" etc. buttons | ||
| 17 | 'div.order-last', # code iframe containers | ||
| 18 | 'div.dark-image', # dark images | ||
| 19 | 'a[title="Open in CodeSandbox"]', # codesandbox links | ||
| 20 | ] | ||
| 21 | css(*remove_selectors).each do |node| | ||
| 22 | node.remove | ||
| 23 | end | ||
| 24 | |||
| 25 | # Fix images not loading | ||
| 26 | css('img').remove_attr('srcset') | ||
| 27 | |||
| 28 | # Remove recipe blocks - TODO transform to outgoing link to docs | ||
| 29 | css('h4[id^="examples-"]').each do |node| | ||
| 30 | node.parent.parent.parent.remove | ||
| 31 | end | ||
| 32 | |||
| 33 | # Transform callout blocks | ||
| 34 | class_transform = { | ||
| 35 | '.expandable-callout[class*=yellow]' => 'note note-orange', # pitfalls, experimental | ||
| 36 | '.expandable-callout[class*=green]' => 'note note-green', # note | ||
| 37 | '.expandable-callout[class*=gray]' => 'note', # canary | ||
| 38 | '.bg-card' => 'note', # you will learn | ||
| 39 | 'details' => 'note note-blue' # deep dive | ||
| 40 | } | ||
| 41 | |||
| 42 | class_transform.each do |old_class, new_class| | ||
| 43 | css(old_class).each do |node| | ||
| 44 | node.set_attribute('class', new_class) | ||
| 45 | end | ||
| 46 | end | ||
| 47 | |||
| 48 | # Transform h3 to h4 inside callouts | ||
| 49 | css('.note h3', '.note h2').each do |node| | ||
| 50 | new_node = Nokogiri::XML::Node.new('h4', @doc) | ||
| 51 | new_node.content = node.content | ||
| 52 | node.replace(new_node) | ||
| 53 | end | ||
| 54 | |||
| 55 | # Remove styling divs while lifting children | ||
| 56 | styling_prefixes = %w[ps- mx- my- px- py- mb- sp- rounded-] | ||
| 57 | selectors = styling_prefixes.map { |prefix| "div[class*=\"#{prefix}\"]:not(.note)" } | ||
| 58 | css(*selectors, 'div[class=""]', 'div.cm-line').each do |node| | ||
| 59 | node.before(node.children).remove | ||
| 60 | end | ||
| 61 | |||
| 62 | # Syntax highlighting | ||
| 63 | css('pre br').each do |node| | ||
| 64 | node.replace("\n") | ||
| 65 | end | ||
| 66 | css('pre').each do |node| | ||
| 67 | node['data-language'] = 'jsx' | ||
| 68 | end | ||
| 69 | |||
| 70 | # Remove styling except for callouts and images | ||
| 71 | css('*:not([class*=image]):not(.note)').remove_attr('class').remove_attr('style') | ||
| 72 | |||
| 73 | doc | ||
| 74 | end | ||
| 75 | end | ||
| 76 | end | ||
| 77 | end | ||
| @@ -0,0 +1,32 @@ | |||
| 1 | module Docs | ||
| 2 | class React | ||
| 3 | class EntriesReactDevFilter < Docs::EntriesFilter | ||
| 4 | def get_name | ||
| 5 | name = at_css('article h1')&.content | ||
| 6 | |||
| 7 | update_canary_copy(name) | ||
| 8 | end | ||
| 9 | |||
| 10 | def get_type | ||
| 11 | # Category is the opened category in the sidebar | ||
| 12 | category = css('a:has(> span.text-link) > div').first&.content | ||
| 13 | # The grey category in the sidebar | ||
| 14 | top_category = css('h3:has(~ li a.text-link)') | ||
| 15 | .last&.content | ||
| 16 | &.sub(/@.*$/, '') # remove version tag | ||
| 17 | &.sub(/^./, &:upcase) # capitalize first letter | ||
| 18 | &.concat(": ") | ||
| 19 | is_learn_page = path.start_with?('learn/') || slug == 'learn' | ||
| 20 | prefix = is_learn_page ? 'Learn: ' : top_category || '' | ||
| 21 | |||
| 22 | update_canary_copy(prefix + (category || 'Miscellaneous')) | ||
| 23 | end | ||
| 24 | |||
| 25 | def update_canary_copy(string) | ||
| 26 | canary_copy = '- This feature is available in the latest Canary' | ||
| 27 | |||
| 28 | string.sub(canary_copy, ' (Canary)') | ||
| 29 | end | ||
| 30 | end | ||
| 31 | end | ||
| 32 | end | ||
| @@ -1,38 +1,59 @@ | |||
| 1 | module Docs | 1 | module Docs |
| 2 | class React < UrlScraper | 2 | class React < UrlScraper |
| 3 | |||
| 3 | self.name = 'React' | 4 | self.name = 'React' |
| 4 | self.type = 'simple' | 5 | self.type = 'react' |
| 5 | self.release = '18.2.0' | ||
| 6 | self.base_url = 'https://reactjs.org/docs/' | ||
| 7 | self.root_path = 'hello-world.html' | ||
| 8 | self.links = { | 6 | self.links = { |
| 9 | home: 'https://reactjs.org/', | 7 | home: 'https://react.dev/', |
| 10 | code: 'https://github.com/facebook/react' | 8 | code: 'https://github.com/facebook/react' |
| 11 | } | 9 | } |
| 12 | 10 | ||
| 13 | html_filters.push 'react/entries', 'react/clean_html' | ||
| 14 | |||
| 15 | options[:skip] = %w( | ||
| 16 | codebase-overview.html | ||
| 17 | design-principles.html | ||
| 18 | how-to-contribute.html | ||
| 19 | implementation-notes.html | ||
| 20 | ) | ||
| 21 | |||
| 22 | options[:replace_paths] = { | ||
| 23 | 'more-about-refs.html' => 'refs-and-the-dom.html', | ||
| 24 | 'interactivity-and-dynamic-uis.html' => 'state-and-lifecycle.html', | ||
| 25 | 'working-with-the-browser.html' => 'refs-and-the-dom.html', | ||
| 26 | 'top-level-api.html' => 'react-api.html', | ||
| 27 | } | ||
| 28 | |||
| 29 | options[:attribution] = <<-HTML | 11 | options[:attribution] = <<-HTML |
| 30 | © 2013–present Facebook Inc.<br> | 12 | © 2013–present Facebook Inc.<br> |
| 31 | Licensed under the Creative Commons Attribution 4.0 International Public License. | 13 | Licensed under the Creative Commons Attribution 4.0 International Public License. |
| 32 | HTML | 14 | HTML |
| 33 | 15 | ||
| 16 | version do | ||
| 17 | self.release = '19' | ||
| 18 | self.base_url = 'https://react.dev' | ||
| 19 | self.initial_paths = %w(/reference/react /learn) | ||
| 20 | html_filters.push 'react/entries_react_dev', 'react/clean_html_react_dev' | ||
| 21 | |||
| 22 | options[:only_patterns] = [/\A\/learn/, /\A\/reference/] | ||
| 23 | end | ||
| 24 | |||
| 25 | version '18' do | ||
| 26 | self.release = '18.3.1' | ||
| 27 | self.base_url = 'https://18.react.dev' | ||
| 28 | self.initial_paths = %w(/reference/react /learn) | ||
| 29 | html_filters.push 'react/entries_react_dev', 'react/clean_html_react_dev' | ||
| 30 | |||
| 31 | options[:only_patterns] = [/\A\/learn/, /\A\/reference/] | ||
| 32 | end | ||
| 33 | |||
| 34 | version '17' do | ||
| 35 | self.release = '17.0.2' | ||
| 36 | self.base_url = 'https://17.reactjs.org/docs/' | ||
| 37 | self.root_path = 'hello-world.html' | ||
| 38 | html_filters.push 'react/entries', 'react/clean_html' | ||
| 39 | |||
| 40 | options[:skip] = %w( | ||
| 41 | codebase-overview.html | ||
| 42 | design-principles.html | ||
| 43 | how-to-contribute.html | ||
| 44 | implementation-notes.html | ||
| 45 | ) | ||
| 46 | |||
| 47 | options[:replace_paths] = { | ||
| 48 | 'more-about-refs.html' => 'refs-and-the-dom.html', | ||
| 49 | 'interactivity-and-dynamic-uis.html' => 'state-and-lifecycle.html', | ||
| 50 | 'working-with-the-browser.html' => 'refs-and-the-dom.html', | ||
| 51 | 'top-level-api.html' => 'react-api.html', | ||
| 52 | } | ||
| 53 | end | ||
| 54 | |||
| 34 | def get_latest_version(opts) | 55 | def get_latest_version(opts) |
| 35 | doc = fetch_doc('https://reactjs.org/docs/getting-started.html', opts) | 56 | doc = fetch_doc('https://react.dev/', opts) |
| 36 | doc.at_css('a[href="/versions"]').content.strip[1..-1] | 57 | doc.at_css('a[href="/versions"]').content.strip[1..-1] |
| 37 | end | 58 | end |
| 38 | end | 59 | end |
Binary file not shown.
Binary file not shown.
| @@ -1,2 +1,2 @@ | |||
| 1 | https://es.m.wikipedia.org/wiki/React#/media/Archivo%3AReact.svg | 1 | https://github.com/reactjs/react.dev/blob/master/public/favicon-16x16.png |
| 2 | https://github.com/facebook/react/blob/master/docs/img/logo.svg | 2 | https://github.com/reactjs/react.dev/blob/master/public/favicon-32x32.png |