Class: RDoc::Generator::Papyrus
- Inherits:
-
Object
- Object
- RDoc::Generator::Papyrus
- Defined in:
- lib/rdoc/generator/papyrus.rb,
lib/rdoc/generator/papyrus/options.rb
Overview
This is the main class for the Papyrus PDF generator for RDoc. It takes RDoc’s raw parsed data and transforms it into a single PDF file backed by pdfLaTeX. If you’re interested in how this process works, feel free to dig into this class’ code, but ensure you also have a look on the Markup::ToLaTeX class which does the heavy work of translating the markup tokens into LaTeX code. The below section also has a brief overview of how the generation process works.
The generation process
-
During startup, RDoc calls the ::setup_options method that adds
some commandline options to RDoc (these are described in the
RDoc::Generator::Papyrus::Options module).
-
RDoc parses the source files.
-
RDoc calls the #generate method and passes it all encountered
files as an array of RDoc::TopLevel objects.
-
The #generate method examines all encountered classes, modules
and methods and then starts to transform the raw data handed by
RDoc into LaTeX markup by means of the formatter class
RDoc::Markup::ToLaTeX_Crossref. The generated markup is written
into a temporary directory "tmp" below the output directory
RDoc has chosen or has been instructed to choose (via commandline),
generating one LaTeX file for each class and module plus one main
file "main.tex" that includes the other files as needed.
-
pdfLaTeX is invoked on that final main file, generating “main.pdf”
in the temporary directory.
-
The generated PDF file is copied over to the real output directory
and renamed to "Documentation.pdf".
-
The temporary directory is recursively deleted.
-
A file
index.html
is created inside the output directory
that contains a link to the PDF file. This allows navigating to the
documentation via RubyGems’ server (if somebody really set his
default generator to +pdf_latex+...).
Defined Under Namespace
Modules: Options Classes: PapyrusError
Constant Summary collapse
- DESCRIPTION =
Description displayed in RDoc’s help.
"PDF generator based on LaTeX"
- ROOT_DIR =
Root directory of this project.
Pathname.new(__FILE__).dirname.parent.parent.parent
- VERSION =
The version number.
ROOT_DIR.join("VERSION.txt").read.chomp.freeze
- DATA_DIR =
Directory where the LaTeX template files are stored.
ROOT_DIR + "data"
- FONT_DIR =
Directory where the internal fonts are stored.
DATA_DIR + "fonts"
- MAIN_TEMPLATE =
The main file’s ERB template.
ERB.new(File.open(DATA_DIR.join("main.tex.erb"), "r:UTF-8"){|f| f.read})
- RDOC_FILE_TEMPLATE =
The ERB template for a single file.
ERB.new(File.open(DATA_DIR.join("rdoc_file.tex.erb"), "r:UTF-8"){|f| f.read})
- MODULE_TEMPLATE =
The ERB template for a single class or module.
ERB.new(File.open(DATA_DIR.join("module.tex.erb"), "r:UTF-8"){|f| f.read})
- MAIN_FILE_BASENAME =
Basename of the main resulting LaTeX file. The path is prepended later as it’s a temporary directory.
"main.tex"
- MAIN_FILE_RESULT_BASENAME =
Basename of the resulting documentation file inside the temporary directory.
"main.pdf"
Class Method Summary collapse
-
.setup_options(options) ⇒ Object
Called by RDoc during option processing.
Instance Method Summary collapse
-
#generate(top_levels) ⇒ Object
Called by RDoc after parsing has happened in order to generate the output.
-
#initialize(options) ⇒ Papyrus
constructor
Creates a new instance of this class.
Constructor Details
#initialize(options) ⇒ Papyrus
Creates a new instance of this class. Automatically called by RDoc. There shouldn’t be any need for you to call this.
Parameter
- options
-
RDoc passes the current RDoc::Options instance here.
Return value
The newly created instance.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/rdoc/generator/papyrus.rb', line 161 def initialize() #The requiring of the rest of the library *must* be placed here, #because otherwise it’s loaded during RDoc’s discovering process, #effectively eliminating the possibility to generate anything #other than LaTeX output due to the overwrites the #RDoc::Generator::LaTeX_Markup module does. require_relative "../markup/to_latex_crossref" require_relative "latex_markup" @options = @output_dir = Pathname.pwd. + @options.op_dir #The following variable is used to generate unique filenames. #During processing the ERB templates, many files are created and #accidentally creating two files with the same name, effectively #overwriting the previous one, should be avoided. Hence, this #little number is prepended to generated filenames (except the #main file). @counter = 0 end |
Class Method Details
.setup_options(options) ⇒ Object
Called by RDoc during option processing. Adds commandline switches specific to this generator.
Parameter
- options
-
The yet unparsed RDoc::Options.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/rdoc/generator/papyrus.rb', line 105 def () debug("Teaching new options to RDoc") #Define the methods to get and set the options .extend(RDoc::Generator::Papyrus::Options) .option_parser.separator "" .option_parser.separator "Papyrus generator options:" .option_parser.separator "" #Define the options themselves .option_parser.on("--[no-]show-pages", "Enables or disables page", "numbers following hyperlinks (default true).") do |val| debug("Found --show-pages: #{val}") .show_pages = val end .option_parser.on("--latex-command=VALUE", " Sets the command to run", "LaTeX (defaults to '#{RDoc::Generator::Papyrus::Options::DEFAULT_LATEX_COMMAND}')") do |val| debug("Found --latex-command: #{val}") .latex_command = val end .option_parser.on("--babel-lang=VALUE", "Sets the language option", "for babel (defaults to '#{RDoc::Generator::Papyrus::Options::DEFAULT_BABEL_LANG}')") do |val| debug("Found --babel-lang: #{val}") .babel_lang = val end .option_parser.on("--inputencoding", "Sets the encoding used for the input files.", "Defaults to '#{RDoc::Generator::Papyrus::Options::DEFAULT_INPUT_ENCODING}'.") do |val| debug("Found --inputencoding: #{val}") .inputencoding = val end .option_parser.on("--[no-]append-source", "If set, the sourcecode of all methods is included", "as an appendix (warning: HUGE PDF", "files can be the result! Default: false."){|val| .append_source = val} end |
Instance Method Details
#generate(top_levels) ⇒ Object
Called by RDoc after parsing has happened in order to generate the output. This method takes the input of RDoc::TopLevel objects and tranforms them by means of the RDoc::Markup::ToLaTeX_Crossref class into LaTeX markup.
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/rdoc/generator/papyrus.rb', line 185 def generate(top_levels) #Prepare all the data needed by all the templates doc_title = @options.title babel_lang = @options.babel_lang #Get the rdoc file list and move the "main page file" to the beginning. debug("Examining toplevel files") @rdoc_files = top_levels.select{|t| t.name =~ /\.rdoc$/i} debug("Found #{@rdoc_files.count} toplevels ending in .rdoc that will be processed") if @options.main_page #nil if not set, no main page main_index = @rdoc_files.index{|t| t.full_name == @options.main_page} if main_index #nil if invalid main_page given @rdoc_files.unshift(@rdoc_files.slice!(main_index)) debug("Main page is #{@rdoc_files.first.name}") end end #Get the class, module and methods lists, sorted alphabetically by their full names debug("Sorting classes, modules and methods") @classes = RDoc::TopLevel.all_classes.sort_by{|klass| klass.full_name} @modules = RDoc::TopLevel.all_modules.sort_by{|mod| mod.full_name} @classes_and_modules = @classes.concat(@modules).sort_by{|mod| mod.full_name} @methods = @classes_and_modules.map{|mod| mod.method_list}.flatten.sort #Start the template filling process if @options.dry_run temp_dir = Pathname.pwd #No output directory in dryrun mode! else temp_dir = @output_dir + "tmp" temp_dir.mkpath end debug("Temporary directory is at '#{temp_dir.}'") Dir.chdir(temp_dir) do #We want LaTeX to output it’s files into our temporary directory #Evaluate the main page which includes all #subpages as necessary. debug("Evaluating main ERB temlpate") main_file = temp_dir + MAIN_FILE_BASENAME main_file.open("w"){|f| f.write(MAIN_TEMPLATE.result(binding))} unless @options.dry_run #Let LaTeX process the whole thing -- 3 times, to ensure #any kinds of references are correct. debug("Invoking LaTeX") 3.times{latex(main_file)} #Oh, and don’t forget to copy the result file into our documentation #directory :-) debug("Copying resulting Documentation.pdf file") unless @options.dry_run FileUtils.rm(@output_dir + "Documentation.pdf") if File.file?(@output_dir + "Documentation.pdf") FileUtils.cp(temp_dir + MAIN_FILE_RESULT_BASENAME, @output_dir + "Documentation.pdf") end #To allow browsing the documentation with the RubyGems server, put an index.html #file there that points to the PDF file. debug("Creating index.html") unless @options.dry_run File.open(@output_dir + "index.html", "w") do |f| f.puts("<html>") f.puts("<!-- This file exists to allow browsing docs with the Gem server -->") f.puts("<head><title>#{doc_title}</title></head>") f.puts('<body><p>Documentation available as a <a href="Documentation.pdf">PDF file</a>.</p></body>') f.puts("</html>") end end end #Remove the temporary directory (this is *not* done if invoking LaTeX #failed, as the #latex method throws an exception. This is useful for #debugging the generated LaTeX files) unless $DEBUG_RDOC debug("Removing temporary directory") temp_dir.rmtree unless @options.dry_run end end |