# encoding: utf-8
module Prawn
module ManualBuilder
# The Prawn::ManualBuilder ExampleFile class is a utility class to ease
# the manipulation and extraction of source code and comments from the
# actual example files
#
class ExampleFile
attr_reader :package, :filename
# Stores the file data, filename and parent, which will be either an
# ExampleSection or an ExamplePackage.
#
# Available boolean options are:
#
# :eval_source:: Evals the example source code (default: true)
# :full_source:: Extract the full source code when true. Extract
# only the code between the generate block when false (default: false)
#
def initialize(parent, filename, options={})
@parent = parent.is_a?(String) ? ExamplePackage.new(parent) : parent
@filename = filename
@data = read_file(@parent.folder_name, filename)
@options = {:eval_source => true, :full_source => false}.merge(options)
end
# Return the example source code excluding the initial comments and
# require calls
#
def full_source
@data.gsub(/# encoding.*?\n.*require.*?\n\n/m, "\n").strip
end
# Return the example source contained inside the first generate block or
# the full source if no generate block is found
#
def generate_block_source
block = @data.slice(/\w+\.generate.*? do\n(.*)end/m, 1)
return full_source unless block
block.gsub(/^( ){2}/, "")
end
# Return either the full_source or the generate_block_source according
# to the options
#
def source
@options[:full_source] ? full_source : generate_block_source
end
# Return true if the example source should be evaluated inline within
# the manual according to the options
#
def eval?
@options[:eval_source]
end
# Retrieve the comments between the encoding declaration and the require
# call for example_helper.rb
#
# Then removes the '#' signs, reflows the line breaks and return the result
#
def introduction_text
intro_lines
.map do |line|
line
.gsub(/\A\s*# (?=\S)/m, ' ')
.gsub(/\A\s*#/, '')
.strip
end
.join("\n")
end
# Returns a human friendly version of the example file name
#
def name
@name ||= @filename[/(.*)\.rb/, 1].gsub("_", " ").capitalize
end
# Returns this example's parent original folder name
#
def parent_folder_name
@parent.folder_name
end
# Returns the human friendly version of this example parent name
#
def parent_name
@parent.name
end
# Renders this example to a pdf
#
def render(pdf)
pdf.render_example(self)
end
private
# Read the data from a file in a given package
#
def read_file(folder_name, filename)
data = File.read(File.expand_path(File.join(
Prawn::ManualBuilder.manual_dir, folder_name, filename)))
data.encode(::Encoding::UTF_8)
end
def intro_lines
@data
.lines
.grep(/^#/)
.reject do |line|
line.start_with?('#!') ||
/coding:/.match(line) ||
/\A\s*#\s*frozen_string_literal:/.match(line) ||
/\A\s*#\s*rubocop:/.match(line)
end
end
end
end
end