Skip to content

Commit

Permalink
Refactor rendering
Browse files Browse the repository at this point in the history
This reimplements the `SDoc::Templatable` module as an `SDoc::Renderer`
class.  An `SDoc::Renderer` is instantiated per file render, which
provides an isolated scope for each rendering.  Utilizing that
isolation, the context object (the `RDoc::CodeObject` instance) is now
stored in `@context` so that it doesn't have to be explicitly passed to
partials.

Also, as an optimization, `SDoc::Renderer` memoizes compiled ERB.
  • Loading branch information
jonathanhefner committed Sep 28, 2023
1 parent 444c4a4 commit d08ca4d
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 126 deletions.
22 changes: 11 additions & 11 deletions lib/rdoc/generator/template/rails/_context.rhtml
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
<div id="context">
<% unless (description = context.description).empty? %>
<% unless (description = @context.description).empty? %>
<div class="description">
<%= description %>
</div>
<% end %>


<%# File only: requires %>
<% unless context.requires.empty? %>
<% unless @context.requires.empty? %>
<div class="content__divider">Required Files</div>
<ul>
<% context.requires.each do |req| %>
<% @context.requires.each do |req| %>
<li><%= full_name req.name %></li>
<% end %>
</ul>
<% end %>


<%# Module only: ancestors %>
<% unless context.is_a?(RDoc::TopLevel) || (ancestors = module_ancestors(context)).empty? %>
<% unless @context.is_a?(RDoc::TopLevel) || (ancestors = module_ancestors(@context)).empty? %>
<div class="content__divider">Inherits From</div>
<ul>
<% ancestors.each do |kind, ancestor| %>
Expand All @@ -31,7 +31,7 @@
<% end %>


<% sections = context.sections.select { |s| s.title }.sort_by{ |s| s.title.to_s } %>
<% sections = @context.sections.select { |s| s.title }.sort_by{ |s| s.title.to_s } %>
<% unless sections.empty? then %>
<!-- Sections -->
<div class="content__divider">Sections</div>
Expand All @@ -42,11 +42,11 @@
</ul>
<% end %>

<% unless context.method_list.empty? %>
<% unless @context.method_list.empty? %>
<!-- Method ref -->
<div class="content__divider">Methods</div>
<dl class="methods">
<% group_by_first_letter(context.method_list).each do |letter, methods| %>
<% group_by_first_letter(@context.method_list).each do |letter, methods| %>
<dt><%= letter %></dt>
<dd>
<ul>
Expand All @@ -64,7 +64,7 @@



<% context.each_section do |section, constants, attributes| %>
<% @context.each_section do |section, constants, attributes| %>

<% if section.title then %>
<div class="content__section-title" id="<%= h section.aref %>">
Expand Down Expand Up @@ -117,7 +117,7 @@

<!-- Methods -->
<%
context.methods_by_type(section).each do |type, visibilities|
@context.methods_by_type(section).each do |type, visibilities|
next if visibilities.empty?

visibilities.each do |visibility, methods|
Expand Down Expand Up @@ -174,11 +174,11 @@
<% end %><%# context.methods_by_type %>
<% end %><%# context.each_section %>

<% unless context.classes_and_modules.empty? %>
<% unless @context.classes_and_modules.empty? %>
<!-- Namespace -->
<div class="content__divider">Namespace</div>
<ul>
<% (context.modules.sort + context.classes.sort).each do |mod| %>
<% (@context.modules.sort + @context.classes.sort).each do |mod| %>
<li>
<span class="kind"><%= mod.type %></span>
<%= link_to mod %>
Expand Down
6 changes: 3 additions & 3 deletions lib/rdoc/generator/template/rails/_head.rhtml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<%= base_tag_for_context(context) %>
<%= base_tag_for_context(@context) %>

<link rel="stylesheet" href="/css/panel.css" type="text/css" media="screen" />
<link rel="stylesheet" href="/css/main.css" type="text/css" media="screen" />
Expand All @@ -11,13 +11,13 @@
<script src="/js/searchdoc.js" type="text/javascript"></script>
<meta name="data-tree-keys" content='<%= tree_keys %>'>

<% if canonical = canonical_url(context) %>
<% if canonical = canonical_url(@context) %>
<link rel="canonical" href="<%= canonical %>" />
<meta property="og:url" content="<%= canonical %>">
<meta property="og:image" content="<%= canonical_url("/i/logo.svg") %>">
<% end %>
<meta property="og:type" content="article">
<meta property="article:modified_time" content="<%= og_modified_time %>">
<% if description = page_description(context.description) %>
<% if description = page_description(@context.description) %>
<meta name="description" property="og:description" content="<%= description %>">
<% end %>
14 changes: 7 additions & 7 deletions lib/rdoc/generator/template/rails/class.rhtml
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@
<html lang="en">
<head>
<meta charset="<%= @options.charset %>">
<title><%= page_title klass.full_name %></title>
<title><%= page_title @context.full_name %></title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= include_template '_head.rhtml', {:context => klass, :tree_keys => klass.full_name.split('::') } %>
<%= render "_head.rhtml", { :tree_keys => @context.full_name.split('::') } %>

