From 2f0ad7c09f9a1b238017611aee0a47ed640134c7 Mon Sep 17 00:00:00 2001 From: Chaitanya Rahalkar Date: Mon, 23 Dec 2024 22:44:04 -0600 Subject: [PATCH 01/13] Add documentation and support for three.js --- assets/stylesheets/pages/_threejs.scss | 56 ++++ docs/file-scrapers.md | 8 + lib/docs/filters/threejs/clean_html.rb | 348 +++++++++++++++++++++++++ lib/docs/filters/threejs/entries.rb | 54 ++++ lib/docs/scrapers/threejs.rb | 85 ++++++ 5 files changed, 551 insertions(+) create mode 100644 assets/stylesheets/pages/_threejs.scss create mode 100644 lib/docs/filters/threejs/clean_html.rb create mode 100644 lib/docs/filters/threejs/entries.rb create mode 100644 lib/docs/scrapers/threejs.rb diff --git a/assets/stylesheets/pages/_threejs.scss b/assets/stylesheets/pages/_threejs.scss new file mode 100644 index 0000000000..32b39ce12f --- /dev/null +++ b/assets/stylesheets/pages/_threejs.scss @@ -0,0 +1,56 @@ +._threejs { + // Code blocks + pre, code { + background-color: #f5f5f5; + border-radius: 3px; + padding: 0.2em 0.4em; + } + + pre { + padding: 1em; + margin: 1em 0; + overflow: auto; + + code { + background: none; + padding: 0; + } + } + + // Links + a { + color: #049EF4; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + } + + // Headings + h2 { + margin-top: 2em; + padding-bottom: 0.3em; + border-bottom: 1px solid #eaecef; + } + + h3 { + margin-top: 1.5em; + } + + // Tables + table { + border-collapse: collapse; + margin: 1em 0; + width: 100%; + } + + th, td { + border: 1px solid #dfe2e5; + padding: 6px 13px; + } + + tr:nth-child(2n) { + background-color: #f6f8fa; + } +} \ No newline at end of file diff --git a/docs/file-scrapers.md b/docs/file-scrapers.md index 2f8fd8f38e..cdfed33755 100644 --- a/docs/file-scrapers.md +++ b/docs/file-scrapers.md @@ -289,3 +289,11 @@ it to `docs/sqlite` ```sh curl https://sqlite.org/2022/sqlite-doc-3400000.zip | bsdtar --extract --file - --directory=docs/sqlite/ --strip-components=1 ``` + +## Three.js + +```sh +git clone --depth 1 --branch r${VERSION} https://github.com/mrdoob/three.js.git +mv three.js/docs/ docs/threejs~${VERSION}/ +rm -rf three.js/ +``` diff --git a/lib/docs/filters/threejs/clean_html.rb b/lib/docs/filters/threejs/clean_html.rb new file mode 100644 index 0000000000..5a15b7b95d --- /dev/null +++ b/lib/docs/filters/threejs/clean_html.rb @@ -0,0 +1,348 @@ +module Docs + class Threejs + class CleanHtmlFilter < Filter + def call + # Remove unnecessary elements + css('head, script, style').remove + + # Add syntax highlighting CSS + style = doc.document.create_element('style') + style.content = <<-CSS + .highlight { background: #272b30; color: #e9ecef; border-radius: 4px; margin: 1em 0; } + .highlight pre { margin: 0; padding: 10px; } + .highlight .k { color: #cc7832; font-weight: bold; } /* Keyword */ + .highlight .kd { color: #cc7832; font-weight: bold; } /* Keyword.Declaration */ + .highlight .nb { color: #6897bb; } /* Name.Builtin */ + .highlight .nx { color: #ffc66d; } /* Name.Other */ + .highlight .nf { color: #ffc66d; } /* Name.Function */ + .highlight .mi { color: #6897bb; } /* Literal.Number.Integer */ + .highlight .s1 { color: #6a8759; } /* Literal.String.Single */ + .highlight .s2 { color: #6a8759; } /* Literal.String.Double */ + .highlight .c1 { color: #808080; font-style: italic; } /* Comment.Single */ + .highlight .lineno { color: #606366; margin-right: 10px; -webkit-user-select: none; user-select: none; } + .highlight-javascript { padding: 0; } + + /* Method signatures */ + .sig { padding: 5px 10px; } + .sig-name { color: #ffc66d; } + .sig-param { color: #e9ecef; } + .sig-param .sig-type { color: #6897bb; } + .sig-returns { color: #cc7832; } + .sig-returns .sig-type { color: #6897bb; } + .sig-paren { color: #e9ecef; } + .property .pre { color: #cc7832; } + + /* Inline code */ + code.literal { background: #2b2b2b; padding: 2px 4px; border-radius: 3px; } + code.literal .pre { color: #e9ecef; } + + /* Links */ + .reference { color: #6897bb; text-decoration: none; } + .reference:hover { text-decoration: underline; } + .reference.external { color: #6a8759; } + + /* Notes */ + .admonition.note { background: #2b2b2b; padding: 12px 15px; border-left: 4px solid #6897bb; margin: 1em 0; } + .admonition-title { color: #6897bb; font-weight: bold; margin: 0 0 5px 0; } + CSS + doc.at_css('head') ? doc.at_css('head').add_child(style) : doc.add_child(style) + + # Create a wrapper div for better styling + if root = at_css('body') + content = root.inner_html + else + content = doc.inner_html + end + + # Create Django-like structure + content = <<-HTML +
+
+
+
+ #{content} +
+
+
+
+ HTML + + doc.inner_html = content + + # Handle source links + css('h2').each do |node| + if node.content.strip == 'Source' + content = node.next_element&.inner_html + if content + # Clean up any existing formatting + content = content.gsub(/<[^>]+>/, '') + # Extract the path from the content + if content =~ /src\/(.*?)\.js/ + path = "/#{$1}.js" + formatted_link = %Q(src#{path}) + node.next_element.inner_html = formatted_link if node.next_element + end + end + end + end + + # Handle method signatures + css('h3').each do |node| + content = node.inner_html + + # Handle [method:this methodName]( param1, param2, ... ) format + content = content.gsub(/\[method:this\s+([^\]]+)\]\s*\((.*?)\)/) do |match| + method_name, params_str = $1, $2 + + # Format parameters + params = params_str.split(',').map do |param| + param = param.strip + if param.include?(' ') + type, name = param.split(' ', 2).map(&:strip) + "#{type} #{name}" + else + "#{param}" + end + end.join(", ") + + "
" \ + "this." \ + "#{method_name}" \ + "(" \ + "#{params}" \ + ")
" + end + + # Handle [method:returnType methodName]( param1, param2, ... ) format + content = content.gsub(/\[method:([^\s\]]+)\s+([^\]]+)\]\s*\((.*?)\)/) do |match| + return_type, method_name, params_str = $1, $2, $3 + next if method_name.start_with?('this') # Skip if already handled above + + # Format parameters + params = params_str.split(',').map do |param| + param = param.strip + if param.include?(' ') + type, name = param.split(' ', 2).map(&:strip) + "#{type} #{name}" + else + "#{param}" + end + end.join(", ") + + "
" \ + "#{method_name}" \ + "(" \ + "#{params}" \ + ")" \ + ": " \ + "#{return_type}
" + end + + # Handle [method:returnType methodName] format (no parameters) + content = content.gsub(/\[method:([^\s\]]+)\s+([^\]]+)\](?!\()/) do |match| + return_type, method_name = $1, $2 + "
" \ + "#{method_name}" \ + "(" \ + ")" \ + ": " \ + "#{return_type}
" + end + + node.inner_html = content + end + + # Handle [name] placeholders in headers and constructor + css('h1, h3').each do |node| + content = node.inner_html + + # Replace [name] with class name + content = content.gsub(/\[name\]/) do + name = slug.split('/').last.gsub('.html', '') + "#{name}" + end + + # Format constructor parameters + content = content.gsub(/\[param:([^\]]+?)\s+([^\]]+?)\]/) do |match| + type, name = $1, $2 + "#{type} #{name}" + end + + node.inner_html = content + end + + # Clean up property formatting + css('h3').each do |node| + node.inner_html = node.inner_html.gsub(/\[property:([^\]]+?)\s+([^\]]+?)\]/) do |match| + type, name = $1, $2 + "
" \ + "#{name}" \ + ": " \ + "#{type}
" + end + end + + # Clean up external links + css('*').each do |node| + next if node.text? + + # Handle example links [example:tag Title] + node.inner_html = node.inner_html.gsub(/\[example:([^\s\]]+)\s+([^\]]+)\]/) do |match| + tag, title = $1, $2 + "#{title}" + end + + # Handle external links with [link:url text] format + node.inner_html = node.inner_html.gsub(/\[link:([^\s\]]+)\s+([^\]]+)\]/) do |match| + url, text = $1, $2 + "#{text}" + end + + # Handle external links with [link:url] format + node.inner_html = node.inner_html.gsub(/\[link:([^\]]+)\]/) do |match| + url = $1 + "#{url}" + end + + # Handle internal page links with text + node.inner_html = node.inner_html.gsub(/\[page:([^\]]+?)\s+([^\]]+?)\]/) do + path, text = $1, $2 + "#{text}" + end + + # Handle internal page links without text + node.inner_html = node.inner_html.gsub(/\[page:([^\]]+?)\]/) do |match| + path = $1 + "#{path}" + end + end + + # Fix all href attributes to be lowercase and remove .html + css('a[href]').each do |link| + next if link['href'].start_with?('http') + link['href'] = link['href'].remove('../').downcase.sub(/\.html$/, '') + link['class'] = 'reference internal' + end + + # Add section classes + css('h2').each do |node| + node['class'] = 'section-title' + section = node.next_element + if section + wrapper = doc.document.create_element('div') + wrapper['class'] = 'section' + node.after(wrapper) + wrapper.add_child(node) + current = section + while current && current.name != 'h2' + next_el = current.next + wrapper.add_child(current) + current = next_el + end + end + end + + # Format description paragraphs + css('p.desc').each do |node| + node['class'] = 'section-desc' + end + + # Handle inline code/backticks in text + css('p, li, dt, dd').each do |node| + next if node.at_css('pre') # Skip if contains a code block + + # Replace backticks with proper code formatting + node.inner_html = node.inner_html.gsub(/`([^`]+)`/) do |match| + code = $1 + "#{code}" + end + end + + # Handle inline code in property descriptions + css('.property-type').each do |node| + node.inner_html = node.inner_html.gsub(/`([^`]+)`/) do |match| + code = $1 + "#{code}" + end + end + + # Clean up code blocks + css('pre').each do |node| + wrapper = doc.document.create_element('div') + wrapper['class'] = 'highlight' + node.replace(wrapper) + + div = doc.document.create_element('div') + div['class'] = 'highlight-javascript notranslate' + wrapper.add_child(div) + + pre = doc.document.create_element('pre') + pre['class'] = '' + div.add_child(pre) + + # Format the code content + code = node.content.strip + + # Add syntax highlighting spans + highlighted_code = highlight_javascript(code) + + pre.inner_html = highlighted_code + end + + # Add proper heading IDs and classes + css('h1, h2, h3, h4').each do |node| + node['id'] ||= node.content.strip.downcase.gsub(/[^\w]+/, '-') + existing_class = node['class'].to_s + node['class'] = "#{existing_class} section-header" + end + + # Remove interactive examples + css('.threejs_example_container').remove + + # Add note styling + css('p').each do |node| + if node.content.start_with?('Note:') + wrapper = doc.document.create_element('div') + wrapper['class'] = 'admonition note' + + title = doc.document.create_element('p') + title['class'] = 'first admonition-title' + title.content = 'Note' + + content = doc.document.create_element('p') + content['class'] = 'last' + content.inner_html = node.inner_html.sub('Note:', '').strip + + wrapper.add_child(title) + wrapper.add_child(content) + node.replace(wrapper) + end + end + + doc + end + + private + + def highlight_javascript(code) + code = code.gsub(/\b(function|return|var|let|const|if|else|for|while|do|switch|case|break|continue|new|try|catch|throw|this|typeof|instanceof|in|of|class|extends|super|import|export|default|null|undefined|true|false)\b/, '\1') # keywords + code = code.gsub(/\b(\d+(\.\d+)?)\b/, '\1') # numbers + code = code.gsub(/'([^']*)'/, '\'\1\'') # single quotes + code = code.gsub(/"([^"]*)"/, '"\1"') # double quotes + code = code.gsub(/`([^`]*)`/, '`\1`') # template literals + code = code.gsub(/\/\/[^\n]*/, '\0') # single line comments + code = code.gsub(/\b(console|document|window|Array|Object|String|Number|Boolean|Function|Symbol|Map|Set|Promise|async|await)\b/, '\1') # built-ins + code = code.gsub(/([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/, '\1(') # function calls + code = code.gsub(/\b(addEventListener|querySelector|getElementById|setTimeout|setInterval)\b/, '\1') # common methods + + # Add line numbers + lines = code.split("\n") + numbered_lines = lines.map.with_index(1) do |line, i| + "#{i}#{line}" + end + + numbered_lines.join("\n") + end + end + end +end \ No newline at end of file diff --git a/lib/docs/filters/threejs/entries.rb b/lib/docs/filters/threejs/entries.rb new file mode 100644 index 0000000000..fa14628eb4 --- /dev/null +++ b/lib/docs/filters/threejs/entries.rb @@ -0,0 +1,54 @@ +module Docs + class Threejs + class EntriesFilter < Docs::EntriesFilter + def get_name + # Try to get name from the title first + if title = at_css('.lesson-title h1')&.content + title + else + # Fallback to path-based name for API docs + slug.split('/').last.gsub('.html', '').titleize + end + end + + def get_type + if slug.start_with?('api/en/') + # For API documentation, use the section as type + # e.g. "api/en/animation/AnimationAction" -> "Animation" + path_parts = slug.split('/') + if path_parts.length >= 3 + path_parts[2].titleize + else + 'API' + end + elsif slug.start_with?('manual/en/') + # For manual pages, get the section from the path + # e.g. "manual/en/introduction/Creating-a-scene" -> "Introduction" + path_parts = slug.split('/') + if path_parts.length >= 3 + path_parts[2].titleize + else + 'Manual' + end + else + 'Other' + end + end + + def additional_entries + entries = [] + + # Get all methods and properties from h3 headings + css('h3').each do |node| + name = node.content.strip + # Skip if it's a constructor or doesn't have an ID + next if name == get_name || !node['id'] + + entries << [name, node['id'], get_type] + end + + entries + end + end + end +end \ No newline at end of file diff --git a/lib/docs/scrapers/threejs.rb b/lib/docs/scrapers/threejs.rb new file mode 100644 index 0000000000..9f6a27cc9d --- /dev/null +++ b/lib/docs/scrapers/threejs.rb @@ -0,0 +1,85 @@ +module Docs + class Threejs < FileScraper + self.name = 'Three.js' + self.type = 'threejs' + self.slug = 'threejs' + self.links = { + home: 'https://threejs.org/', + code: 'https://github.com/mrdoob/three.js' + } + + html_filters.push 'threejs/entries', 'threejs/clean_html' + + # The content is directly in the body + options[:container] = 'body' + + options[:skip] = %w( + prettify.js + lesson.js + lang.css + lesson.css + editor.html + list.js + page.js + ) + + options[:only_patterns] = [ + /\Aapi\/en\/.+\.html/, # API documentation + /\Amanual\/en\/.+\.html/ # Manual pages + ] + + options[:skip_patterns] = [ + /examples/, + /\A_/, + /\Aresources\//, + /\Ascenes\// + ] + + options[:attribution] = <<-HTML + © 2010–#{Time.current.year} Three.js Authors
+ Licensed under the MIT License. + HTML + + self.class_attribute :release + + version '160' do + self.release = '160' + self.base_url = "https://threejs.org/docs" + end + + def get_latest_version(opts) + get_latest_github_release('mrdoob', 'three.js', opts) + end + + def initial_paths + paths = [] + json_path = File.expand_path("docs/threejs~#{self.release}/list.json") + json_content = File.read(json_path) + json_data = JSON.parse(json_content) + + # Process both API and manual sections + process_documentation(json_data['en'], paths) + paths + end + + private + + def process_documentation(data, paths, prefix = '') + data.each do |category, items| + if items.is_a?(Hash) + if items.values.first.is_a?(String) + # This is a leaf node with actual pages + items.each do |name, path| + paths << "#{path}.html" + end + else + # This is a category with subcategories + items.each do |subcategory, subitems| + process_documentation(items, paths, "#{prefix}#{category}/") + end + end + end + end + end + end +end \ No newline at end of file From e08baefb529f229596fa75e1e002ec30049b42f1 Mon Sep 17 00:00:00 2001 From: Chaitanya Rahalkar Date: Mon, 23 Dec 2024 22:51:31 -0600 Subject: [PATCH 02/13] Add logos --- public/icons/docs/threejs/16.png | Bin 0 -> 428 bytes public/icons/docs/threejs/16@2x.png | Bin 0 -> 986 bytes public/icons/docs/threejs/SOURCE | 1 + 3 files changed, 1 insertion(+) create mode 100644 public/icons/docs/threejs/16.png create mode 100644 public/icons/docs/threejs/16@2x.png create mode 100644 public/icons/docs/threejs/SOURCE diff --git a/public/icons/docs/threejs/16.png b/public/icons/docs/threejs/16.png new file mode 100644 index 0000000000000000000000000000000000000000..dd410d87321970ebfe066a22ae1ab5ccc806ae4d GIT binary patch literal 428 zcmV;d0aN~oP)F*v2A;@dtxA$4=IG?HBlr=h(y)zG1HPouZ8vHZ${YPoO`8Ata_ThFPrP47;WG z5@Qju5D~Ad0$*{A?`ReqGkA-6Y@mxDh5L2KLa{N2XIRBY?3YQp#l{4FX68zdX;d00004P)5#vL75lb2u4^zQ5Z>-+jQ~F#=Fb)I=#8~XYyP5gJh#6$&fCmrY;?l=r11`b3nj3{4 zEW?X<9dpn%*j6XcPzm=5=0(Ifti@BAxflB)Vsd8oRdhBM!NWKgDmuU3dbJxfB4QF&U~y*t zjP00J-}a#o<1|UTUbB5`s7)XttJs)KzECcg)QG-UF5nuA<)&zw2Zw{ zAPXu_TBGwd-fJ~pHddE@4OSYWQU>&amTmbvBDx_WdTGLrS_v7x&TwL#GY5K`kIFy-> z90{Zyft`2_OEmRfmxM8tGW zvaKEtye)x}{Sh%KGxyi{X1tG|@G$1#iE7)2a2wvp%nhA@_j`K8N0UqoN?(dQO7B%Y zpk?iHEIr!8Xuy47uv96oDv$SO=36yC7ZWmbQ;mDECo|vf*z=OM*RLwQX}DBV=l!xB zS41Pr@!7F}qkRM*A|Au%nj6v-{DzNlD}Kj2nYsB`z|lSjirj46-ZDN-lZ?AD`)K!k z*yDHz*`c`$^vj>P0rzI+wqy3ZWVkX^jb#kf{cyGBkl8a*a611n`92~p)Eu{~ju$wF z&w<+aIoOKHBi-|(>I3~!e@ka%=C8-i^M2c%5IB)?(tl3>0Z<9%{yPcm{Qv*}07*qo IM6N<$f{i23vj6}9 literal 0 HcmV?d00001 diff --git a/public/icons/docs/threejs/SOURCE b/public/icons/docs/threejs/SOURCE new file mode 100644 index 0000000000..01efe7e30f --- /dev/null +++ b/public/icons/docs/threejs/SOURCE @@ -0,0 +1 @@ +https://github.com/mrdoob/three.js/tree/dev/files \ No newline at end of file From 71729cfa4d1b24fe8260d87c7b6fca108095cb2d Mon Sep 17 00:00:00 2001 From: Chaitanya Rahalkar Date: Mon, 23 Dec 2024 23:13:30 -0600 Subject: [PATCH 03/13] Updated instructions for downloading the documentation --- assets/stylesheets/pages/_threejs.scss | 56 -------------------------- docs/file-scrapers.md | 11 +++-- 2 files changed, 8 insertions(+), 59 deletions(-) delete mode 100644 assets/stylesheets/pages/_threejs.scss diff --git a/assets/stylesheets/pages/_threejs.scss b/assets/stylesheets/pages/_threejs.scss deleted file mode 100644 index 32b39ce12f..0000000000 --- a/assets/stylesheets/pages/_threejs.scss +++ /dev/null @@ -1,56 +0,0 @@ -._threejs { - // Code blocks - pre, code { - background-color: #f5f5f5; - border-radius: 3px; - padding: 0.2em 0.4em; - } - - pre { - padding: 1em; - margin: 1em 0; - overflow: auto; - - code { - background: none; - padding: 0; - } - } - - // Links - a { - color: #049EF4; - text-decoration: none; - - &:hover { - text-decoration: underline; - } - } - - // Headings - h2 { - margin-top: 2em; - padding-bottom: 0.3em; - border-bottom: 1px solid #eaecef; - } - - h3 { - margin-top: 1.5em; - } - - // Tables - table { - border-collapse: collapse; - margin: 1em 0; - width: 100%; - } - - th, td { - border: 1px solid #dfe2e5; - padding: 6px 13px; - } - - tr:nth-child(2n) { - background-color: #f6f8fa; - } -} \ No newline at end of file diff --git a/docs/file-scrapers.md b/docs/file-scrapers.md index cdfed33755..164b6f7d9d 100644 --- a/docs/file-scrapers.md +++ b/docs/file-scrapers.md @@ -291,9 +291,14 @@ curl https://sqlite.org/2022/sqlite-doc-3400000.zip | bsdtar --extract --file - ``` ## Three.js +Download the docs from https://github.com/mrdoob/three.js/tree/dev/files or run the following commands in your terminal: +Make sure to set the version per the release tag (e.g. r160). Note that the r prefix is already included, only the version number is needed. ```sh -git clone --depth 1 --branch r${VERSION} https://github.com/mrdoob/three.js.git -mv three.js/docs/ docs/threejs~${VERSION}/ -rm -rf three.js/ +curl https://codeload.github.com/mrdoob/three.js/tar.gz/refs/tags/r${VERSION} > threejs.tar.gz +tar -xzf threejs.tar.gz +mkdir -p docs/threejs~${VERSION} +mv three.js-r${VERSION}/docs/* docs/threejs~${VERSION}/ +rm -rf three.js-r${VERSION}/ +rm threejs.tar.gz ``` From 1a1973580c31d4c447f5d380e060f487a19cc2bf Mon Sep 17 00:00:00 2001 From: Chaitanya Rahalkar Date: Mon, 23 Dec 2024 23:23:25 -0600 Subject: [PATCH 04/13] add page to the styling --- assets/stylesheets/application.css.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/stylesheets/application.css.scss b/assets/stylesheets/application.css.scss index 3823cdc3d8..d2887ba994 100644 --- a/assets/stylesheets/application.css.scss +++ b/assets/stylesheets/application.css.scss @@ -131,6 +131,7 @@ 'pages/tcl_tk', 'pages/tensorflow', 'pages/terraform', + 'pages/threejs', 'pages/typescript', 'pages/underscore', 'pages/vue', From 58d3d7de0a5bb4b33d3011f5dd9a701861a5c66c Mon Sep 17 00:00:00 2001 From: Chaitanya Rahalkar Date: Mon, 23 Dec 2024 23:26:23 -0600 Subject: [PATCH 05/13] add styling --- assets/stylesheets/pages/_threejs.scss | 47 ++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 assets/stylesheets/pages/_threejs.scss diff --git a/assets/stylesheets/pages/_threejs.scss b/assets/stylesheets/pages/_threejs.scss new file mode 100644 index 0000000000..8996ba0bf9 --- /dev/null +++ b/assets/stylesheets/pages/_threejs.scss @@ -0,0 +1,47 @@ +._threejs { + // Code blocks + pre, code { + background-color: #f5f5f5; + border-radius: 3px; + padding: 0.2em 0.4em; + } + pre { + padding: 1em; + margin: 1em 0; + overflow: auto; + code { + background: none; + padding: 0; + } + } + // Links + a { + color: #049EF4; + text-decoration: none; + &:hover { + text-decoration: underline; + } + } + // Headings + h2 { + margin-top: 2em; + padding-bottom: 0.3em; + border-bottom: 1px solid #eaecef; + } + h3 { + margin-top: 1.5em; + } + // Tables + table { + border-collapse: collapse; + margin: 1em 0; + width: 100%; + } + th, td { + border: 1px solid #dfe2e5; + padding: 6px 13px; + } + tr:nth-child(2n) { + background-color: #f6f8fa; + } + } \ No newline at end of file From 15fcdc22bb201c8ff5f9560ca8fb14eaae3fe57f Mon Sep 17 00:00:00 2001 From: Chaitanya Rahalkar Date: Tue, 24 Dec 2024 11:16:59 -0600 Subject: [PATCH 06/13] switched to the simple styling option --- lib/docs/filters/threejs/clean_html.rb | 70 ++------------------------ lib/docs/scrapers/threejs.rb | 2 +- 2 files changed, 6 insertions(+), 66 deletions(-) diff --git a/lib/docs/filters/threejs/clean_html.rb b/lib/docs/filters/threejs/clean_html.rb index 5a15b7b95d..b66bc729d9 100644 --- a/lib/docs/filters/threejs/clean_html.rb +++ b/lib/docs/filters/threejs/clean_html.rb @@ -4,71 +4,7 @@ class CleanHtmlFilter < Filter def call # Remove unnecessary elements css('head, script, style').remove - - # Add syntax highlighting CSS - style = doc.document.create_element('style') - style.content = <<-CSS - .highlight { background: #272b30; color: #e9ecef; border-radius: 4px; margin: 1em 0; } - .highlight pre { margin: 0; padding: 10px; } - .highlight .k { color: #cc7832; font-weight: bold; } /* Keyword */ - .highlight .kd { color: #cc7832; font-weight: bold; } /* Keyword.Declaration */ - .highlight .nb { color: #6897bb; } /* Name.Builtin */ - .highlight .nx { color: #ffc66d; } /* Name.Other */ - .highlight .nf { color: #ffc66d; } /* Name.Function */ - .highlight .mi { color: #6897bb; } /* Literal.Number.Integer */ - .highlight .s1 { color: #6a8759; } /* Literal.String.Single */ - .highlight .s2 { color: #6a8759; } /* Literal.String.Double */ - .highlight .c1 { color: #808080; font-style: italic; } /* Comment.Single */ - .highlight .lineno { color: #606366; margin-right: 10px; -webkit-user-select: none; user-select: none; } - .highlight-javascript { padding: 0; } - - /* Method signatures */ - .sig { padding: 5px 10px; } - .sig-name { color: #ffc66d; } - .sig-param { color: #e9ecef; } - .sig-param .sig-type { color: #6897bb; } - .sig-returns { color: #cc7832; } - .sig-returns .sig-type { color: #6897bb; } - .sig-paren { color: #e9ecef; } - .property .pre { color: #cc7832; } - - /* Inline code */ - code.literal { background: #2b2b2b; padding: 2px 4px; border-radius: 3px; } - code.literal .pre { color: #e9ecef; } - - /* Links */ - .reference { color: #6897bb; text-decoration: none; } - .reference:hover { text-decoration: underline; } - .reference.external { color: #6a8759; } - - /* Notes */ - .admonition.note { background: #2b2b2b; padding: 12px 15px; border-left: 4px solid #6897bb; margin: 1em 0; } - .admonition-title { color: #6897bb; font-weight: bold; margin: 0 0 5px 0; } - CSS - doc.at_css('head') ? doc.at_css('head').add_child(style) : doc.add_child(style) - - # Create a wrapper div for better styling - if root = at_css('body') - content = root.inner_html - else - content = doc.inner_html - end - - # Create Django-like structure - content = <<-HTML -
-
-
-
- #{content} -
-
-
-
- HTML - - doc.inner_html = content - + # Handle source links css('h2').each do |node| if node.content.strip == 'Source' @@ -319,6 +255,10 @@ def call end end + # Remove the navigation arrows and links + css('.nav').remove if at_css('.nav') + # If the arrows are in a different container, adjust the selector accordingly + doc end diff --git a/lib/docs/scrapers/threejs.rb b/lib/docs/scrapers/threejs.rb index 9f6a27cc9d..5be458b8d8 100644 --- a/lib/docs/scrapers/threejs.rb +++ b/lib/docs/scrapers/threejs.rb @@ -1,7 +1,7 @@ module Docs class Threejs < FileScraper self.name = 'Three.js' - self.type = 'threejs' + self.type = 'simple' self.slug = 'threejs' self.links = { home: 'https://threejs.org/', From 21a04f9115937f24decad1fbd96fe12804487e95 Mon Sep 17 00:00:00 2001 From: Chaitanya Rahalkar Date: Tue, 24 Dec 2024 19:33:56 -0600 Subject: [PATCH 07/13] fix the clean_html file for optimizations --- lib/docs/filters/threejs/clean_html.rb | 61 ++++---------------------- 1 file changed, 8 insertions(+), 53 deletions(-) diff --git a/lib/docs/filters/threejs/clean_html.rb b/lib/docs/filters/threejs/clean_html.rb index b66bc729d9..ac1cb03690 100644 --- a/lib/docs/filters/threejs/clean_html.rb +++ b/lib/docs/filters/threejs/clean_html.rb @@ -4,6 +4,14 @@ class CleanHtmlFilter < Filter def call # Remove unnecessary elements css('head, script, style').remove + # Wrap code blocks with pre tags and add syntax highlighting + css('code').each do |node| + unless node.parent.name == 'pre' + pre = node.wrap('
')
+            pre['data-language'] = 'javascript'
+            pre['class'] = 'language-javascript'
+          end
+        end
         
         # Handle source links
         css('h2').each do |node|
@@ -202,29 +210,6 @@ def call
           end
         end
         
-        # Clean up code blocks
-        css('pre').each do |node|
-          wrapper = doc.document.create_element('div')
-          wrapper['class'] = 'highlight'
-          node.replace(wrapper)
-          
-          div = doc.document.create_element('div')
-          div['class'] = 'highlight-javascript notranslate'
-          wrapper.add_child(div)
-          
-          pre = doc.document.create_element('pre')
-          pre['class'] = ''
-          div.add_child(pre)
-
-          # Format the code content
-          code = node.content.strip
-          
-          # Add syntax highlighting spans
-          highlighted_code = highlight_javascript(code)
-          
-          pre.inner_html = highlighted_code
-        end
-
         # Add proper heading IDs and classes
         css('h1, h2, h3, h4').each do |node|
           node['id'] ||= node.content.strip.downcase.gsub(/[^\w]+/, '-')
@@ -232,9 +217,6 @@ def call
           node['class'] = "#{existing_class} section-header"
         end
 
-        # Remove interactive examples
-        css('.threejs_example_container').remove
-
         # Add note styling
         css('p').each do |node|
           if node.content.start_with?('Note:')
@@ -254,35 +236,8 @@ def call
             node.replace(wrapper)
           end
         end
-
-        # Remove the navigation arrows and links
-        css('.nav').remove if at_css('.nav')
-        # If the arrows are in a different container, adjust the selector accordingly
-        
         doc
       end
-
-      private
-
-      def highlight_javascript(code)
-        code = code.gsub(/\b(function|return|var|let|const|if|else|for|while|do|switch|case|break|continue|new|try|catch|throw|this|typeof|instanceof|in|of|class|extends|super|import|export|default|null|undefined|true|false)\b/, '\1') # keywords
-        code = code.gsub(/\b(\d+(\.\d+)?)\b/, '\1') # numbers
-        code = code.gsub(/'([^']*)'/, '\'\1\'') # single quotes
-        code = code.gsub(/"([^"]*)"/, '"\1"') # double quotes
-        code = code.gsub(/`([^`]*)`/, '`\1`') # template literals
-        code = code.gsub(/\/\/[^\n]*/, '\0') # single line comments
-        code = code.gsub(/\b(console|document|window|Array|Object|String|Number|Boolean|Function|Symbol|Map|Set|Promise|async|await)\b/, '\1') # built-ins
-        code = code.gsub(/([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/, '\1(') # function calls
-        code = code.gsub(/\b(addEventListener|querySelector|getElementById|setTimeout|setInterval)\b/, '\1') # common methods
-        
-        # Add line numbers
-        lines = code.split("\n")
-        numbered_lines = lines.map.with_index(1) do |line, i|
-          "#{i}#{line}"
-        end
-        
-        numbered_lines.join("\n")
-      end
     end
   end
 end 
\ No newline at end of file

From 8d0efa7c28aecc9a05c0d680b8c699934797080f Mon Sep 17 00:00:00 2001
From: Chaitanya Rahalkar 
Date: Tue, 24 Dec 2024 19:36:03 -0600
Subject: [PATCH 08/13] update threejs doc version

---
 lib/docs/scrapers/threejs.rb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/docs/scrapers/threejs.rb b/lib/docs/scrapers/threejs.rb
index 5be458b8d8..bc792faeaa 100644
--- a/lib/docs/scrapers/threejs.rb
+++ b/lib/docs/scrapers/threejs.rb
@@ -42,8 +42,8 @@ class Threejs < FileScraper
 
     self.class_attribute :release
 
-    version '160' do
-      self.release = '160'
+    version '171' do
+      self.release = '171'
       self.base_url = "https://threejs.org/docs"
     end
 

From b7393f4d5504e6bd76995ec4734bce3fedeef17c Mon Sep 17 00:00:00 2001
From: Chaitanya Rahalkar 
Date: Tue, 24 Dec 2024 20:57:03 -0600
Subject: [PATCH 09/13] update documentation for new folder location for json
 file

---
 docs/file-scrapers.md                  | 2 ++
 lib/docs/filters/threejs/clean_html.rb | 1 +
 lib/docs/scrapers/threejs.rb           | 4 +---
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/docs/file-scrapers.md b/docs/file-scrapers.md
index 164b6f7d9d..923bac2061 100644
--- a/docs/file-scrapers.md
+++ b/docs/file-scrapers.md
@@ -298,7 +298,9 @@ Make sure to set the version per the release tag (e.g. r160). Note that the r pr
 curl https://codeload.github.com/mrdoob/three.js/tar.gz/refs/tags/r${VERSION} > threejs.tar.gz
 tar -xzf threejs.tar.gz
 mkdir -p docs/threejs~${VERSION}
+mv three.js-r${VERSION}/list.json /tmp/list.json
 mv three.js-r${VERSION}/docs/* docs/threejs~${VERSION}/
+
 rm -rf three.js-r${VERSION}/
 rm threejs.tar.gz
 ```
