diff --git a/.stylelintrc.json b/.stylelintrc.json index b71ea34bdf..64e834b227 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,9 +1,6 @@ { "extends": "stylelint-config-standard", "plugins": ["stylelint-value-no-unknown-custom-properties"], - "ignoreFiles": [ - "lib/rdoc/generator/template/darkfish/css/**/*.css" - ], "rules": { "csstools/value-no-unknown-custom-properties": true, "custom-property-no-missing-var-function": true, diff --git a/AGENTS.md b/AGENTS.md index a51f9ddce7..dc3c50410d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -178,12 +178,10 @@ lib/rdoc/ │ └── ... ├── generator/ # Documentation generators │ ├── aliki.rb # HTML generator (default theme) -│ ├── darkfish.rb # HTML generator (deprecated, will be removed in v8.0) │ ├── markup.rb # Markup format generator │ ├── ri.rb # RI command generator │ └── template/ # ERB templates (.rhtml files) -│ ├── aliki/ # Aliki theme (default) -│ └── darkfish/ # Darkfish theme (deprecated) +│ └── aliki/ # Aliki theme ├── markup/ # Markup parsing and formatting ├── code_object/ # AST objects for documented items ├── markdown/ # Markdown parsing @@ -230,7 +228,7 @@ exe/ ### Pluggable System - **Parsers:** Ruby, C, Markdown, RD, Prism-based Ruby (experimental) -- **Generators:** HTML/Aliki (default), HTML/Darkfish (deprecated), RI, POT (gettext), JSON, Markup +- **Generators:** HTML/Aliki (default), RI, POT (gettext), Markup ## Common Workflows @@ -317,7 +315,7 @@ When editing markup reference documentation, such as `doc/markup_reference/markd ### Modifying Themes/Styling -When making changes to theme CSS or templates (e.g., Darkfish or Aliki themes): +When making changes to theme CSS or templates: 1. **Generate documentation**: Run `bundle exec rake rerdoc` to create baseline 2. **Start HTTP server**: Run `cd _site && python3 -m http.server 8000` (use different port if 8000 is in use) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9911267cc5..57a1a50515 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -143,14 +143,9 @@ bundle exec rake coverage ## Themes -RDoc ships with two HTML themes: +RDoc ships with the **Aliki** HTML theme, a modern theme with improved styling and navigation. -- **Aliki** (default) - Modern theme with improved styling and navigation -- **Darkfish** (deprecated) - Classic theme, will be removed in v8.0 - -New feature development should focus on the Aliki theme. Darkfish will continue to receive bug fixes but no new features. - -Theme templates are located at `lib/rdoc/generator/template//`. +Theme templates are located at `lib/rdoc/generator/template/aliki/`. ## Project Structure @@ -166,12 +161,10 @@ lib/rdoc/ │ └── ... ├── generator/ # Documentation generators │ ├── aliki.rb # HTML generator (default theme) -│ ├── darkfish.rb # HTML generator (deprecated, will be removed in v8.0) │ ├── markup.rb # Markup format generator │ ├── ri.rb # RI command generator │ └── template/ # ERB templates -│ ├── aliki/ # Aliki theme (default) -│ └── darkfish/ # Darkfish theme (deprecated) +│ └── aliki/ # Aliki theme ├── markup/ # Markup parsing and formatting ├── code_object/ # AST objects for documented items ├── markdown.kpeg # Parser source (edit this) diff --git a/LEGAL.rdoc b/LEGAL.rdoc index f054ab851a..f864ae99cc 100644 --- a/LEGAL.rdoc +++ b/LEGAL.rdoc @@ -10,26 +10,9 @@ Aliki:: * lib/rdoc/generator/aliki.rb * lib/rdoc/generator/template/aliki/* -Darkfish:: - Darkfish was written by Michael Granger and is included under the BSD 3-Clause - license. Darkfish contains images from the Silk Icons set by Mark James. - - See lib/rdoc/generator/darkfish.rb for license information. - - * lib/rdoc/generator/darkfish.rb - * lib/rdoc/generator/template/darkfish/* - * lib/rdoc/generator/template/darkfish/images - SDoc:: - Portions of SDoc by (Володя Колесников) Vladimir Kolesnikov are included - under the MIT license as RDoc::Generator::JsonIndex. See - lib/rdoc/generator/json_index.rb for license information. - - * lib/rdoc/generator/json_index.rb - * lib/rdoc/generator/template/json_index/* - * The +#search_index+ methods on RDoc::CodeObject subclasses were derived - from sdoc. - * RDoc::ClassModule#document_self_or_methods comes from SDoc. + RDoc::ClassModule#document_self_or_methods comes from SDoc by + (Володя Колесников) Vladimir Kolesnikov, included under the MIT license. peg-markdown:: RDoc's Markdown support is derived from peg-markdown by John MacFarlane. It @@ -42,15 +25,3 @@ MarkdownTest:: same terms as Perl itself. See http://dev.perl.org/licenses/ for the terms of the Perl license. - -Fonts:: - Source Code Pro is (c) 2010, 2012 Adobe Systems Incorporated. - - Lato is (c) 2010 Łukasz Dziedzic. - - Both fonts are used under the SIL Open Font License, Version 1.1. The - license is available at http://scripts.sil.org/OFL - - See lib/rdoc/generator/template/darkfish/fonts.css for complete copyright - and license information, including a copy of the OFL. - diff --git a/README.md b/README.md index 510f12b5b2..f1fc2555cd 100644 --- a/README.md +++ b/README.md @@ -156,22 +156,7 @@ To determine how well your project is documented run `rdoc -C lib` to get a docu ## Theme Options -RDoc ships with two built-in themes: - -- **Aliki** (default) - A modern, clean theme with improved navigation and search -- **Darkfish** (deprecated) - The classic theme, will be removed in v8.0 - -To use the Darkfish theme instead of the default Aliki theme: - -```shell -rdoc --format darkfish -``` - -Or in your `.rdoc_options` file: - -```yaml -generator_name: darkfish -``` +RDoc ships with the **Aliki** theme, a modern, clean theme with improved navigation and search. There are also a few community-maintained themes for RDoc: diff --git a/lib/rdoc/code_object/class_module.rb b/lib/rdoc/code_object/class_module.rb index 00e406b1a6..7e5f46683f 100644 --- a/lib/rdoc/code_object/class_module.rb +++ b/lib/rdoc/code_object/class_module.rb @@ -723,24 +723,6 @@ def remove_things(my_things, other_files) # :nodoc: end end - ## - # Search record used by RDoc::Generator::JsonIndex - # - # TODO: Remove this method after dropping the darkfish theme and JsonIndex generator. - # Use #search_snippet instead for getting documentation snippets. - - def search_record - [ - name, - full_name, - full_name, - '', - path, - '', - snippet(@comment_location), - ] - end - ## # Returns an HTML snippet of the first comment for search results. diff --git a/lib/rdoc/code_object/method_attr.rb b/lib/rdoc/code_object/method_attr.rb index 3169640982..dae6af7f7a 100644 --- a/lib/rdoc/code_object/method_attr.rb +++ b/lib/rdoc/code_object/method_attr.rb @@ -372,25 +372,6 @@ def pretty_print(q) # :nodoc: end end - ## - # Used by RDoc::Generator::JsonIndex to create a record for the search - # engine. - # - # TODO: Remove this method after dropping the darkfish theme and JsonIndex generator. - # Use #search_snippet instead for getting documentation snippets. - - def search_record - [ - @name, - full_name, - @name, - @parent.full_name, - path, - params, - search_snippet, - ] - end - ## # Returns an HTML snippet of the comment for search results. diff --git a/lib/rdoc/code_object/top_level.rb b/lib/rdoc/code_object/top_level.rb index 21e412f82a..512d1b2ae8 100644 --- a/lib/rdoc/code_object/top_level.rb +++ b/lib/rdoc/code_object/top_level.rb @@ -237,26 +237,6 @@ def pretty_print(q) # :nodoc: end end - ## - # Search record used by RDoc::Generator::JsonIndex - # - # TODO: Remove this method after dropping the darkfish theme and JsonIndex generator. - # Use #search_snippet instead for getting documentation snippets. - - def search_record - return unless @parser < RDoc::Parser::Text - - [ - page_name, - '', - page_name, - '', - path, - '', - search_snippet, - ] - end - ## # Returns an HTML snippet of the comment for search results. diff --git a/lib/rdoc/generator.rb b/lib/rdoc/generator.rb index e8a14d4a66..23c17507f4 100644 --- a/lib/rdoc/generator.rb +++ b/lib/rdoc/generator.rb @@ -2,7 +2,7 @@ ## # RDoc uses generators to turn parsed source code in the form of an # RDoc::CodeObject tree into some form of output. RDoc comes with the HTML -# generator RDoc::Generator::Darkfish and an ri data generator +# generator RDoc::Generator::Aliki and an ri data generator # RDoc::Generator::RI. # # == Registering a Generator @@ -44,8 +44,6 @@ module RDoc::Generator autoload :Markup, "#{__dir__}/generator/markup" autoload :Aliki, "#{__dir__}/generator/aliki" - autoload :Darkfish, "#{__dir__}/generator/darkfish" - autoload :JsonIndex, "#{__dir__}/generator/json_index" autoload :RI, "#{__dir__}/generator/ri" autoload :POT, "#{__dir__}/generator/pot" diff --git a/lib/rdoc/generator/aliki.rb b/lib/rdoc/generator/aliki.rb index d8314196f9..0f64d2fad2 100644 --- a/lib/rdoc/generator/aliki.rb +++ b/lib/rdoc/generator/aliki.rb @@ -1,25 +1,151 @@ # frozen_string_literal: true +require 'erb' +require 'fileutils' +require 'json' +require 'pathname' require 'uri' +require_relative 'markup' ## -# Aliki theme for RDoc documentation +# Aliki HTML generator for RDoc documentation. # # Author: Stan Lo -# -class RDoc::Generator::Aliki < RDoc::Generator::Darkfish +class RDoc::Generator::Aliki + RDoc::RDoc.add_generator self + include ERB::Util + + ## + # Description of this generator + + DESCRIPTION = 'HTML generator, default theme' + + ## + # The relative path to style sheets and javascript. By default this is set + # the same as the rel_prefix. + + attr_accessor :asset_rel_path + + ## + # The path to generate files into, combined with --op from the + # options for a full path. + + attr_reader :base_dir + + ## + # Classes and modules to be used by this generator, not necessarily + # displayed. See also #modsort + + attr_reader :classes + + ## + # No files will be written when dry_run is true. + + attr_accessor :dry_run + + ## + # When false the generate methods return a String instead of writing to a + # file. The default is true. + + attr_accessor :file_output + + ## + # Files to be displayed by this generator + + attr_reader :files + + ## + # Methods to be displayed by this generator + + attr_reader :methods + + ## + # Sorted list of classes and modules to be displayed by this generator + + attr_reader :modsort + + ## + # The RDoc::Store that is the source of the generated content + + attr_reader :store + + ## + # The directory where the template files live + + attr_reader :template_dir # :nodoc: + + ## + # The output directory + + attr_reader :outputdir + + ## + # Initialize a few instance variables before we start + def initialize(store, options) - super - aliki_template_dir = File.expand_path(File.join(__dir__, 'template', 'aliki')) - @template_dir = Pathname.new(aliki_template_dir) + @store = store + @options = options + + @asset_rel_path = '' + @base_dir = Pathname.pwd.expand_path + @dry_run = @options.dry_run + @file_output = true + @template_dir = Pathname.new(@options.template_dir) + @template_cache = {} + + @classes = nil + @context = nil + @files = nil + @methods = nil + @modsort = nil end ## - # Generate documentation. Overrides Darkfish to use Aliki's own search index - # instead of the JsonIndex generator. + # Output progress information if debugging is enabled + + def debug_msg(*msg) + return unless $DEBUG_RDOC + $stderr.puts(*msg) + end + + ## + # Create the directories the generated docs will live in if they don't + # already exist. + + def gen_sub_directories + @outputdir.mkpath + end + + ## + # Copy static assets (CSS, JS, fonts) from the template directory + # to the output directory. + + def write_style_sheet + debug_msg "Copying static files" + options = { verbose: $DEBUG_RDOC, noop: @dry_run } + + %w[css js fonts images].each do |subdir| + Dir[(@template_dir + "#{subdir}/**/*").to_s].each do |path| + next if File.directory?(path) + next if File.basename(path).start_with?('.') + + dst = Pathname.new(path).relative_path_from(@template_dir) + + install_rdoc_static_file @template_dir + path, dst, options + end + end + + unless @options.template_stylesheets.empty? + FileUtils.cp @options.template_stylesheets, '.', **options + end + end + + ## + # Build the initial indices and output objects based on an array of TopLevel + # objects containing the extracted information. def generate setup @@ -42,28 +168,563 @@ def generate end ## - # Copy only the static assets required by the Aliki theme. Unlike Darkfish we - # don't ship embedded fonts or image sprites, so limit the asset list to keep - # generated documentation lightweight. + # Copies static files from the static_path into the output directory - def write_style_sheet - debug_msg "Copying Aliki static files" - options = { verbose: $DEBUG_RDOC, noop: @dry_run } + def copy_static + return if @options.static_path.empty? - install_rdoc_static_file @template_dir + 'css/rdoc.css', "./css/rdoc.css", options + fu_options = { :verbose => $DEBUG_RDOC, :noop => @dry_run } - unless @options.template_stylesheets.empty? - FileUtils.cp @options.template_stylesheets, '.', **options + @options.static_path.each do |path| + unless File.directory? path then + FileUtils.install path, @outputdir, **fu_options.merge(:mode => 0644) + next + end + + Dir.chdir path do + Dir[File.join('**', '*')].each do |entry| + dest_file = @outputdir + entry + + if File.directory? entry then + FileUtils.mkdir_p entry, **fu_options + else + FileUtils.install entry, dest_file, **fu_options.merge(:mode => 0644) + end + end + end + end + end + + ## + # Return a list of the documented modules sorted by salience first, then + # by name. + + def get_sorted_module_list(classes) + classes.select do |klass| + klass.display? + end.sort + end + + ## + # Generate an index page which lists all the classes which are documented. + + def generate_index + template_file = @template_dir + 'index.rhtml' + return unless template_file.exist? + + debug_msg "Rendering the index page..." + + out_file = @base_dir + @options.op_dir + 'index.html' + rel_prefix = @outputdir.relative_path_from out_file.dirname + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + asset_rel_prefix = rel_prefix + @asset_rel_path + + @title = @options.title + @main_page = @files.find { |f| f.full_name == @options.main_page } + + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + # some partials rely on the presence of current variable to render + here.local_variable_set(:current, @main_page) if @main_page + here + end + rescue => e + error = RDoc::Error.new \ + "error generating index.html: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + ## + # Generates a class file for +klass+ + + def generate_class(klass, template_file = nil) + # This is used to auto-collapse Pages section on class/module pages + @inside_class_file = true + current = klass + + template_file ||= @template_dir + 'class.rhtml' + + debug_msg " working on %s (%s)" % [klass.full_name, klass.path] + out_file = @outputdir + klass.path + rel_prefix = @outputdir.relative_path_from out_file.dirname + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + asset_rel_prefix = rel_prefix + @asset_rel_path + + breadcrumb = # used in templates + breadcrumb = generate_nesting_namespaces_breadcrumb(current, rel_prefix) + + @title = "#{klass.type} #{klass.full_name} - #{@options.title}" + + debug_msg " rendering #{out_file}" + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end + ensure + @inside_class_file = false + end + + ## + # Generate a documentation file for each class and module + + def generate_class_files + template_file = @template_dir + 'class.rhtml' + template_file = @template_dir + 'classpage.rhtml' unless + template_file.exist? + return unless template_file.exist? + debug_msg "Generating class documentation in #{@outputdir}" + + current = nil + + # Document files are generated only for non-alias classes/modules + @classes.reject(&:is_alias_for).each do |klass| + + current = klass + + generate_class klass, template_file + end + rescue => e + error = RDoc::Error.new \ + "error generating #{current.path}: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + ## + # Generate a documentation file for each file + + def generate_file_files + page_file = @template_dir + 'page.rhtml' + fileinfo_file = @template_dir + 'fileinfo.rhtml' + + # for legacy templates + filepage_file = @template_dir + 'filepage.rhtml' unless + page_file.exist? or fileinfo_file.exist? + + return unless + page_file.exist? or fileinfo_file.exist? or filepage_file.exist? + + debug_msg "Generating file documentation in #{@outputdir}" + + out_file = nil + current = nil + + @files.each do |file| + current = file + + if file.text? and page_file.exist? then + generate_page file + next + end + + template_file = nil + out_file = @outputdir + file.path + debug_msg " working on %s (%s)" % [file.full_name, out_file] + rel_prefix = @outputdir.relative_path_from out_file.dirname + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + asset_rel_prefix = rel_prefix + @asset_rel_path + + unless filepage_file then + if file.text? then + next unless page_file.exist? + template_file = page_file + @title = file.page_name + else + next unless fileinfo_file.exist? + template_file = fileinfo_file + @title = "File: #{file.base_name}" + end + end + + @title += " - #{@options.title}" + template_file ||= filepage_file + + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here.local_variable_set(:current, current) + here + end + end + rescue => e + error = + RDoc::Error.new "error generating #{out_file}: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + ## + # Generate a page file for +file+ + + def generate_page(file) + template_file = @template_dir + 'page.rhtml' + + out_file = @outputdir + file.path + debug_msg " working on %s (%s)" % [file.full_name, out_file] + rel_prefix = @outputdir.relative_path_from out_file.dirname + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + current = file + asset_rel_prefix = rel_prefix + @asset_rel_path + + @title = "#{file.page_name} - #{@options.title}" + + debug_msg " rendering #{out_file}" + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:current, current) + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end + end + + ## + # Generates the 404 page for the RDoc servlet + + def generate_servlet_not_found(message) + template_file = @template_dir + 'servlet_not_found.rhtml' + return unless template_file.exist? + + debug_msg "Rendering the servlet 404 Not Found page..." + + rel_prefix = rel_prefix = '' + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + asset_rel_prefix = '' + + @title = 'Not Found' + + render_template template_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end + rescue => e + error = RDoc::Error.new \ + "error generating servlet_not_found: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + ## + # Generates the servlet root page for the RDoc servlet + + def generate_servlet_root(installed) + template_file = @template_dir + 'servlet_root.rhtml' + return unless template_file.exist? + + debug_msg 'Rendering the servlet root page...' + + rel_prefix = '.' + asset_rel_prefix = rel_prefix + search_index_rel_prefix = asset_rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + @title = 'Local RDoc Documentation' + + render_template template_file do |io| binding end + rescue => e + error = RDoc::Error.new \ + "error generating servlet_root: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + ## + # Generate an index page which lists all the classes which are documented. + + def generate_table_of_contents + template_file = @template_dir + 'table_of_contents.rhtml' + return unless template_file.exist? + + debug_msg "Rendering the Table of Contents..." + + out_file = @outputdir + 'table_of_contents.html' + rel_prefix = @outputdir.relative_path_from out_file.dirname + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + asset_rel_prefix = rel_prefix + @asset_rel_path + + @title = "Table of Contents - #{@options.title}" + + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end + rescue => e + error = RDoc::Error.new \ + "error generating table_of_contents.html: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + def install_rdoc_static_file(source, destination, options) # :nodoc: + return unless source.exist? + + begin + FileUtils.mkdir_p File.dirname(destination), **options + + begin + FileUtils.ln source, destination, **options + rescue Errno::EEXIST + FileUtils.rm destination + retry + end + rescue + FileUtils.cp source, destination, **options + end + end + + ## + # Prepares for generation of output from the current directory + + def setup + return if instance_variable_defined? :@outputdir + + @outputdir = Pathname.new(@options.op_dir).expand_path @base_dir + + return unless @store + + @classes = @store.all_classes_and_modules.sort + @files = @store.all_files.sort + @methods = @classes.flat_map { |m| m.method_list }.sort + @modsort = get_sorted_module_list @classes + end + + ## + # Creates a template from its components and the +body_file+. + # + # For backwards compatibility, if +body_file+ contains " + + + +#{head_file.read} + +#{body} + TEMPLATE + end + + ## + # Renders the ERb contained in +file_name+ relative to the template + # directory and returns the result based on the current context. + + def render(file_name) + template_file = @template_dir + file_name + + template = template_for template_file, false, RDoc::ERBPartial + + template.filename = template_file.to_s + + template.result @context + end + + ## + # Load and render the erb template in the given +template_file+ and write + # it out to +out_file+. + # + # Both +template_file+ and +out_file+ should be Pathname-like objects. + # + # An io will be yielded which must be captured by binding in the caller. + + def render_template(template_file, out_file = nil) # :yield: io + io_output = out_file && !@dry_run && @file_output + erb_klass = io_output ? RDoc::ERBIO : ERB + + template = template_for template_file, true, erb_klass + + if io_output then + debug_msg "Outputting to %s" % [out_file.expand_path] + + out_file.dirname.mkpath + out_file.open 'w', 0644 do |io| + io.set_encoding @options.encoding + + @context = yield io + + template_result template, @context, template_file + end + else + @context = yield nil + + output = template_result template, @context, template_file + + debug_msg " would have written %d characters to %s" % [ + output.length, out_file.expand_path + ] if @dry_run + + output end + end - Dir[(@template_dir + 'js/**/*').to_s].each do |path| - next if File.directory?(path) - next if File.basename(path).start_with?('.') + ## + # Creates the result for +template+ with +context+. If an error is raised a + # Pathname +template_file+ will indicate the file where the error occurred. + + def template_result(template, context, template_file) + template.filename = template_file.to_s + template.result context + rescue NoMethodError => e + raise RDoc::Error, "Error while evaluating %s: %s" % [ + template_file.expand_path, + e.message, + ], e.backtrace + end + + ## + # Retrieves a cache template for +file+, if present, or fills the cache. + + def template_for(file, page = true, klass = ERB) + template = @template_cache[file] + + return template if template + + if page then + template = assemble_template file + erbout = 'io' + else + template = file.read + template = template.encode @options.encoding - dst = Pathname.new(path).relative_path_from(@template_dir) + file_var = File.basename(file).sub(/\..*/, '') - install_rdoc_static_file @template_dir + path, dst, options + erbout = "_erbout_#{file_var}" end + + template = klass.new template, trim_mode: '-', eoutvar: erbout + @template_cache[file] = template + template + end + + # :stopdoc: + ParagraphExcerptRegexpOther = %r[\b\w[^./:]++\.] + # use \p/\P{letter} instead of \w/\W in Unicode + ParagraphExcerptRegexpUnicode = %r[\b\p{letter}[^./:]++\.] + # :startdoc: + + # Returns an excerpt of the comment for usage in meta description tags + def excerpt(comment) + text = case comment + when RDoc::Comment + comment.text + else + comment + end + + # Match from a capital letter to the first period, discarding any links, so + # that we don't end up matching badges in the README + pattern = ParagraphExcerptRegexpUnicode + begin + first_paragraph_match = text.match(pattern) + rescue Encoding::CompatibilityError + # The doc is non-ASCII text and encoded in other than Unicode base encodings. + raise if pattern == ParagraphExcerptRegexpOther + pattern = ParagraphExcerptRegexpOther + retry + end + return text[0...150].tr_s("\n", " ").squeeze(" ") unless first_paragraph_match + + extracted_text = first_paragraph_match[0] + second_paragraph = text.match(pattern, first_paragraph_match.end(0)) + extracted_text << " " << second_paragraph[0] if second_paragraph + + extracted_text[0...150].tr_s("\n", " ").squeeze(" ") + end + + def generate_ancestor_list(ancestors, klass) + return '' if ancestors.empty? + + ancestor = ancestors.shift + content = +'' + end + + def generate_class_link(klass, rel_prefix) + if klass.display? + %(#{klass.name}) + else + %(#{klass.name}) + end + end + + def generate_class_index_content(classes, rel_prefix) + grouped_classes = group_classes_by_namespace_for_sidebar(classes) + return '' unless top = grouped_classes[nil] + + solo = top.one? { |klass| klass.display? } + traverse_classes(top, grouped_classes, rel_prefix, solo) + end + + def traverse_classes(klasses, grouped_classes, rel_prefix, solo = false) + content = +'" + end + + def group_classes_by_namespace_for_sidebar(classes) + grouped_classes = classes.group_by do |klass| + klass.full_name[/\A[^:]++(?:::[^:]++(?=::))*+(?=::[^:]*+\z)/] + end.select do |_, klasses| + klasses.any?(&:display?) + end + + grouped_classes.values.each(&:uniq!) + grouped_classes end ## @@ -134,6 +795,23 @@ def resolve_url(rel_prefix, url) private + def nesting_namespaces_to_class_modules(klass) + tree = {} + + klass.nesting_namespaces.zip(klass.fully_qualified_nesting_namespaces) do |ns, fqns| + tree[ns] = @store.classes_hash[fqns] || @store.modules_hash[fqns] + end + + tree + end + + def generate_nesting_namespaces_breadcrumb(klass, rel_prefix) + nesting_namespaces_to_class_modules(klass).map do |namespace, class_module| + path = class_module ? (rel_prefix + class_module.path).to_s : "" + { name: namespace, path: path, self: klass.full_name == class_module&.full_name } + end + end + def build_class_module_entry(klass) type = case klass when RDoc::NormalClass then 'class' diff --git a/lib/rdoc/generator/darkfish.rb b/lib/rdoc/generator/darkfish.rb deleted file mode 100644 index 9a81b74688..0000000000 --- a/lib/rdoc/generator/darkfish.rb +++ /dev/null @@ -1,818 +0,0 @@ -# frozen_string_literal: true -# -*- mode: ruby; ruby-indent-level: 2; tab-width: 2 -*- - -require 'erb' -require 'fileutils' -require 'pathname' -require_relative 'markup' - -## -# Darkfish RDoc HTML Generator -# -# $Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $ -# -# == Author/s -# * Michael Granger (ged@FaerieMUD.org) -# -# == Contributors -# * Mahlon E. Smith (mahlon@martini.nu) -# * Eric Hodel (drbrain@segment7.net) -# -# == License -# -# Copyright (c) 2007, 2008, Michael Granger. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# * Neither the name of the author/s, nor the names of the project's -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# == Attributions -# -# Darkfish uses the {Silk Icons}[http://www.famfamfam.com/lab/icons/silk/] set -# by Mark James. - -class RDoc::Generator::Darkfish - - RDoc::RDoc.add_generator self - - include ERB::Util - - ## - # Stylesheets, fonts, etc. that are included in RDoc. - - BUILTIN_STYLE_ITEMS = # :nodoc: - %w[ - css/fonts.css - fonts/Lato-Light.ttf - fonts/Lato-LightItalic.ttf - fonts/Lato-Regular.ttf - fonts/Lato-RegularItalic.ttf - fonts/SourceCodePro-Bold.ttf - fonts/SourceCodePro-Regular.ttf - css/rdoc.css - ] - - ## - # Release Version - - VERSION = '3' - - ## - # Description of this generator - - DESCRIPTION = 'HTML generator, written by Michael Granger' - - ## - # The relative path to style sheets and javascript. By default this is set - # the same as the rel_prefix. - - attr_accessor :asset_rel_path - - ## - # The path to generate files into, combined with --op from the - # options for a full path. - - attr_reader :base_dir - - ## - # Classes and modules to be used by this generator, not necessarily - # displayed. See also #modsort - - attr_reader :classes - - ## - # No files will be written when dry_run is true. - - attr_accessor :dry_run - - ## - # When false the generate methods return a String instead of writing to a - # file. The default is true. - - attr_accessor :file_output - - ## - # Files to be displayed by this generator - - attr_reader :files - - ## - # The JSON index generator for this Darkfish generator - - attr_reader :json_index - - ## - # Methods to be displayed by this generator - - attr_reader :methods - - ## - # Sorted list of classes and modules to be displayed by this generator - - attr_reader :modsort - - ## - # The RDoc::Store that is the source of the generated content - - attr_reader :store - - ## - # The directory where the template files live - - attr_reader :template_dir # :nodoc: - - ## - # The output directory - - attr_reader :outputdir - - ## - # Initialize a few instance variables before we start - - def initialize(store, options) - @store = store - @options = options - - @asset_rel_path = '' - @base_dir = Pathname.pwd.expand_path - @dry_run = @options.dry_run - @file_output = true - @template_dir = Pathname.new options.template_dir - @template_cache = {} - - @classes = nil - @context = nil - @files = nil - @methods = nil - @modsort = nil - - @json_index = RDoc::Generator::JsonIndex.new self, options - end - - ## - # Output progress information if debugging is enabled - - def debug_msg(*msg) - return unless $DEBUG_RDOC - $stderr.puts(*msg) - end - - ## - # Create the directories the generated docs will live in if they don't - # already exist. - - def gen_sub_directories - @outputdir.mkpath - end - - ## - # Copy over the stylesheet into the appropriate place in the output - # directory. - - def write_style_sheet - debug_msg "Copying static files" - options = { :verbose => $DEBUG_RDOC, :noop => @dry_run } - - BUILTIN_STYLE_ITEMS.each do |item| - install_rdoc_static_file @template_dir + item, "./#{item}", options - end - - unless @options.template_stylesheets.empty? - FileUtils.cp @options.template_stylesheets, '.', **options - end - - Dir[(@template_dir + "{js,images}/**/*").to_s].each do |path| - next if File.directory? path - next if File.basename(path) =~ /^\./ - - dst = Pathname.new(path).relative_path_from @template_dir - - install_rdoc_static_file @template_dir + path, dst, options - end - end - - ## - # Build the initial indices and output objects based on an array of TopLevel - # objects containing the extracted information. - - def generate - setup - - write_style_sheet - generate_index - generate_class_files - generate_file_files - generate_table_of_contents - @json_index.generate - @json_index.generate_gzipped - - copy_static - - rescue => e - debug_msg "%s: %s\n %s" % [ - e.class.name, e.message, e.backtrace.join("\n ") - ] - - raise - end - - ## - # Copies static files from the static_path into the output directory - - def copy_static - return if @options.static_path.empty? - - fu_options = { :verbose => $DEBUG_RDOC, :noop => @dry_run } - - @options.static_path.each do |path| - unless File.directory? path then - FileUtils.install path, @outputdir, **fu_options.merge(:mode => 0644) - next - end - - Dir.chdir path do - Dir[File.join('**', '*')].each do |entry| - dest_file = @outputdir + entry - - if File.directory? entry then - FileUtils.mkdir_p entry, **fu_options - else - FileUtils.install entry, dest_file, **fu_options.merge(:mode => 0644) - end - end - end - end - end - - ## - # Return a list of the documented modules sorted by salience first, then - # by name. - - def get_sorted_module_list(classes) - classes.select do |klass| - klass.display? - end.sort - end - - ## - # Generate an index page which lists all the classes which are documented. - - def generate_index - template_file = @template_dir + 'index.rhtml' - return unless template_file.exist? - - debug_msg "Rendering the index page..." - - out_file = @base_dir + @options.op_dir + 'index.html' - rel_prefix = @outputdir.relative_path_from out_file.dirname - search_index_rel_prefix = rel_prefix - search_index_rel_prefix += @asset_rel_path if @file_output - - asset_rel_prefix = rel_prefix + @asset_rel_path - - @title = @options.title - @main_page = @files.find { |f| f.full_name == @options.main_page } - - render_template template_file, out_file do |io| - here = binding - # suppress 1.9.3 warning - here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) - # some partials rely on the presence of current variable to render - here.local_variable_set(:current, @main_page) if @main_page - here - end - rescue => e - error = RDoc::Error.new \ - "error generating index.html: #{e.message} (#{e.class})" - error.set_backtrace e.backtrace - - raise error - end - - ## - # Generates a class file for +klass+ - - def generate_class(klass, template_file = nil) - # This is used to auto-collapse Pages section on class/module pages - @inside_class_file = true - current = klass - - template_file ||= @template_dir + 'class.rhtml' - - debug_msg " working on %s (%s)" % [klass.full_name, klass.path] - out_file = @outputdir + klass.path - rel_prefix = @outputdir.relative_path_from out_file.dirname - search_index_rel_prefix = rel_prefix - search_index_rel_prefix += @asset_rel_path if @file_output - - asset_rel_prefix = rel_prefix + @asset_rel_path - - breadcrumb = # used in templates - breadcrumb = generate_nesting_namespaces_breadcrumb(current, rel_prefix) - - @title = "#{klass.type} #{klass.full_name} - #{@options.title}" - - debug_msg " rendering #{out_file}" - render_template template_file, out_file do |io| - here = binding - # suppress 1.9.3 warning - here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) - here - end - ensure - @inside_class_file = false - end - - ## - # Generate a documentation file for each class and module - - def generate_class_files - template_file = @template_dir + 'class.rhtml' - template_file = @template_dir + 'classpage.rhtml' unless - template_file.exist? - return unless template_file.exist? - debug_msg "Generating class documentation in #{@outputdir}" - - current = nil - - # Document files are generated only for non-alias classes/modules - @classes.reject(&:is_alias_for).each do |klass| - - current = klass - - generate_class klass, template_file - end - rescue => e - error = RDoc::Error.new \ - "error generating #{current.path}: #{e.message} (#{e.class})" - error.set_backtrace e.backtrace - - raise error - end - - ## - # Generate a documentation file for each file - - def generate_file_files - page_file = @template_dir + 'page.rhtml' - fileinfo_file = @template_dir + 'fileinfo.rhtml' - - # for legacy templates - filepage_file = @template_dir + 'filepage.rhtml' unless - page_file.exist? or fileinfo_file.exist? - - return unless - page_file.exist? or fileinfo_file.exist? or filepage_file.exist? - - debug_msg "Generating file documentation in #{@outputdir}" - - out_file = nil - current = nil - - @files.each do |file| - current = file - - if file.text? and page_file.exist? then - generate_page file - next - end - - template_file = nil - out_file = @outputdir + file.path - debug_msg " working on %s (%s)" % [file.full_name, out_file] - rel_prefix = @outputdir.relative_path_from out_file.dirname - search_index_rel_prefix = rel_prefix - search_index_rel_prefix += @asset_rel_path if @file_output - - asset_rel_prefix = rel_prefix + @asset_rel_path - - unless filepage_file then - if file.text? then - next unless page_file.exist? - template_file = page_file - @title = file.page_name - else - next unless fileinfo_file.exist? - template_file = fileinfo_file - @title = "File: #{file.base_name}" - end - end - - @title += " - #{@options.title}" - template_file ||= filepage_file - - render_template template_file, out_file do |io| - here = binding - # suppress 1.9.3 warning - here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) - here.local_variable_set(:current, current) - here - end - end - rescue => e - error = - RDoc::Error.new "error generating #{out_file}: #{e.message} (#{e.class})" - error.set_backtrace e.backtrace - - raise error - end - - ## - # Generate a page file for +file+ - - def generate_page(file) - template_file = @template_dir + 'page.rhtml' - - out_file = @outputdir + file.path - debug_msg " working on %s (%s)" % [file.full_name, out_file] - rel_prefix = @outputdir.relative_path_from out_file.dirname - search_index_rel_prefix = rel_prefix - search_index_rel_prefix += @asset_rel_path if @file_output - - current = file - asset_rel_prefix = rel_prefix + @asset_rel_path - - @title = "#{file.page_name} - #{@options.title}" - - debug_msg " rendering #{out_file}" - render_template template_file, out_file do |io| - here = binding - # suppress 1.9.3 warning - here.local_variable_set(:current, current) - here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) - here - end - end - - ## - # Generates the 404 page for the RDoc servlet - - def generate_servlet_not_found(message) - template_file = @template_dir + 'servlet_not_found.rhtml' - return unless template_file.exist? - - debug_msg "Rendering the servlet 404 Not Found page..." - - rel_prefix = rel_prefix = '' - search_index_rel_prefix = rel_prefix - search_index_rel_prefix += @asset_rel_path if @file_output - - asset_rel_prefix = '' - - @title = 'Not Found' - - render_template template_file do |io| - here = binding - # suppress 1.9.3 warning - here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) - here - end - rescue => e - error = RDoc::Error.new \ - "error generating servlet_not_found: #{e.message} (#{e.class})" - error.set_backtrace e.backtrace - - raise error - end - - ## - # Generates the servlet root page for the RDoc servlet - - def generate_servlet_root(installed) - template_file = @template_dir + 'servlet_root.rhtml' - return unless template_file.exist? - - debug_msg 'Rendering the servlet root page...' - - rel_prefix = '.' - asset_rel_prefix = rel_prefix - search_index_rel_prefix = asset_rel_prefix - search_index_rel_prefix += @asset_rel_path if @file_output - - @title = 'Local RDoc Documentation' - - render_template template_file do |io| binding end - rescue => e - error = RDoc::Error.new \ - "error generating servlet_root: #{e.message} (#{e.class})" - error.set_backtrace e.backtrace - - raise error - end - - ## - # Generate an index page which lists all the classes which are documented. - - def generate_table_of_contents - template_file = @template_dir + 'table_of_contents.rhtml' - return unless template_file.exist? - - debug_msg "Rendering the Table of Contents..." - - out_file = @outputdir + 'table_of_contents.html' - rel_prefix = @outputdir.relative_path_from out_file.dirname - search_index_rel_prefix = rel_prefix - search_index_rel_prefix += @asset_rel_path if @file_output - - asset_rel_prefix = rel_prefix + @asset_rel_path - - @title = "Table of Contents - #{@options.title}" - - render_template template_file, out_file do |io| - here = binding - # suppress 1.9.3 warning - here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) - here - end - rescue => e - error = RDoc::Error.new \ - "error generating table_of_contents.html: #{e.message} (#{e.class})" - error.set_backtrace e.backtrace - - raise error - end - - def install_rdoc_static_file(source, destination, options) # :nodoc: - return unless source.exist? - - begin - FileUtils.mkdir_p File.dirname(destination), **options - - begin - FileUtils.ln source, destination, **options - rescue Errno::EEXIST - FileUtils.rm destination - retry - end - rescue - FileUtils.cp source, destination, **options - end - end - - ## - # Prepares for generation of output from the current directory - - def setup - return if instance_variable_defined? :@outputdir - - @outputdir = Pathname.new(@options.op_dir).expand_path @base_dir - - return unless @store - - @classes = @store.all_classes_and_modules.sort - @files = @store.all_files.sort - @methods = @classes.flat_map { |m| m.method_list }.sort - @modsort = get_sorted_module_list @classes - end - - ## - # Creates a template from its components and the +body_file+. - # - # For backwards compatibility, if +body_file+ contains " - - - -#{head_file.read} - -#{body} - TEMPLATE - end - - ## - # Renders the ERb contained in +file_name+ relative to the template - # directory and returns the result based on the current context. - - def render(file_name) - template_file = @template_dir + file_name - - template = template_for template_file, false, RDoc::ERBPartial - - template.filename = template_file.to_s - - template.result @context - end - - ## - # Load and render the erb template in the given +template_file+ and write - # it out to +out_file+. - # - # Both +template_file+ and +out_file+ should be Pathname-like objects. - # - # An io will be yielded which must be captured by binding in the caller. - - def render_template(template_file, out_file = nil) # :yield: io - io_output = out_file && !@dry_run && @file_output - erb_klass = io_output ? RDoc::ERBIO : ERB - - template = template_for template_file, true, erb_klass - - if io_output then - debug_msg "Outputting to %s" % [out_file.expand_path] - - out_file.dirname.mkpath - out_file.open 'w', 0644 do |io| - io.set_encoding @options.encoding - - @context = yield io - - template_result template, @context, template_file - end - else - @context = yield nil - - output = template_result template, @context, template_file - - debug_msg " would have written %d characters to %s" % [ - output.length, out_file.expand_path - ] if @dry_run - - output - end - end - - ## - # Creates the result for +template+ with +context+. If an error is raised a - # Pathname +template_file+ will indicate the file where the error occurred. - - def template_result(template, context, template_file) - template.filename = template_file.to_s - template.result context - rescue NoMethodError => e - raise RDoc::Error, "Error while evaluating %s: %s" % [ - template_file.expand_path, - e.message, - ], e.backtrace - end - - ## - # Retrieves a cache template for +file+, if present, or fills the cache. - - def template_for(file, page = true, klass = ERB) - template = @template_cache[file] - - return template if template - - if page then - template = assemble_template file - erbout = 'io' - else - template = file.read - template = template.encode @options.encoding - - file_var = File.basename(file).sub(/\..*/, '') - - erbout = "_erbout_#{file_var}" - end - - template = klass.new template, trim_mode: '-', eoutvar: erbout - @template_cache[file] = template - template - end - - # :stopdoc: - ParagraphExcerptRegexpOther = %r[\b\w[^./:]++\.] - # use \p/\P{letter} instead of \w/\W in Unicode - ParagraphExcerptRegexpUnicode = %r[\b\p{letter}[^./:]++\.] - # :startdoc: - - # Returns an excerpt of the comment for usage in meta description tags - def excerpt(comment) - text = case comment - when RDoc::Comment - comment.text - else - comment - end - - # Match from a capital letter to the first period, discarding any links, so - # that we don't end up matching badges in the README - pattern = ParagraphExcerptRegexpUnicode - begin - first_paragraph_match = text.match(pattern) - rescue Encoding::CompatibilityError - # The doc is non-ASCII text and encoded in other than Unicode base encodings. - raise if pattern == ParagraphExcerptRegexpOther - pattern = ParagraphExcerptRegexpOther - retry - end - return text[0...150].tr_s("\n", " ").squeeze(" ") unless first_paragraph_match - - extracted_text = first_paragraph_match[0] - second_paragraph = text.match(pattern, first_paragraph_match.end(0)) - extracted_text << " " << second_paragraph[0] if second_paragraph - - extracted_text[0...150].tr_s("\n", " ").squeeze(" ") - end - - def generate_ancestor_list(ancestors, klass) - return '' if ancestors.empty? - - ancestor = ancestors.shift - content = +'
  • ' - - if ancestor.is_a?(RDoc::NormalClass) - content << "#{ancestor.full_name}" - else - content << ancestor.to_s - end - - # Recursively call the method for the remaining ancestors - content << generate_ancestor_list(ancestors, klass) - - content << '
' - end - - def generate_class_link(klass, rel_prefix) - if klass.display? - %(#{klass.name}) - else - %(#{klass.name}) - end - end - - def generate_class_index_content(classes, rel_prefix) - grouped_classes = group_classes_by_namespace_for_sidebar(classes) - return '' unless top = grouped_classes[nil] - - solo = top.one? { |klass| klass.display? } - traverse_classes(top, grouped_classes, rel_prefix, solo) - end - - def traverse_classes(klasses, grouped_classes, rel_prefix, solo = false) - content = +'" - end - - def group_classes_by_namespace_for_sidebar(classes) - grouped_classes = classes.group_by do |klass| - klass.full_name[/\A[^:]++(?:::[^:]++(?=::))*+(?=::[^:]*+\z)/] - end.select do |_, klasses| - klasses.any?(&:display?) - end - - grouped_classes.values.each(&:uniq!) - grouped_classes - end - - private - - def nesting_namespaces_to_class_modules(klass) - tree = {} - - klass.nesting_namespaces.zip(klass.fully_qualified_nesting_namespaces) do |ns, fqns| - tree[ns] = @store.classes_hash[fqns] || @store.modules_hash[fqns] - end - - tree - end - - def generate_nesting_namespaces_breadcrumb(klass, rel_prefix) - nesting_namespaces_to_class_modules(klass).map do |namespace, class_module| - path = class_module ? (rel_prefix + class_module.path).to_s : "" - { name: namespace, path: path, self: klass.full_name == class_module&.full_name } - end - end -end diff --git a/lib/rdoc/generator/json_index.rb b/lib/rdoc/generator/json_index.rb deleted file mode 100644 index c61391d630..0000000000 --- a/lib/rdoc/generator/json_index.rb +++ /dev/null @@ -1,284 +0,0 @@ -# frozen_string_literal: true -require 'json' -begin - require 'zlib' -rescue LoadError -end - -## -# The JsonIndex generator is designed to complement an HTML generator and -# produces a JSON search index. This generator is derived from sdoc by -# Vladimir Kolesnikov and contains verbatim code written by him. -# -# This generator is designed to be used with a regular HTML generator: -# -# class RDoc::Generator::Darkfish -# def initialize options -# # ... -# @base_dir = Pathname.pwd.expand_path -# -# @json_index = RDoc::Generator::JsonIndex.new self, options -# end -# -# def generate -# # ... -# @json_index.generate -# end -# end -# -# == Index Format -# -# The index is output as a JSON file assigned to the global variable -# +search_data+. The structure is: -# -# var search_data = { -# "index": { -# "searchIndex": -# ["a", "b", ...], -# "longSearchIndex": -# ["a", "a::b", ...], -# "info": [ -# ["A", "A", "A.html", "", ""], -# ["B", "A::B", "A::B.html", "", ""], -# ... -# ] -# } -# } -# -# The same item is described across the +searchIndex+, +longSearchIndex+ and -# +info+ fields. The +searchIndex+ field contains the item's short name, the -# +longSearchIndex+ field contains the full_name (when appropriate) and the -# +info+ field contains the item's name, full_name, path, parameters and a -# snippet of the item's comment. -# -# == LICENSE -# -# Copyright (c) 2009 Vladimir Kolesnikov -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class RDoc::Generator::JsonIndex - - include RDoc::Text - - ## - # Where the search index lives in the generated output - - SEARCH_INDEX_FILE = File.join 'js', 'search_index.js' - - attr_reader :index # :nodoc: - - ## - # Creates a new generator. - # +options+ are the same options passed to the parent generator. - - def initialize(parent_generator, options) - @parent_generator = parent_generator - @store = parent_generator.store - @options = options - - @template_dir = File.expand_path '../template/json_index', __FILE__ - @base_dir = @parent_generator.base_dir - - @classes = nil - @files = nil - @index = nil - end - - ## - # Builds the JSON index as a Hash. - - def build_index - reset @store.all_files.sort, @store.all_classes_and_modules.sort - - index_classes - index_methods - index_pages - - { :index => @index } - end - - ## - # Output progress information if debugging is enabled - - def debug_msg(*msg) - return unless $DEBUG_RDOC - $stderr.puts(*msg) - end - - ## - # Writes the JSON index to disk - - def generate - debug_msg "Generating JSON index" - - debug_msg " writing search index to %s" % SEARCH_INDEX_FILE - data = build_index - - return if @options.dry_run - - out_dir = @base_dir + @options.op_dir - index_file = out_dir + SEARCH_INDEX_FILE - - FileUtils.mkdir_p index_file.dirname, :verbose => $DEBUG_RDOC - - index_file.open 'w', 0644 do |io| - io.set_encoding Encoding::UTF_8 - io.write 'var search_data = ' - - JSON.dump data, io, 0 - end - unless ENV['SOURCE_DATE_EPOCH'].nil? - index_file.utime index_file.atime, Time.at(ENV['SOURCE_DATE_EPOCH'].to_i).gmtime - end - - Dir.chdir @template_dir do - Dir['**/*.js'].each do |source| - dest = File.join out_dir, source - - FileUtils.install source, dest, :mode => 0644, :preserve => true, :verbose => $DEBUG_RDOC - end - end - end - - ## - # Compress the search_index.js file using gzip - - def generate_gzipped - return if @options.dry_run or not defined?(Zlib) - - debug_msg "Compressing generated JSON index" - out_dir = @base_dir + @options.op_dir - - search_index_file = out_dir + SEARCH_INDEX_FILE - outfile = out_dir + "#{search_index_file}.gz" - - debug_msg "Reading the JSON index file from %s" % search_index_file - search_index = search_index_file.read(mode: 'r:utf-8') - - debug_msg "Writing gzipped search index to %s" % outfile - - Zlib::GzipWriter.open(outfile) do |gz| - gz.mtime = File.mtime(search_index_file) - gz.orig_name = search_index_file.basename.to_s - gz.write search_index - gz.close - end - - # GZip the rest of the js files - Dir.chdir @template_dir do - Dir['**/*.js'].each do |source| - dest = out_dir + source - outfile = out_dir + "#{dest}.gz" - - debug_msg "Reading the original js file from %s" % dest - data = dest.read - - debug_msg "Writing gzipped file to %s" % outfile - - Zlib::GzipWriter.open(outfile) do |gz| - gz.mtime = File.mtime(dest) - gz.orig_name = dest.basename.to_s - gz.write data - gz.close - end - end - end - end - - ## - # Adds classes and modules to the index - - def index_classes - debug_msg " generating class search index" - - documented = @classes.uniq.select do |klass| - klass.document_self_or_methods - end - - documented.each do |klass| - debug_msg " #{klass.full_name}" - record = klass.search_record - @index[:searchIndex] << search_string(record.shift) - @index[:longSearchIndex] << search_string(record.shift) - @index[:info] << record - end - end - - ## - # Adds methods to the index - - def index_methods - debug_msg " generating method search index" - - list = @classes.uniq.flat_map do |klass| - klass.method_list - end.sort_by do |method| - [method.name, method.parent.full_name] - end - - list.each do |method| - debug_msg " #{method.full_name}" - record = method.search_record - @index[:searchIndex] << "#{search_string record.shift}()" - @index[:longSearchIndex] << "#{search_string record.shift}()" - @index[:info] << record - end - end - - ## - # Adds pages to the index - - def index_pages - debug_msg " generating pages search index" - - pages = @files.select do |file| - file.text? - end - - pages.each do |page| - debug_msg " #{page.page_name}" - record = page.search_record - @index[:searchIndex] << search_string(record.shift) - @index[:longSearchIndex] << '' - record.shift - @index[:info] << record - end - end - - def reset(files, classes) # :nodoc: - @files = files - @classes = classes - - @index = { - :searchIndex => [], - :longSearchIndex => [], - :info => [] - } - end - - ## - # Removes whitespace and downcases +string+ - - def search_string(string) - string.downcase.gsub(/\s/, '') - end - -end diff --git a/lib/rdoc/generator/template/darkfish/.document b/lib/rdoc/generator/template/darkfish/.document deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/lib/rdoc/generator/template/darkfish/_footer.rhtml b/lib/rdoc/generator/template/darkfish/_footer.rhtml deleted file mode 100644 index 620cf01484..0000000000 --- a/lib/rdoc/generator/template/darkfish/_footer.rhtml +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/lib/rdoc/generator/template/darkfish/_head.rhtml b/lib/rdoc/generator/template/darkfish/_head.rhtml deleted file mode 100644 index c90635877a..0000000000 --- a/lib/rdoc/generator/template/darkfish/_head.rhtml +++ /dev/null @@ -1,43 +0,0 @@ - - - -<%= h @title %> - -<%- if defined?(klass) %> - "> - - <%- if klass.comment.empty? %> - "> - <%- else %> - "> - <%- end %> -<%- elsif defined?(file) %> - - "> -<%- elsif @title %> - -<% description = @main_page ? "#{@title}: #{excerpt(@main_page.comment)}" : "Documentation for #{@title}" %> - -<%- end %> - -<%- if canonical_url = @options.canonical_root %> -<% canonical_url = current.canonical_url if defined?(current) %> - -<%- end %> - - - - - - - - - - - -<%- @options.template_stylesheets.each do |stylesheet| %> - -<%- end %> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml deleted file mode 100644 index d33ecd43f7..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml deleted file mode 100644 index b83c1ef29c..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +++ /dev/null @@ -1,15 +0,0 @@ -<%- unless klass.extends.empty? then %> - -<%- end %> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml deleted file mode 100644 index cc2255f861..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +++ /dev/null @@ -1,15 +0,0 @@ -<%- unless klass.includes.empty? then %> - -<%- end %> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml deleted file mode 100644 index b20310556a..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml deleted file mode 100644 index 67bf7c47aa..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +++ /dev/null @@ -1,21 +0,0 @@ -<% if (class_methods = klass.class_method_list.sort).any? %> - -<% end %> - -<% if (instance_methods = klass.instance_methods.sort).any? %> - -<% end %> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml deleted file mode 100644 index d7f330840a..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml deleted file mode 100644 index 1d93300124..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +++ /dev/null @@ -1,32 +0,0 @@ -<%- simple_files = @files.select { |f| f.text? } %> -<%- if defined?(current) %> - <%- dir = current.full_name[%r{\A[^/]+(?=/)}] || current.page_name %> -<%- end %> -<%- unless simple_files.empty? then %> - -<%- end %> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml deleted file mode 100644 index 497b4a669a..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +++ /dev/null @@ -1,6 +0,0 @@ -<%- if klass.type == 'class' && (ancestors = klass.super_classes).any? %> - -<%- end %> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml deleted file mode 100644 index c41d9990cf..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml deleted file mode 100644 index b275657c8e..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +++ /dev/null @@ -1,11 +0,0 @@ -<%- unless klass.sections.length == 1 then %> - -<%- end %> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml deleted file mode 100644 index 7561e4c05a..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +++ /dev/null @@ -1,39 +0,0 @@ -<%- comment = if current.respond_to? :comment_location then - current.comment_location - else - current.comment - end - table = current.parse(comment).table_of_contents.dup - - if table.length > 1 then %> - -<%- end %> diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml deleted file mode 100644 index ed2cbe31a0..0000000000 --- a/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/lib/rdoc/generator/template/darkfish/class.rhtml b/lib/rdoc/generator/template/darkfish/class.rhtml deleted file mode 100644 index 50fbe2873f..0000000000 --- a/lib/rdoc/generator/template/darkfish/class.rhtml +++ /dev/null @@ -1,223 +0,0 @@ - -<%= render '_sidebar_toggle.rhtml' %> - - - -
- <%# If nesting level is 1, breadcrumb list is not needed %> - <% if breadcrumb.size > 1 %> - - <% end %> - - -

- <%= klass.type %> <%= klass.full_name %> -

- -
- <%= klass.description %> -
- - <%- klass.each_section do |section, constants, attributes| %> - - -<%- end %> -
- diff --git a/lib/rdoc/generator/template/darkfish/css/fonts.css b/lib/rdoc/generator/template/darkfish/css/fonts.css deleted file mode 100644 index 57302b5183..0000000000 --- a/lib/rdoc/generator/template/darkfish/css/fonts.css +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), - * with Reserved Font Name "Source". All Rights Reserved. Source is a - * trademark of Adobe Systems Incorporated in the United States and/or other - * countries. - * - * This Font Software is licensed under the SIL Open Font License, Version - * 1.1. - * - * This license is copied below, and is also available with a FAQ at: - * http://scripts.sil.org/OFL - */ - -@font-face { - font-family: "Source Code Pro"; - font-style: normal; - font-weight: 400; - src: local("Source Code Pro"), - local("SourceCodePro-Regular"), - url("../fonts/SourceCodePro-Regular.ttf") format("truetype"); -} - -@font-face { - font-family: "Source Code Pro"; - font-style: normal; - font-weight: 700; - src: local("Source Code Pro Bold"), - local("SourceCodePro-Bold"), - url("../fonts/SourceCodePro-Bold.ttf") format("truetype"); -} - -/* - * Copyright (c) 2010, Łukasz Dziedzic (dziedzic@typoland.com), - * with Reserved Font Name Lato. - * - * This Font Software is licensed under the SIL Open Font License, Version - * 1.1. - * - * This license is copied below, and is also available with a FAQ at: - * http://scripts.sil.org/OFL - */ - -@font-face { - font-family: "Lato"; - font-style: normal; - font-weight: 300; - src: local("Lato Light"), - local("Lato-Light"), - url("../fonts/Lato-Light.ttf") format("truetype"); -} - -@font-face { - font-family: "Lato"; - font-style: italic; - font-weight: 300; - src: local("Lato Light Italic"), - local("Lato-LightItalic"), - url("../fonts/Lato-LightItalic.ttf") format("truetype"); -} - -@font-face { - font-family: "Lato"; - font-style: normal; - font-weight: 700; - src: local("Lato Regular"), - local("Lato-Regular"), - url("../fonts/Lato-Regular.ttf") format("truetype"); -} - -@font-face { - font-family: "Lato"; - font-style: italic; - font-weight: 700; - src: local("Lato Italic"), - local("Lato-Italic"), - url("../fonts/Lato-RegularItalic.ttf") format("truetype"); -} - -/* - * ----------------------------------------------------------- - * SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 - * ----------------------------------------------------------- - * - * PREAMBLE - * The goals of the Open Font License (OFL) are to stimulate worldwide - * development of collaborative font projects, to support the font creation - * efforts of academic and linguistic communities, and to provide a free and - * open framework in which fonts may be shared and improved in partnership - * with others. - * - * The OFL allows the licensed fonts to be used, studied, modified and - * redistributed freely as long as they are not sold by themselves. The - * fonts, including any derivative works, can be bundled, embedded, - * redistributed and/or sold with any software provided that any reserved - * names are not used by derivative works. The fonts and derivatives, - * however, cannot be released under any other type of license. The - * requirement for fonts to remain under this license does not apply - * to any document created using the fonts or their derivatives. - * - * DEFINITIONS - * "Font Software" refers to the set of files released by the Copyright - * Holder(s) under this license and clearly marked as such. This may - * include source files, build scripts and documentation. - * - * "Reserved Font Name" refers to any names specified as such after the - * copyright statement(s). - * - * "Original Version" refers to the collection of Font Software components as - * distributed by the Copyright Holder(s). - * - * "Modified Version" refers to any derivative made by adding to, deleting, - * or substituting -- in part or in whole -- any of the components of the - * Original Version, by changing formats or by porting the Font Software to a - * new environment. - * - * "Author" refers to any designer, engineer, programmer, technical - * writer or other person who contributed to the Font Software. - * - * PERMISSION & CONDITIONS - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of the Font Software, to use, study, copy, merge, embed, modify, - * redistribute, and sell modified and unmodified copies of the Font - * Software, subject to the following conditions: - * - * 1) Neither the Font Software nor any of its individual components, - * in Original or Modified Versions, may be sold by itself. - * - * 2) Original or Modified Versions of the Font Software may be bundled, - * redistributed and/or sold with any software, provided that each copy - * contains the above copyright notice and this license. These can be - * included either as stand-alone text files, human-readable headers or - * in the appropriate machine-readable metadata fields within text or - * binary files as long as those fields can be easily viewed by the user. - * - * 3) No Modified Version of the Font Software may use the Reserved Font - * Name(s) unless explicit written permission is granted by the corresponding - * Copyright Holder. This restriction only applies to the primary font name as - * presented to the users. - * - * 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font - * Software shall not be used to promote, endorse or advertise any - * Modified Version, except to acknowledge the contribution(s) of the - * Copyright Holder(s) and the Author(s) or with their explicit written - * permission. - * - * 5) The Font Software, modified or unmodified, in part or in whole, - * must be distributed entirely under this license, and must not be - * distributed under any other license. The requirement for fonts to - * remain under this license does not apply to any document created - * using the Font Software. - * - * TERMINATION - * This license becomes null and void if any of the above conditions are - * not met. - * - * DISCLAIMER - * THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT - * OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM - * OTHER DEALINGS IN THE FONT SOFTWARE. - */ - diff --git a/lib/rdoc/generator/template/darkfish/css/rdoc.css b/lib/rdoc/generator/template/darkfish/css/rdoc.css deleted file mode 100644 index 87bf24c36e..0000000000 --- a/lib/rdoc/generator/template/darkfish/css/rdoc.css +++ /dev/null @@ -1,702 +0,0 @@ -/* - * "Darkfish" RDoc CSS - * $Id: rdoc.css 54 2009-01-27 01:09:48Z deveiant $ - * - * Author: Michael Granger - * - */ - -/* vim: ft=css et sw=2 ts=2 sts=2 */ - -/* 1. Variables and Root Styles */ -:root { - --sidebar-width: 300px; - --highlight-color: #cc342d; /* Reddish color for accents and headings */ - --secondary-highlight-color: #c83045; /* Darker reddish color for secondary highlights */ - --text-color: #505050; /* Dark bluish-grey for text */ - --background-color: #fefefe; /* Near white background */ - --code-block-background-color: #f6f6f3; /* Slightly darker grey for code blocks */ - --link-color: #42405F; /* Dark bluish-grey for links */ - --link-hover-color: var(--highlight-color); /* Reddish color on hover */ - --border-color: #e0e0e0;; /* General border color */ - --source-code-toggle-color: var(--secondary-highlight-color); - --scrollbar-thumb-hover-background: #505050; /* Hover color for scrollbar thumb */ - --table-header-background-color: #eceaed; - --table-td-background-color: #f5f4f6; - - /* Font family variables */ - --font-primary: 'Segoe UI', 'Verdana', 'Arial', sans-serif; - --font-heading: 'Helvetica', 'Arial', sans-serif; - --font-code: monospace; -} - -/* 2. Global Styles */ -body { - background: var(--background-color); - font-family: var(--font-primary); - font-weight: 400; - color: var(--text-color); - line-height: 1.6; - - /* Layout */ - display: flex; - flex-direction: column; - min-height: 100vh; - margin: 0; -} - -/* 3. Typography */ -h1 span, -h2 span, -h3 span, -h4 span, -h5 span, -h6 span { - position: relative; - - display: none; - padding-left: 1em; - line-height: 0; - vertical-align: baseline; - font-size: 10px; -} - -h1 span { top: -1.3em; } -h2 span { top: -1.2em; } -h3 span { top: -1.0em; } -h4 span { top: -0.8em; } -h5 span { top: -0.5em; } -h6 span { top: -0.5em; } - -h1:hover span, -h2:hover span, -h3:hover span, -h4:hover span, -h5:hover span, -h6:hover span { - display: inline; -} - -h1:target, -h2:target, -h3:target, -h4:target, -h5:target, -h6:target { - margin-left: -10px; - border-left: 10px solid var(--border-color); - scroll-margin-top: 1rem; -} - -main .anchor-link:target { - scroll-margin-top: 1rem; -} - -/* Legacy anchor for backward compatibility with old label- prefix links */ -.legacy-anchor { - display: block; - position: relative; - visibility: hidden; - scroll-margin-top: 1rem; -} - -/* When a legacy anchor is targeted, highlight the next heading sibling */ -.legacy-anchor:target + h1, -.legacy-anchor:target + h2, -.legacy-anchor:target + h3, -.legacy-anchor:target + h4, -.legacy-anchor:target + h5, -.legacy-anchor:target + h6 { - margin-left: -10px; - border-left: 10px solid var(--border-color); -} - -/* 4. Links */ -a { - color: var(--link-color); - transition: color 0.3s ease; - text-decoration: underline; - text-underline-offset: 0.2em; /* Make sure it doesn't overlap with underscores in a method name. */ -} - -a:hover { - color: var(--link-hover-color); -} - -a code:hover { - color: var(--link-hover-color); -} - -/* 5. Code and Pre */ -code, -pre { - font-family: var(--font-code); - background-color: var(--code-block-background-color); - border: 1px solid var(--border-color); - border-radius: 6px; - padding: 16px; - overflow-x: auto; - font-size: 15px; - line-height: 1.5; - margin: 1em 0; -} - -code { - background-color: var(--code-block-background-color); - padding: 0.1em 0.3em; - border-radius: 3px; - font-size: 85%; -} - -/* Tables */ -table { - margin: 0; - border-spacing: 0; - border-collapse: collapse; -} - -table tr th, table tr td { - padding: 0.2em 0.4em; - border: 1px solid var(--border-color); -} - -table tr th { - background-color: var(--table-header-background-color); -} - -table tr:nth-child(even) td { - background-color: var(--table-td-background-color); -} - -/* 7. Navigation and Sidebar */ -nav { - font-family: var(--font-heading); - font-size: 16px; - border-right: 1px solid var(--border-color); - position: fixed; - top: 0; - bottom: 0; - left: 0; - width: var(--sidebar-width); - background: var(--background-color); /* It needs an explicit background for toggling narrow screens */ - overflow-y: auto; - z-index: 10; - display: flex; - flex-direction: column; - color: var(--text-color); -} - -nav[hidden] { - display: none; -} - -nav footer { - padding: 1em; - border-top: 1px solid var(--border-color); -} - -nav footer a { - color: var(--secondary-highlight-color); -} - -nav .nav-section { - margin-top: 1em; - padding: 0 1em; -} - -nav h2, nav h3 { - margin: 0 0 0.5em; - padding: 0.5em 0; - color: var(--highlight-color); - border-bottom: 1px solid var(--border-color); -} - -nav h2 { - font-size: 1.2em; -} - -nav h3, -#table-of-contents-navigation { - font-size: 1em; -} - -ol.breadcrumb { - display: flex; - - padding: 0; - margin: 0 0 1em; -} - -ol.breadcrumb li { - display: block; - list-style: none; - font-size: 125%; -} - -nav ul, -nav dl, -nav p { - padding: 0; - list-style: none; - margin: 0.5em 0; -} - -nav ul li { - margin-bottom: 0.3em; -} - -nav ul ul { - padding-left: 1em; -} - -nav ul ul ul { - padding-left: 1em; -} - -nav ul ul ul ul { - padding-left: 1em; -} - -nav a { - color: var(--link-color); - text-decoration: none; -} - -nav a:hover { - color: var(--link-hover-color); - text-decoration: underline; -} - -#navigation-toggle { - z-index: 1000; - font-size: 2em; - display: block; - position: fixed; - top: 10px; - left: 20px; - cursor: pointer; -} - -#navigation-toggle[aria-expanded="true"] { - top: 10px; - left: 250px; -} - -nav ul li details { - position: relative; - padding-right: 1.5em; /* Add space for the marker on the right */ -} - -nav ul li details > summary { - list-style: none; /* Remove the default marker */ - position: relative; /* So that the open/close triangle can position itself absolutely inside */ -} - -nav ul li details > summary::-webkit-details-marker { - display: none; /* Removes the default marker, in Safari 18. */ -} - -nav ul li details > summary::after { - content: '▶'; /* Unicode right-pointing triangle */ - position: absolute; - font-size: 0.8em; - bottom: 0.1em; - margin-left: 0.3em; - transition: transform 0.2s ease; -} - -nav ul li details[open] > summary::after { - transform: rotate(90deg); /* Rotate the triangle when open */ -} - -/* 8. Main Content */ -main { - flex: 1; - display: block; - margin: 3em auto; - padding: 0 2em; - max-width: 800px; - font-size: 16px; - line-height: 1.6; - color: var(--text-color); - box-sizing: border-box; -} - -@media (min-width: 1024px) { - main { - margin-left: var(--sidebar-width); - } - - .table-of-contents main { - margin-left: 20em; - } - - #navigation-toggle { - display: none; - } -} - -main h1[class] { - margin-top: 0; - margin-bottom: 1em; - font-size: 2.5em; - color: var(--highlight-color); -} - -main h1, -main h2, -main h3, -main h4, -main h5, -main h6 { - font-family: var(--font-heading); - color: var(--highlight-color); -} - -/* Search */ -#search-section { - padding: 1em; - background-color: var(--background-color); - border-bottom: 1px solid var(--border-color); -} - -#search-field-wrapper { - position: relative; - display: flex; - align-items: center; -} - -#search-field { - width: 100%; - padding: 0.5em 1em 0.5em 2.5em; - border: 1px solid var(--border-color); - border-radius: 20px; - font-size: 14px; - outline: none; - transition: border-color 0.3s ease; - color: var(--text-color); -} - -#search-field:focus { - border-color: var(--highlight-color); -} - -#search-field::placeholder { - color: var(--text-color); -} - -#search-field-wrapper::before { - content: "\1F50D"; - position: absolute; - left: 0.75em; - top: 50%; - transform: translateY(-50%); - font-size: 14px; - color: var(--text-color); - opacity: 0.6; -} - -/* Search Results */ -#search-results { - font-family: var(--font-primary); - font-weight: 300; -} - -#search-results .search-match { - font-family: var(--font-heading); - font-weight: normal; -} - -#search-results .search-selected { - background: var(--code-block-background-color); - border-bottom: 1px solid transparent; -} - -#search-results li { - list-style: none; - border-bottom: 1px solid var(--border-color); - margin-bottom: 0.5em; -} - -#search-results li:last-child { - border-bottom: none; - margin-bottom: 0; -} - -#search-results li p { - padding: 0; - margin: 0.5em; -} - -#search-results .search-namespace { - font-weight: bold; -} - -#search-results li em { - background-color: rgba(224, 108, 117, 0.1); - font-style: normal; -} - -#search-results pre { - margin: 0.5em; - font-family: var(--font-code); -} - -/* Syntax Highlighting - Gruvbox Light Scheme */ - -.ruby-constant { color: #AF3A03; } /* Dark Orange */ -.ruby-keyword { color: #9D0006; } /* Dark Red */ -.ruby-ivar { color: #B57614; } /* Brown */ -.ruby-operator { color: #427B58; } /* Dark Teal */ -.ruby-identifier { color: #076678; } /* Deep Teal */ -.ruby-node { color: #8F3F71; } /* Plum */ -.ruby-comment { color: #928374; font-style: italic; } /* Gray */ -.ruby-regexp { color: #8F3F71; } /* Plum */ -.ruby-value { color: #AF3A03; } /* Dark Orange */ -.ruby-string { color: #79740E; } /* Olive */ - -/* Emphasis */ -em { - text-decoration-color: rgba(52, 48, 64, 0.25); - text-decoration-line: underline; - text-decoration-style: dotted; -} - -strong, -em { - color: var(--highlight-color); - background-color: rgba(255, 111, 97, 0.1); /* Light red background for emphasis */ -} - -/* Paragraphs */ -main p { - line-height: 1.5em; - font-weight: 400; -} - -/* Preformatted Text */ -main pre { - margin: 1.2em 0.5em; - padding: 1em; - font-size: 0.8em; -} - -/* Horizontal Rules */ -main hr { - margin: 1.5em 1em; - border: 2px solid var(--border-color); -} - -/* Blockquotes */ -main blockquote { - margin: 0 2em 1.2em 1.2em; - padding-left: 0.5em; - border-left: 2px solid var(--border-color); -} - -/* Lists */ -main li > p { - margin: 0.5em; -} - -/* Definition Lists */ -main dl { - margin: 1em 0.5em; -} - -main dt { - line-height: 1.5; /* matches `main p` */ - font-weight: bold; -} - -main dl.note-list dt { - margin-right: 1em; - float: left; -} - -main dl.note-list dt:has(+ dt) { - margin-right: 0.25em; -} - -main dl.note-list dt:has(+ dt)::after { - content: ', '; - font-weight: normal; -} - -main dd { - margin: 0 0 1em 1em; -} - -main dd p:first-child { - margin-top: 0; -} - -/* Headers within Main */ -main header h2 { - margin-top: 2em; - border-width: 0; - border-top: 4px solid var(--border-color); - font-size: 130%; -} - -main header h3 { - margin: 2em 0 1.5em; - border-width: 0; - border-top: 3px solid var(--border-color); - font-size: 120%; -} - -/* Utility Classes */ -.hide { display: none !important; } -.initially-hidden { display: none; } - -/* Table of Contents */ -.table-of-contents ul { - margin: 1em; - list-style: none; -} - -.table-of-contents ul ul { - margin-top: 0.25em; -} - -.table-of-contents ul :link, -.table-of-contents ul :visited { - font-size: 16px; -} - -.table-of-contents li { - margin-bottom: 0.25em; -} - -/* Method Details */ -main .method-source-code { - visibility: hidden; - max-height: 0; - overflow: auto; - transition-duration: 200ms; - transition-delay: 0ms; - transition-property: all; - transition-timing-function: ease-in-out; -} - -main .method-source-code pre { - border-color: var(--source-code-toggle-color); -} - -main .method-source-code.active-menu { - visibility: visible; - max-height: 100vh; -} - -main .method-description .method-calls-super { - color: var(--text-color); - font-weight: bold; -} - -main .method-detail { - margin-bottom: 2.5em; -} - -main .method-detail:target { - margin-left: -10px; - border-left: 10px solid var(--border-color); -} - -main .method-header { - display: inline-block; -} - -main .method-heading { - position: relative; - font-family: var(--font-code); - font-size: 110%; - font-weight: bold; -} - -main .method-heading::after { - content: '¶'; - position: absolute; - visibility: hidden; - color: var(--highlight-color); - font-size: 0.5em; -} - -main .method-heading:hover::after { - visibility: visible; -} - -main .method-controls { - line-height: 20px; - float: right; - color: var(--source-code-toggle-color); - cursor: pointer; -} - -main .method-description, -main .aliases { - margin-top: 0.75em; - color: var(--text-color); -} - -main .aliases { - padding-top: 4px; - font-style: italic; - cursor: default; -} - -main .aliases a { - color: var(--secondary-highlight-color); -} - -main .mixin-from { - font-size: 80%; - font-style: italic; - margin-bottom: 0.75em; -} - -main .method-description ul { - margin-left: 1.5em; -} - -main #attribute-method-details .method-detail:hover { - background-color: transparent; - cursor: default; -} - -main .attribute-access-type { - text-transform: uppercase; -} - -/* Responsive Adjustments */ -@media (max-width: 480px) { - nav { - width: 100%; - } - - main { - margin: 1em auto; - padding: 0 1em; - max-width: 100%; - } - - #navigation-toggle { - right: 10px; - left: auto; - } - - #navigation-toggle[aria-expanded="true"] { - left: auto; - } - - table { - display: block; - overflow-x: auto; - white-space: nowrap; - } - - main .method-controls { - margin-top: 10px; - float: none; - } -} diff --git a/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf b/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf deleted file mode 100644 index b49dd43729..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf b/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf deleted file mode 100644 index 7959fef075..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf b/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf deleted file mode 100644 index 839cd589dc..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf b/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf deleted file mode 100644 index bababa09e3..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf b/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf deleted file mode 100644 index dd00982d49..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf b/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf deleted file mode 100644 index 1decfb95af..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/add.png b/lib/rdoc/generator/template/darkfish/images/add.png deleted file mode 100644 index 6332fefea4..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/add.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/arrow_up.png b/lib/rdoc/generator/template/darkfish/images/arrow_up.png deleted file mode 100644 index 1ebb193243..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/arrow_up.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/brick.png b/lib/rdoc/generator/template/darkfish/images/brick.png deleted file mode 100644 index 7851cf34c9..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/brick.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/brick_link.png b/lib/rdoc/generator/template/darkfish/images/brick_link.png deleted file mode 100644 index 9ebf013a23..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/brick_link.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/bug.png b/lib/rdoc/generator/template/darkfish/images/bug.png deleted file mode 100644 index 2d5fb90ec6..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/bug.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/bullet_black.png b/lib/rdoc/generator/template/darkfish/images/bullet_black.png deleted file mode 100644 index 57619706d1..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/bullet_black.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png b/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png deleted file mode 100644 index b47ce55f68..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png b/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png deleted file mode 100644 index 9ab4a89664..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/date.png b/lib/rdoc/generator/template/darkfish/images/date.png deleted file mode 100644 index 783c83357f..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/date.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/delete.png b/lib/rdoc/generator/template/darkfish/images/delete.png deleted file mode 100644 index 08f249365a..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/delete.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/find.png b/lib/rdoc/generator/template/darkfish/images/find.png deleted file mode 100644 index 1547479646..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/find.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif b/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif deleted file mode 100644 index 82290f4833..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png b/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png deleted file mode 100644 index c6473b324e..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/package.png b/lib/rdoc/generator/template/darkfish/images/package.png deleted file mode 100644 index da3c2a2d74..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/package.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/page_green.png b/lib/rdoc/generator/template/darkfish/images/page_green.png deleted file mode 100644 index de8e003f9f..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/page_green.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/page_white_text.png b/lib/rdoc/generator/template/darkfish/images/page_white_text.png deleted file mode 100644 index 813f712f72..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/page_white_text.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/page_white_width.png b/lib/rdoc/generator/template/darkfish/images/page_white_width.png deleted file mode 100644 index 1eb880947d..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/page_white_width.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/plugin.png b/lib/rdoc/generator/template/darkfish/images/plugin.png deleted file mode 100644 index 6187b15aec..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/plugin.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/ruby.png b/lib/rdoc/generator/template/darkfish/images/ruby.png deleted file mode 100644 index f763a16880..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/ruby.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/tag_blue.png b/lib/rdoc/generator/template/darkfish/images/tag_blue.png deleted file mode 100644 index 3f02b5f8f8..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/tag_blue.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/tag_green.png b/lib/rdoc/generator/template/darkfish/images/tag_green.png deleted file mode 100644 index 83ec984bd7..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/tag_green.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/transparent.png b/lib/rdoc/generator/template/darkfish/images/transparent.png deleted file mode 100644 index d665e179ef..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/transparent.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/wrench.png b/lib/rdoc/generator/template/darkfish/images/wrench.png deleted file mode 100644 index 5c8213fef5..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/wrench.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/wrench_orange.png b/lib/rdoc/generator/template/darkfish/images/wrench_orange.png deleted file mode 100644 index 565a9330e0..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/wrench_orange.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/images/zoom.png b/lib/rdoc/generator/template/darkfish/images/zoom.png deleted file mode 100644 index 908612e394..0000000000 Binary files a/lib/rdoc/generator/template/darkfish/images/zoom.png and /dev/null differ diff --git a/lib/rdoc/generator/template/darkfish/index.rhtml b/lib/rdoc/generator/template/darkfish/index.rhtml deleted file mode 100644 index d2ebcf69f7..0000000000 --- a/lib/rdoc/generator/template/darkfish/index.rhtml +++ /dev/null @@ -1,24 +0,0 @@ - -<%= render '_sidebar_toggle.rhtml' %> - - - -
-<%- if @main_page %> - <%= @main_page.description %> -<%- else %> -

This is the API documentation for <%= h @title %>.

-<%- end %> -
- diff --git a/lib/rdoc/generator/template/darkfish/js/darkfish.js b/lib/rdoc/generator/template/darkfish/js/darkfish.js deleted file mode 100644 index 6b6e688afb..0000000000 --- a/lib/rdoc/generator/template/darkfish/js/darkfish.js +++ /dev/null @@ -1,140 +0,0 @@ -/** - * - * Darkfish Page Functions - * $Id: darkfish.js 53 2009-01-07 02:52:03Z deveiant $ - * - * Author: Michael Granger - * - */ - -/* Provide console simulation for firebug-less environments */ -/* -if (!("console" in window) || !("firebug" in console)) { - var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", - "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; - - window.console = {}; - for (var i = 0; i < names.length; ++i) - window.console[names[i]] = function() {}; -}; -*/ - - -function showSource( e ) { - var target = e.target; - while (!target.classList.contains('method-detail')) { - target = target.parentNode; - } - if (typeof target !== "undefined" && target !== null) { - target = target.querySelector('.method-source-code'); - } - if (typeof target !== "undefined" && target !== null) { - target.classList.toggle('active-menu') - } -}; - -function hookSourceViews() { - document.querySelectorAll('.method-source-toggle').forEach(function (codeObject) { - codeObject.addEventListener('click', showSource); - }); -}; - -function hookSearch() { - var input = document.querySelector('#search-field'); - var result = document.querySelector('#search-results'); - result.classList.remove("initially-hidden"); - - var search_section = document.querySelector('#search-section'); - search_section.classList.remove("initially-hidden"); - - var search = new Search(search_data, input, result); - - search.renderItem = function(result) { - var li = document.createElement('li'); - var html = ''; - - // TODO add relative path to >, yield_arg' - @attr = RDoc::Attr.new nil, 'attr', 'RW', '' - - @klass.add_method @meth - @klass.add_method @meth_bang - @klass.add_method @meth_with_html_tag_yield - @klass.add_attribute @attr - - @ignored = @top_level.add_class RDoc::NormalClass, 'Ignored' - @ignored.ignore - - @store.complete :private - - @object = @store.find_class_or_module 'Object' - @klass_alias = @store.find_class_or_module 'Klass::A' - end - - def teardown - super - - $LOAD_PATH.shift - Dir.chdir @pwd - FileUtils.rm_rf @tmpdir - end - - def test_generate - top_level = @store.add_file 'file.rb' - top_level.add_class @klass.class, @klass.name - @klass.add_class RDoc::NormalClass, 'Inner' - @klass.add_comment <<~RDOC, top_level - = Heading 1 - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod - == Heading 1.1 - tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, - === Heading 1.1.1 - quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - ==== Heading 1.1.1.1 - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse - == Heading 1.2 - cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat - == Heading 1.3 - non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - === Heading 1.3.1 - etc etc... - RDOC - - @g.generate - - assert_file 'index.html' - assert_file 'Object.html' - assert_file 'Klass.html' - assert_file 'Klass/Inner.html' - assert_file 'table_of_contents.html' - assert_file 'js/search_index.js' - - assert_hard_link 'css/rdoc.css' - assert_hard_link 'css/fonts.css' - - assert_hard_link 'fonts/SourceCodePro-Bold.ttf' - assert_hard_link 'fonts/SourceCodePro-Regular.ttf' - - encoding = Regexp.escape Encoding::UTF_8.name - - assert_match %r%%, File.binread('index.html') - assert_match %r%%, File.binread('Object.html') - - refute_match(/Ignored/, File.binread('index.html')) - summary = File.binread('index.html')[%r[.*]m] - assert_match(%r[Klass/Inner\.html".*>Inner<], summary) - - klass = File.binread('Klass.html') - klassnav = klass[%r[