<meta property="og:title" value="<%= og_title klass.full_name %>">
<meta property="og:title" value="<%= og_title @context.full_name %>">
</head>

<body>
<a class="sr-only sr-only-focusable" href="#context" data-turbo="false">Skip to Content</a>
<a class="sr-only sr-only-focusable" href="#search" data-turbo="false">Skip to Search</a>

<%= include_template '_panel.rhtml' %>
<%= render "_panel.rhtml" %>

<main id="content">
<hgroup class="content__title">
<h1><span class="kind"><%= klass.type %></span> <%= module_breadcrumbs klass %></h1>
<h1><span class="kind"><%= @context.type %></span> <%= module_breadcrumbs @context %></h1>
</hgroup>

<%= include_template '_context.rhtml', {:context => klass} %>
<%= render "_context.rhtml" %>

<div class="content__divider">Definition files</div>
<%= more_less_ul klass.in_files.map { |file| link_to file }, 5..9 %>
<%= more_less_ul @context.in_files.map { |file| link_to file }, 5..9 %>
</main>
</body>
</html>
18 changes: 9 additions & 9 deletions lib/rdoc/generator/template/rails/file.rhtml
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@
<html lang="en">
<head>
<meta charset="<%= @options.charset %>">
<title><%= page_title file.name %></title>
<title><%= page_title @context.name %></title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= include_template '_head.rhtml', {:context => file, :tree_keys => [] } %>
<%= render "_head.rhtml", { :tree_keys => [] } %>

<meta property="og:title" value="<%= og_title file.name %>">
<meta property="og:title" value="<%= og_title @context.name %>">
</head>

<body>
<a class="sr-only sr-only-focusable" href="#context" data-turbo="false">Skip to Content</a>
<a class="sr-only sr-only-focusable" href="#search" data-turbo="false">Skip to Search</a>

<%= include_template '_panel.rhtml' %>
<%= render "_panel.rhtml" %>

<main id="content">
<div class="content__title">
<%= "<h1>" if file.comment.empty? %>
<%= full_name file %>
<%= "</h1>" if file.comment.empty? %>
<%= "<h1>" if @context.comment.empty? %>
<%= full_name @context %>
<%= "</h1>" if @context.comment.empty? %>
</div>

<% if source_url = github_url(file.relative_name) %>
<% if source_url = github_url(@context.relative_name) %>
<p class="content__source-link"><%= link_to_external "View on GitHub", source_url %></p>
<% end %>

<%= include_template '_context.rhtml', {:context => file} %>
<%= render "_context.rhtml" %>
</main>
</body>
</html>
2 changes: 1 addition & 1 deletion lib/rdoc/generator/template/rails/file_links.rhtml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
<% @files.each do |file| %>
<% @context.each do |file| %>
<a href="../<%= file.path %>"><%= file.relative_name %></a>
<% end %>
</body>
Expand Down
6 changes: 3 additions & 3 deletions lib/rdoc/generator/template/rails/index.rhtml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
<meta charset="<%= @options.charset %>">
<title><%= page_title %></title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= include_template '_head.rhtml', {:context => index, tree_keys: []} %>
<%= render "_head.rhtml", {tree_keys: []} %>
</head>

<body>
<a class="sr-only sr-only-focusable" href="#context" data-turbo="false">Skip to Content</a>
<a class="sr-only sr-only-focusable" href="#search" data-turbo="false">Skip to Search</a>

<%= include_template '_panel.rhtml' %>
<%= render "_panel.rhtml" %>

<main id="content">
<%= include_template '_context.rhtml', {:context => index } %>
<%= render "_context.rhtml" %>
</main>
</body>
</html>
78 changes: 32 additions & 46 deletions lib/sdoc/generator.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
require 'erb'
require 'pathname'
require 'fileutils'
require 'json'

require "rdoc"
require_relative "rdoc_monkey_patches"

require 'sdoc/templatable'
require 'sdoc/helpers'
require 'sdoc/search_index'
require 'sdoc/version'
require "sdoc/postprocessor"
require "sdoc/renderer"
require "sdoc/search_index"
require "sdoc/version"

class RDoc::ClassModule
def with_documentation?
Expand All @@ -27,19 +26,13 @@ class RDoc::Generator::SDoc

DESCRIPTION = 'Searchable HTML documentation'

include ERB::Util
include SDoc::Templatable
include SDoc::Helpers

TREE_FILE = File.join 'panel', 'tree.js'

FILE_DIR = 'files'
CLASS_DIR = 'classes'