diff --git a/lib/docs/filters/threejs/clean_html.rb b/lib/docs/filters/threejs/clean_html.rb
index ac1cb03690..abee6997c1 100644
--- a/lib/docs/filters/threejs/clean_html.rb
+++ b/lib/docs/filters/threejs/clean_html.rb
@@ -4,6 +4,7 @@ class CleanHtmlFilter < Filter
       def call
         # Remove unnecessary elements
         css('head, script, style').remove
+        
         # Wrap code blocks with pre tags and add syntax highlighting
         css('code').each do |node|
           unless node.parent.name == 'pre'
diff --git a/lib/docs/scrapers/threejs.rb b/lib/docs/scrapers/threejs.rb
index bc792faeaa..e596e03444 100644
--- a/lib/docs/scrapers/threejs.rb
+++ b/lib/docs/scrapers/threejs.rb
@@ -40,8 +40,6 @@ class Threejs < FileScraper
       Licensed under the MIT License.
     HTML
 
-    self.class_attribute :release
-
     version '171' do
       self.release = '171'
       self.base_url = "https://threejs.org/docs"
@@ -53,7 +51,7 @@ def get_latest_version(opts)
 
     def initial_paths
       paths = []
-      json_path = File.expand_path("docs/threejs~#{self.release}/list.json")
+      json_path = File.expand_path("/tmp/list.json")
       json_content = File.read(json_path)
       json_data = JSON.parse(json_content)
 

From b218836a82b66db21beffc48df75744b15317fe9 Mon Sep 17 00:00:00 2001
From: Chaitanya Rahalkar 
Date: Wed, 25 Dec 2024 14:09:00 -0600
Subject: [PATCH 10/13] cleanup the code

---
 lib/docs/filters/threejs/clean_html.rb | 365 ++++++++++++-------------
 1 file changed, 180 insertions(+), 185 deletions(-)

diff --git a/lib/docs/filters/threejs/clean_html.rb b/lib/docs/filters/threejs/clean_html.rb
index abee6997c1..9b0de32445 100644
--- a/lib/docs/filters/threejs/clean_html.rb
+++ b/lib/docs/filters/threejs/clean_html.rb
@@ -1,243 +1,238 @@
 module Docs
   class Threejs
     class CleanHtmlFilter < Filter
+      PATTERNS = {
+        method_this: /\[method:this\s+([^\]]+)\]\s*\((.*?)\)/,
+        method_return: /\[method:([^\s\]]+)\s+([^\]]+)\]\s*\((.*?)\)/,
+        method_no_params: /\[method:([^\s\]]+)\s+([^\]]+)\](?!\()/,
+        property: /\[property:([^\]]+?)\s+([^\]]+?)\]/,
+        example_link: /\[example:([^\s\]]+)\s+([^\]]+)\]/,
+        external_link_text: /\[link:([^\s\]]+)\s+([^\]]+)\]/,
+        external_link: /\[link:([^\]]+)\]/,
+        page_link_text: /\[page:([^\]]+?)\s+([^\]]+?)\]/,
+        page_link: /\[page:([^\]]+?)\]/,
+        inline_code: /`([^`]+)`/,
+        name_placeholder: /\[name\]/,
+        constructor_param: /\[param:([^\]]+?)\s+([^\]]+?)\]/
+      }.freeze
+
       def call
-        # Remove unnecessary elements
+        remove_unnecessary_elements
+        wrap_code_blocks
+        process_sections
+        format_links
+        add_section_structure
+        format_notes
+        add_heading_attributes
+        doc
+      end
+
+      private
+
+      def remove_unnecessary_elements
         css('head, script, style').remove
-        
-        # Wrap code blocks with pre tags and add syntax highlighting
+      end
+
+      def wrap_code_blocks
         css('code').each do |node|
-          unless node.parent.name == 'pre'
-            pre = node.wrap('
')
-            pre['data-language'] = 'javascript'
-            pre['class'] = 'language-javascript'
-          end
+          next if node.parent.name == 'pre'
+          pre = node.wrap('
')
+          pre['data-language'] = pre['class'] = 'language-javascript'
         end
-        
+      end
+
+      def process_sections
         # Handle source links
         css('h2').each do |node|
-          if node.content.strip == 'Source'
-            content = node.next_element&.inner_html
-            if content
-              # Clean up any existing formatting
-              content = content.gsub(/<[^>]+>/, '')
-              # Extract the path from the content
-              if content =~ /src\/(.*?)\.js/
-                path = "/#{$1}.js"
-                formatted_link = %Q(src#{path})
-                node.next_element.inner_html = formatted_link if node.next_element
-              end
-            end
-          end
+          next unless node.content.strip == 'Source'
+          handle_source_link(node)
         end
 
-        # Handle method signatures
+        # Handle method signatures and properties
         css('h3').each do |node|
           content = node.inner_html
-
-          # Handle [method:this methodName]( param1, param2, ... ) format
-          content = content.gsub(/\[method:this\s+([^\]]+)\]\s*\((.*?)\)/) do |match|
-            method_name, params_str = $1, $2
-            
-            # Format parameters
-            params = params_str.split(',').map do |param|
-              param = param.strip
-              if param.include?(' ')
-                type, name = param.split(' ', 2).map(&:strip)
-                "#{type} #{name}"
-              else
-                "#{param}"
-              end
-            end.join(", ")
-
-            "
" \ - "this." \ - "#{method_name}" \ - "(" \ - "#{params}" \ - ")
" - end - - # Handle [method:returnType methodName]( param1, param2, ... ) format - content = content.gsub(/\[method:([^\s\]]+)\s+([^\]]+)\]\s*\((.*?)\)/) do |match| - return_type, method_name, params_str = $1, $2, $3 - next if method_name.start_with?('this') # Skip if already handled above - - # Format parameters - params = params_str.split(',').map do |param| - param = param.strip - if param.include?(' ') - type, name = param.split(' ', 2).map(&:strip) - "#{type} #{name}" - else - "#{param}" - end - end.join(", ") - - "
" \ - "#{method_name}" \ - "(" \ - "#{params}" \ - ")" \ - ": " \ - "#{return_type}
" - end - - # Handle [method:returnType methodName] format (no parameters) - content = content.gsub(/\[method:([^\s\]]+)\s+([^\]]+)\](?!\()/) do |match| - return_type, method_name = $1, $2 - "
" \ - "#{method_name}" \ - "(" \ - ")" \ - ": " \ - "#{return_type}
" - end - + content = handle_method_signatures(content) + content = handle_properties(content) node.inner_html = content end - # Handle [name] placeholders in headers and constructor + # Handle name placeholders and constructor params css('h1, h3').each do |node| content = node.inner_html - - # Replace [name] with class name - content = content.gsub(/\[name\]/) do - name = slug.split('/').last.gsub('.html', '') - "#{name}" - end - - # Format constructor parameters - content = content.gsub(/\[param:([^\]]+?)\s+([^\]]+?)\]/) do |match| - type, name = $1, $2 - "#{type} #{name}" - end - + content = handle_name_placeholders(content) + content = format_constructor_params(content) node.inner_html = content end + end - # Clean up property formatting - css('h3').each do |node| - node.inner_html = node.inner_html.gsub(/\[property:([^\]]+?)\s+([^\]]+?)\]/) do |match| - type, name = $1, $2 - "
" \ - "#{name}" \ - ": " \ - "#{type}
" + def handle_source_link(node) + content = node.next_element&.inner_html + return unless content + content = content.gsub(/<[^>]+>/, '') + if content =~ /src\/(.*?)\.js/ + path = "/#{$1}.js" + formatted_link = %Q(src#{path}) + node.next_element.inner_html = formatted_link if node.next_element + end + end + + def handle_method_signatures(content) + content + .gsub(PATTERNS[:method_this]) { format_method_signature('this', $1, $2) } + .gsub(PATTERNS[:method_return]) do |match| + next if $2.start_with?('this') + format_method_signature($1, $2, $3, true) end + .gsub(PATTERNS[:method_no_params]) { format_method_signature($1, $2, nil, true) } + end + + def format_method_signature(type_or_this, name, params_str, with_return = false) + params = if params_str + params_str.split(',').map { |param| format_parameter(param.strip) }.join(", ") end - # Clean up external links + html = "
" + if type_or_this == 'this' + html << "this." + end + html << "#{name}" \ + "(" \ + "#{params}" \ + ")" + if with_return + html << ": " \ + "#{type_or_this}" + end + html << "
" + end + + def format_parameter(param) + if param.include?(' ') + type, name = param.split(' ', 2).map(&:strip) + "#{type} #{name}" + else + "#{param}" + end + end + + def handle_properties(content) + content.gsub(PATTERNS[:property]) do |match| + type, name = $1, $2 + "
" \ + "#{name}" \ + ": " \ + "#{type}
" + end + end + + def handle_name_placeholders(content) + content.gsub(PATTERNS[:name_placeholder]) do + name = slug.split('/').last.gsub('.html', '') + "#{name}" + end + end + + def format_constructor_params(content) + content.gsub(PATTERNS[:constructor_param]) do |match| + type, name = $1, $2 + "#{type} #{name}" + end + end + + def format_links css('*').each do |node| next if node.text? - # Handle example links [example:tag Title] - node.inner_html = node.inner_html.gsub(/\[example:([^\s\]]+)\s+([^\]]+)\]/) do |match| - tag, title = $1, $2 - "#{title}" - end - - # Handle external links with [link:url text] format - node.inner_html = node.inner_html.gsub(/\[link:([^\s\]]+)\s+([^\]]+)\]/) do |match| - url, text = $1, $2 - "#{text}" - end + content = node.inner_html + .gsub(PATTERNS[:example_link]) { create_external_link("https://threejs.org/examples/##{$1}", $2) } + .gsub(PATTERNS[:external_link_text]) { create_external_link($1, $2) } + .gsub(PATTERNS[:external_link]) { create_external_link($1, $1) } + .gsub(PATTERNS[:page_link_text]) { create_internal_link($1, $2) } + .gsub(PATTERNS[:page_link]) { create_internal_link($1, $1) } + + node.inner_html = content + end - # Handle external links with [link:url] format - node.inner_html = node.inner_html.gsub(/\[link:([^\]]+)\]/) do |match| - url = $1 - "#{url}" - end + normalize_href_attributes + end - # Handle internal page links with text - node.inner_html = node.inner_html.gsub(/\[page:([^\]]+?)\s+([^\]]+?)\]/) do - path, text = $1, $2 - "#{text}" - end + def create_external_link(url, text) + %Q(#{text}) + end - # Handle internal page links without text - node.inner_html = node.inner_html.gsub(/\[page:([^\]]+?)\]/) do |match| - path = $1 - "#{path}" - end - end + def create_internal_link(path, text) + %Q(#{text}) + end - # Fix all href attributes to be lowercase and remove .html + def normalize_href_attributes css('a[href]').each do |link| next if link['href'].start_with?('http') link['href'] = link['href'].remove('../').downcase.sub(/\.html$/, '') link['class'] = 'reference internal' end + end - # Add section classes + def add_section_structure css('h2').each do |node| node['class'] = 'section-title' section = node.next_element - if section - wrapper = doc.document.create_element('div') - wrapper['class'] = 'section' - node.after(wrapper) - wrapper.add_child(node) - current = section - while current && current.name != 'h2' - next_el = current.next - wrapper.add_child(current) - current = next_el - end + next unless section + + wrapper = doc.document.create_element('div') + wrapper['class'] = 'section' + node.after(wrapper) + wrapper.add_child(node) + + current = section + while current && current.name != 'h2' + next_el = current.next + wrapper.add_child(current) + current = next_el end end - # Format description paragraphs - css('p.desc').each do |node| - node['class'] = 'section-desc' - end + css('p.desc').each { |node| node['class'] = 'section-desc' } + end - # Handle inline code/backticks in text - css('p, li, dt, dd').each do |node| - next if node.at_css('pre') # Skip if contains a code block + def format_notes + css('p').each do |node| + next unless node.content.start_with?('Note:') - # Replace backticks with proper code formatting - node.inner_html = node.inner_html.gsub(/`([^`]+)`/) do |match| - code = $1 - "#{code}" - end + wrapper = doc.document.create_element('div') + wrapper['class'] = 'admonition note' + + title = doc.document.create_element('p') + title['class'] = 'first admonition-title' + title.content = 'Note' + + content = doc.document.create_element('p') + content['class'] = 'last' + content.inner_html = node.inner_html.sub('Note:', '').strip + + wrapper.add_child(title) + wrapper.add_child(content) + node.replace(wrapper) end + end - # Handle inline code in property descriptions - css('.property-type').each do |node| - node.inner_html = node.inner_html.gsub(/`([^`]+)`/) do |match| - code = $1 - "#{code}" - end - end - - # Add proper heading IDs and classes + def add_heading_attributes css('h1, h2, h3, h4').each do |node| node['id'] ||= node.content.strip.downcase.gsub(/[^\w]+/, '-') existing_class = node['class'].to_s node['class'] = "#{existing_class} section-header" end - # Add note styling - css('p').each do |node| - if node.content.start_with?('Note:') - wrapper = doc.document.create_element('div') - wrapper['class'] = 'admonition note' - - title = doc.document.create_element('p') - title['class'] = 'first admonition-title' - title.content = 'Note' - - content = doc.document.create_element('p') - content['class'] = 'last' - content.inner_html = node.inner_html.sub('Note:', '').strip - - wrapper.add_child(title) - wrapper.add_child(content) - node.replace(wrapper) + format_inline_code + end + + def format_inline_code + selectors = ['p', 'li', 'dt', 'dd', '.property-type'].join(', ') + css(selectors).each do |node| + next if node.at_css('pre') + node.inner_html = node.inner_html.gsub(PATTERNS[:inline_code]) do |match| + "#{$1}" end end - doc end end end From 8ec3a27b0149f67f52392187eb7ce9bb36789fea Mon Sep 17 00:00:00 2001 From: Chaitanya Rahalkar Date: Wed, 25 Dec 2024 14:12:12 -0600 Subject: [PATCH 11/13] remove scss since using the simple style --- assets/stylesheets/application.css.scss | 1 - assets/stylesheets/pages/_threejs.scss | 47 ------------------------- 2 files changed, 48 deletions(-) delete mode 100644 assets/stylesheets/pages/_threejs.scss diff --git a/assets/stylesheets/application.css.scss b/assets/stylesheets/application.css.scss index d2887ba994..3823cdc3d8 100644 --- a/assets/stylesheets/application.css.scss +++ b/assets/stylesheets/application.css.scss @@ -131,7 +131,6 @@ 'pages/tcl_tk', 'pages/tensorflow', 'pages/terraform', - 'pages/threejs', 'pages/typescript', 'pages/underscore', 'pages/vue', diff --git a/assets/stylesheets/pages/_threejs.scss b/assets/stylesheets/pages/_threejs.scss deleted file mode 100644 index 8996ba0bf9..0000000000 --- a/assets/stylesheets/pages/_threejs.scss +++ /dev/null @@ -1,47 +0,0 @@ -._threejs { - // Code blocks - pre, code { - background-color: #f5f5f5; - border-radius: 3px; - padding: 0.2em 0.4em; - } - pre { - padding: 1em; - margin: 1em 0; - overflow: auto; - code { - background: none; - padding: 0; - } - } - // Links - a { - color: #049EF4; - text-decoration: none; - &:hover { - text-decoration: underline; - } - } - // Headings - h2 { - margin-top: 2em; - padding-bottom: 0.3em; - border-bottom: 1px solid #eaecef; - } - h3 { - margin-top: 1.5em; - } - // Tables - table { - border-collapse: collapse; - margin: 1em 0; - width: 100%; - } - th, td { - border: 1px solid #dfe2e5; - padding: 6px 13px; - } - tr:nth-child(2n) { - background-color: #f6f8fa; - } - } \ No newline at end of file From 35b7c733670bab2f1c289d5f890f277a5c891c89 Mon Sep 17 00:00:00 2001 From: Chaitanya Rahalkar Date: Wed, 25 Dec 2024 14:19:54 -0600 Subject: [PATCH 12/13] update tmp folder to use the rails project temp folder --- docs/file-scrapers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/file-scrapers.md b/docs/file-scrapers.md index 923bac2061..55ba555268 100644 --- a/docs/file-scrapers.md +++ b/docs/file-scrapers.md @@ -298,7 +298,7 @@ Make sure to set the version per the release tag (e.g. r160). Note that the r pr curl https://codeload.github.com/mrdoob/three.js/tar.gz/refs/tags/r${VERSION} > threejs.tar.gz tar -xzf threejs.tar.gz mkdir -p docs/threejs~${VERSION} -mv three.js-r${VERSION}/list.json /tmp/list.json +mv three.js-r${VERSION}/list.json tmp/list.json mv three.js-r${VERSION}/docs/* docs/threejs~${VERSION}/ rm -rf three.js-r${VERSION}/ From 6dbe834e5706d6918d08793cd668395d4049aeb7 Mon Sep 17 00:00:00 2001 From: Simon Legner Date: Sun, 23 Feb 2025 09:57:41 +0100 Subject: [PATCH 13/13] Update Three.js documentation (173) --- assets/javascripts/news.json | 4 ++++ lib/docs/filters/threejs/clean_html.rb | 18 ++++-------------- lib/docs/scrapers/threejs.rb | 16 +++++++--------- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/assets/javascripts/news.json b/assets/javascripts/news.json index 2c393d971b..b6c061b01e 100644 --- a/assets/javascripts/news.json +++ b/assets/javascripts/news.json @@ -1,4 +1,8 @@ [ + [ + "2025-02-23", + "New documentation: Three.js" + ], [ "2025-02-16", "New documentation: OpenLayers" diff --git a/lib/docs/filters/threejs/clean_html.rb b/lib/docs/filters/threejs/clean_html.rb index 9b0de32445..01f43bc4d0 100644 --- a/lib/docs/filters/threejs/clean_html.rb +++ b/lib/docs/filters/threejs/clean_html.rb @@ -36,8 +36,8 @@ def remove_unnecessary_elements def wrap_code_blocks css('code').each do |node| next if node.parent.name == 'pre' - pre = node.wrap('
')
-          pre['data-language'] = pre['class'] = 'language-javascript'
+          node.wrap('
')
+          node.parent['data-language'] = 'javascript'
         end
       end
 
@@ -45,7 +45,8 @@ def process_sections
         # Handle source links
         css('h2').each do |node|
           next unless node.content.strip == 'Source'
-          handle_source_link(node)
+          node.next_element.remove
+          node.remove
         end
 
         # Handle method signatures and properties
@@ -65,17 +66,6 @@ def process_sections
         end
       end
 
-      def handle_source_link(node)
-        content = node.next_element&.inner_html
-        return unless content
-        content = content.gsub(/<[^>]+>/, '')
-        if content =~ /src\/(.*?)\.js/
-          path = "/#{$1}.js"
-          formatted_link = %Q(src#{path})
-          node.next_element.inner_html = formatted_link if node.next_element
-        end
-      end
-
       def handle_method_signatures(content)
         content
           .gsub(PATTERNS[:method_this]) { format_method_signature('this', $1, $2) }
diff --git a/lib/docs/scrapers/threejs.rb b/lib/docs/scrapers/threejs.rb
index e596e03444..c3ef9bc25d 100644
--- a/lib/docs/scrapers/threejs.rb
+++ b/lib/docs/scrapers/threejs.rb
@@ -1,5 +1,5 @@
 module Docs
-  class Threejs < FileScraper
+  class Threejs < UrlScraper
     self.name = 'Three.js'
     self.type = 'simple'
     self.slug = 'threejs'
@@ -40,20 +40,18 @@ class Threejs < FileScraper
       Licensed under the MIT License.
     HTML
 
-    version '171' do
-      self.release = '171'
-      self.base_url = "https://threejs.org/docs"
-    end
+    self.release = '173'
+    self.base_url = "https://threejs.org/docs"
 
     def get_latest_version(opts)
-      get_latest_github_release('mrdoob', 'three.js', opts)
+      get_latest_github_release('mrdoob', 'three.js', opts)[1..]
     end
 
     def initial_paths
       paths = []
-      json_path = File.expand_path("/tmp/list.json")
-      json_content = File.read(json_path)
-      json_data = JSON.parse(json_content)
+      url = 'https://threejs.org/docs/list.json'
+      response = Request.run(url)
+      json_data = JSON.parse(response.body)
 
       # Process both API and manual sections
       process_documentation(json_data['en'], paths)