RESOURCES_DIR = File.join('resources', '.')

attr_reader :base_dir

attr_reader :options

##
Expand Down Expand Up @@ -81,17 +74,15 @@ def initialize(store, options)
@options.pipe = true

@original_dir = Pathname.pwd
@template_dir = Pathname.new(options.template_dir)
@base_dir = options.root
@template_dir = Pathname(options.template_dir)
@output_dir = Pathname(@options.op_dir).expand_path(options.root)
end

def generate
@outputdir = Pathname.new(@options.op_dir).expand_path(@base_dir)
FileUtils.mkdir_p @outputdir
@files = @store.all_files.sort
@classes = @store.all_classes_and_modules.sort

# Now actually write the output
FileUtils.mkdir_p(@output_dir)
copy_resources
generate_search_index
generate_file_links
Expand Down Expand Up @@ -131,58 +122,53 @@ def debug_msg( *msg )
$stderr.puts( *msg )
end

def render_file(template_path, output_path, context = nil)
return if @options.dry_run

result = SDoc::Renderer.new(context, @options).render(template_path)
result = SDoc::Postprocessor.process(result)

output_path = @output_dir.join(output_path)
output_path.dirname.mkpath
output_path.write(result)
end

### Create index.html with frameset
def generate_index_file
debug_msg "Generating index file in #{@outputdir}"
templatefile = @template_dir + 'index.rhtml'
outfile = @outputdir + 'index.html'

render_template(templatefile, binding, outfile)
debug_msg "Generating index file in #{@output_dir}"
render_file("index.rhtml", "index.html", index)
end

### Generate a documentation file for each class
def generate_class_files
debug_msg "Generating class documentation in #{@outputdir}"
templatefile = @template_dir + 'class.rhtml'

debug_msg "Generating class documentation in #{@output_dir}"
@classes.each do |klass|
debug_msg " working on %s (%s)" % [ klass.full_name, klass.path ]
outfile = @outputdir + klass.path

debug_msg " rendering #{outfile}"
render_template(templatefile, binding, outfile)
debug_msg " rendering #{klass.path}"
render_file("class.rhtml", klass.path, klass)
end
end

### Generate a documentation file for each file
def generate_file_files
debug_msg "Generating file documentation in #{@outputdir}"
templatefile = @template_dir + 'file.rhtml'

debug_msg "Generating file documentation in #{@output_dir}"
@files.each do |file|
outfile = @outputdir + file.path
debug_msg " working on %s (%s)" % [ file.full_name, outfile ]

debug_msg " rendering #{outfile}"
render_template(templatefile, binding, outfile)
debug_msg " rendering #{file.path}"
render_file("file.rhtml", file.path, file)
end
end

### Generate file with links for the search engine
def generate_file_links
debug_msg "Generating search engine index in #{@outputdir}"
templatefile = @template_dir + 'file_links.rhtml'
outfile = @outputdir + 'panel/file_links.html'

render_template(templatefile, binding, outfile)
debug_msg "Generating search engine index in #{@output_dir}"
render_file("file_links.rhtml", "panel/file_links.html", @files)
end

### Create class tree structure and write it as json
def generate_class_tree
debug_msg "Generating class tree"
topclasses = @classes.select {|klass| !(RDoc::ClassModule === klass.parent) }
tree = generate_file_tree + generate_class_tree_level(topclasses)
file = @outputdir + TREE_FILE
file = @output_dir + TREE_FILE
debug_msg " writing class tree to %s" % file
File.open(file, "w", 0644) do |f|
f.write('var tree = '); f.write(tree.to_json(:max_nesting => 0))
Expand Down Expand Up @@ -212,7 +198,7 @@ def generate_search_index
unless @options.dry_run
index = SDoc::SearchIndex.generate(@store.all_classes_and_modules)

@outputdir.join("js/search-index.js").open("w") do |file|
@output_dir.join("js/search-index.js").open("w") do |file|
file.write("export default ")
JSON.dump(index, file)
file.write(";")
Expand All @@ -223,8 +209,8 @@ def generate_search_index
### Copy all the resource files to output dir
def copy_resources
resources_path = @template_dir + RESOURCES_DIR
debug_msg "Copying #{resources_path}/** to #{@outputdir}/**"
FileUtils.cp_r resources_path.to_s, @outputdir.to_s unless @options.dry_run
debug_msg "Copying #{resources_path}/** to #{@output_dir}/**"
FileUtils.cp_r resources_path.to_s, @output_dir.to_s unless @options.dry_run
end

class FilesTree
Expand Down
4 changes: 4 additions & 0 deletions lib/sdoc/helpers.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
require "erb"

module SDoc::Helpers
include ERB::Util

require_relative "helpers/git"
include SDoc::Helpers::Git

Expand Down
Loading

0 comments on commit d08ca4d

Please sign in to comment.