lib/asciidoctor/convert.rb in asciidoctor-2.0.10 vs lib/asciidoctor/convert.rb in asciidoctor-2.0.11
- old
+ new
@@ -1,193 +1,198 @@
module Asciidoctor
- module_function
+ class << self
+ # Public: Parse the AsciiDoc source input into an Asciidoctor::Document and
+ # convert it to the specified backend format.
+ #
+ # Accepts input as an IO (or StringIO), String or String Array object. If the
+ # input is a File, the object is expected to be opened for reading and is not
+ # closed afterwards by this method. Information about the file (filename,
+ # directory name, etc) gets assigned to attributes on the Document object.
+ #
+ # If the :to_file option is true, and the input is a File, the output is
+ # written to a file adjacent to the input file, having an extension that
+ # corresponds to the backend format. Otherwise, if the :to_file option is
+ # specified, the file is written to that file. If :to_file is not an absolute
+ # path, it is resolved relative to :to_dir, if given, otherwise the
+ # Document#base_dir. If the target directory does not exist, it will not be
+ # created unless the :mkdirs option is set to true. If the file cannot be
+ # written because the target directory does not exist, or because it falls
+ # outside of the Document#base_dir in safe mode, an IOError is raised.
+ #
+ # If the output is going to be written to a file, the header and footer are
+ # included unless specified otherwise (writing to a file implies creating a
+ # standalone document). Otherwise, the header and footer are not included by
+ # default and the converted result is returned.
+ #
+ # input - the String AsciiDoc source filename
+ # options - a String, Array or Hash of options to control processing (default: {})
+ # String and Array values are converted into a Hash.
+ # See Asciidoctor::Document#initialize for details about options.
+ #
+ # Returns the Document object if the converted String is written to a
+ # file, otherwise the converted String
+ def convert input, options = {}
+ (options = options.merge).delete :parse
+ to_dir = options.delete :to_dir
+ mkdirs = options.delete :mkdirs
- # Public: Parse the AsciiDoc source input into an Asciidoctor::Document and
- # convert it to the specified backend format.
- #
- # Accepts input as an IO (or StringIO), String or String Array object. If the
- # input is a File, the object is expected to be opened for reading and is not
- # closed afterwards by this method. Information about the file (filename,
- # directory name, etc) gets assigned to attributes on the Document object.
- #
- # If the :to_file option is true, and the input is a File, the output is
- # written to a file adjacent to the input file, having an extension that
- # corresponds to the backend format. Otherwise, if the :to_file option is
- # specified, the file is written to that file. If :to_file is not an absolute
- # path, it is resolved relative to :to_dir, if given, otherwise the
- # Document#base_dir. If the target directory does not exist, it will not be
- # created unless the :mkdirs option is set to true. If the file cannot be
- # written because the target directory does not exist, or because it falls
- # outside of the Document#base_dir in safe mode, an IOError is raised.
- #
- # If the output is going to be written to a file, the header and footer are
- # included unless specified otherwise (writing to a file implies creating a
- # standalone document). Otherwise, the header and footer are not included by
- # default and the converted result is returned.
- #
- # input - the String AsciiDoc source filename
- # options - a String, Array or Hash of options to control processing (default: {})
- # String and Array values are converted into a Hash.
- # See Asciidoctor::Document#initialize for details about options.
- #
- # Returns the Document object if the converted String is written to a
- # file, otherwise the converted String
- def convert input, options = {}
- (options = options.merge).delete :parse
- to_dir = options.delete :to_dir
- mkdirs = options.delete :mkdirs
-
- case (to_file = options.delete :to_file)
- when true, nil
- unless (write_to_target = to_dir)
- sibling_path = ::File.absolute_path input.path if ::File === input
+ case (to_file = options.delete :to_file)
+ when true, nil
+ unless (write_to_target = to_dir)
+ sibling_path = ::File.absolute_path input.path if ::File === input
+ end
+ to_file = nil
+ when false
+ to_file = nil
+ when '/dev/null'
+ return load input, options
+ else
+ options[:to_file] = write_to_target = to_file unless (stream_output = to_file.respond_to? :write)
end
- to_file = nil
- when false
- to_file = nil
- when '/dev/null'
- return load input, options
- else
- options[:to_file] = write_to_target = to_file unless (stream_output = to_file.respond_to? :write)
- end
- unless options.key? :standalone
- if sibling_path || write_to_target
- options[:standalone] = options.fetch :header_footer, true
- elsif options.key? :header_footer
- options[:standalone] = options[:header_footer]
+ unless options.key? :standalone
+ if sibling_path || write_to_target
+ options[:standalone] = options.fetch :header_footer, true
+ elsif options.key? :header_footer
+ options[:standalone] = options[:header_footer]
+ end
end
- end
- # NOTE outfile may be controlled by document attributes, so resolve outfile after loading
- if sibling_path
- options[:to_dir] = outdir = ::File.dirname sibling_path
- elsif write_to_target
- if to_dir
- if to_file
- options[:to_dir] = ::File.dirname ::File.expand_path ::File.join to_dir, to_file
- else
- options[:to_dir] = ::File.expand_path to_dir
+ # NOTE outfile may be controlled by document attributes, so resolve outfile after loading
+ if sibling_path
+ options[:to_dir] = outdir = ::File.dirname sibling_path
+ elsif write_to_target
+ if to_dir
+ if to_file
+ options[:to_dir] = ::File.dirname ::File.expand_path to_file, to_dir
+ else
+ options[:to_dir] = ::File.expand_path to_dir
+ end
+ elsif to_file
+ options[:to_dir] = ::File.dirname ::File.expand_path to_file
end
- elsif to_file
- options[:to_dir] = ::File.dirname ::File.expand_path to_file
end
- end
- # NOTE :to_dir is always set when outputting to a file
- # NOTE :to_file option only passed if assigned an explicit path
- doc = load input, options
+ # NOTE :to_dir is always set when outputting to a file
+ # NOTE :to_file option only passed if assigned an explicit path
+ doc = load input, options
- if sibling_path # write to file in same directory
- outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
- raise ::IOError, %(input file and output file cannot be the same: #{outfile}) if outfile == sibling_path
- elsif write_to_target # write to explicit file or directory
- working_dir = (options.key? :base_dir) ? (::File.expand_path options[:base_dir]) : ::Dir.pwd
- # QUESTION should the jail be the working_dir or doc.base_dir???
- jail = doc.safe >= SafeMode::SAFE ? working_dir : nil
- if to_dir
- outdir = doc.normalize_system_path(to_dir, working_dir, jail, target_name: 'to_dir', recover: false)
- if to_file
- outfile = doc.normalize_system_path(to_file, outdir, nil, target_name: 'to_dir', recover: false)
- # reestablish outdir as the final target directory (in the case to_file had directory segments)
+ if sibling_path # write to file in same directory
+ outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
+ raise ::IOError, %(input file and output file cannot be the same: #{outfile}) if outfile == sibling_path
+ elsif write_to_target # write to explicit file or directory
+ working_dir = (options.key? :base_dir) ? (::File.expand_path options[:base_dir]) : ::Dir.pwd
+ # QUESTION should the jail be the working_dir or doc.base_dir???
+ jail = doc.safe >= SafeMode::SAFE ? working_dir : nil
+ if to_dir
+ outdir = doc.normalize_system_path(to_dir, working_dir, jail, target_name: 'to_dir', recover: false)
+ if to_file
+ outfile = doc.normalize_system_path(to_file, outdir, nil, target_name: 'to_dir', recover: false)
+ # reestablish outdir as the final target directory (in the case to_file had directory segments)
+ outdir = ::File.dirname outfile
+ else
+ outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
+ end
+ elsif to_file
+ outfile = doc.normalize_system_path(to_file, working_dir, jail, target_name: 'to_dir', recover: false)
+ # establish outdir as the final target directory (in the case to_file had directory segments)
outdir = ::File.dirname outfile
+ end
+
+ if ::File === input && outfile == (::File.absolute_path input.path)
+ raise ::IOError, %(input file and output file cannot be the same: #{outfile})
+ end
+
+ if mkdirs
+ Helpers.mkdir_p outdir
else
- outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
+ # NOTE we intentionally refer to the directory as it was passed to the API
+ raise ::IOError, %(target directory does not exist: #{to_dir} (hint: set :mkdirs option)) unless ::File.directory? outdir
end
- elsif to_file
- outfile = doc.normalize_system_path(to_file, working_dir, jail, target_name: 'to_dir', recover: false)
- # establish outdir as the final target directory (in the case to_file had directory segments)
- outdir = ::File.dirname outfile
+ else # write to stream
+ outfile = to_file
+ outdir = nil
end
- if ::File === input && outfile == (::File.absolute_path input.path)
- raise ::IOError, %(input file and output file cannot be the same: #{outfile})
- end
-
- if mkdirs
- Helpers.mkdir_p outdir
+ if outfile && !stream_output
+ output = doc.convert 'outfile' => outfile, 'outdir' => outdir
else
- # NOTE we intentionally refer to the directory as it was passed to the API
- raise ::IOError, %(target directory does not exist: #{to_dir} (hint: set :mkdirs option)) unless ::File.directory? outdir
+ output = doc.convert
end
- else # write to stream
- outfile = to_file
- outdir = nil
- end
- if outfile && !stream_output
- output = doc.convert 'outfile' => outfile, 'outdir' => outdir
- else
- output = doc.convert
- end
+ if outfile
+ doc.write output, outfile
- if outfile
- doc.write output, outfile
-
- # NOTE document cannot control this behavior if safe >= SafeMode::SERVER
- # NOTE skip if stylesdir is a URI
- if !stream_output && doc.safe < SafeMode::SECURE && (doc.attr? 'linkcss') && (doc.attr? 'copycss') &&
- (doc.basebackend? 'html') && !((stylesdir = (doc.attr 'stylesdir')) && (Helpers.uriish? stylesdir))
- if (stylesheet = doc.attr 'stylesheet')
- if DEFAULT_STYLESHEET_KEYS.include? stylesheet
- copy_asciidoctor_stylesheet = true
- elsif !(Helpers.uriish? stylesheet)
- copy_user_stylesheet = true
+ # NOTE document cannot control this behavior if safe >= SafeMode::SERVER
+ # NOTE skip if stylesdir is a URI
+ if !stream_output && doc.safe < SafeMode::SECURE && (doc.attr? 'linkcss') && (doc.attr? 'copycss') &&
+ (doc.basebackend? 'html') && !((stylesdir = (doc.attr 'stylesdir')) && (Helpers.uriish? stylesdir))
+ if (stylesheet = doc.attr 'stylesheet')
+ if DEFAULT_STYLESHEET_KEYS.include? stylesheet
+ copy_asciidoctor_stylesheet = true
+ elsif !(Helpers.uriish? stylesheet)
+ copy_user_stylesheet = true
+ end
end
- end
- copy_syntax_hl_stylesheet = (syntax_hl = doc.syntax_highlighter) && (syntax_hl.write_stylesheet? doc)
- if copy_asciidoctor_stylesheet || copy_user_stylesheet || copy_syntax_hl_stylesheet
- stylesoutdir = doc.normalize_system_path(stylesdir, outdir, doc.safe >= SafeMode::SAFE ? outdir : nil)
- if mkdirs
- Helpers.mkdir_p stylesoutdir
- else
- raise ::IOError, %(target stylesheet directory does not exist: #{stylesoutdir} (hint: set :mkdirs option)) unless ::File.directory? stylesoutdir
- end
-
- if copy_asciidoctor_stylesheet
- Stylesheets.instance.write_primary_stylesheet stylesoutdir
- # FIXME should Stylesheets also handle the user stylesheet?
- elsif copy_user_stylesheet
- if (stylesheet_src = doc.attr 'copycss').empty?
- stylesheet_src = doc.normalize_system_path stylesheet
+ copy_syntax_hl_stylesheet = (syntax_hl = doc.syntax_highlighter) && (syntax_hl.write_stylesheet? doc)
+ if copy_asciidoctor_stylesheet || copy_user_stylesheet || copy_syntax_hl_stylesheet
+ stylesoutdir = doc.normalize_system_path(stylesdir, outdir, doc.safe >= SafeMode::SAFE ? outdir : nil)
+ if mkdirs
+ Helpers.mkdir_p stylesoutdir
else
- # NOTE in this case, copycss is a source location (but cannot be a URI)
- stylesheet_src = doc.normalize_system_path stylesheet_src
+ raise ::IOError, %(target stylesheet directory does not exist: #{stylesoutdir} (hint: set :mkdirs option)) unless ::File.directory? stylesoutdir
end
- stylesheet_dest = doc.normalize_system_path stylesheet, stylesoutdir, (doc.safe >= SafeMode::SAFE ? outdir : nil)
- # NOTE don't warn if src can't be read and dest already exists (see #2323)
- if stylesheet_src != stylesheet_dest && (stylesheet_data = doc.read_asset stylesheet_src,
- warn_on_failure: !(::File.file? stylesheet_dest), label: 'stylesheet')
- ::File.write stylesheet_dest, stylesheet_data, mode: FILE_WRITE_MODE
+
+ if copy_asciidoctor_stylesheet
+ Stylesheets.instance.write_primary_stylesheet stylesoutdir
+ # FIXME should Stylesheets also handle the user stylesheet?
+ elsif copy_user_stylesheet
+ if (stylesheet_src = doc.attr 'copycss') == '' || stylesheet_src == true
+ stylesheet_src = doc.normalize_system_path stylesheet
+ else
+ # NOTE in this case, copycss is a source location (but cannot be a URI)
+ stylesheet_src = doc.normalize_system_path stylesheet_src.to_s
+ end
+ stylesheet_dest = doc.normalize_system_path stylesheet, stylesoutdir, (doc.safe >= SafeMode::SAFE ? outdir : nil)
+ # NOTE don't warn if src can't be read and dest already exists (see #2323)
+ if stylesheet_src != stylesheet_dest && (stylesheet_data = doc.read_asset stylesheet_src,
+ warn_on_failure: !(::File.file? stylesheet_dest), label: 'stylesheet')
+ if (stylesheet_outdir = ::File.dirname stylesheet_dest) != stylesoutdir && !(::File.directory? stylesheet_outdir)
+ if mkdirs
+ Helpers.mkdir_p stylesheet_outdir
+ else
+ raise ::IOError, %(target stylesheet directory does not exist: #{stylesheet_outdir} (hint: set :mkdirs option))
+ end
+ end
+ ::File.write stylesheet_dest, stylesheet_data, mode: FILE_WRITE_MODE
+ end
end
+ syntax_hl.write_stylesheet doc, stylesoutdir if copy_syntax_hl_stylesheet
end
- syntax_hl.write_stylesheet doc, stylesoutdir if copy_syntax_hl_stylesheet
end
+ doc
+ else
+ output
end
- doc
- else
- output
end
- end
- # Public: Parse the contents of the AsciiDoc source file into an
- # Asciidoctor::Document and convert it to the specified backend format.
- #
- # input - the String AsciiDoc source filename
- # options - a String, Array or Hash of options to control processing (default: {})
- # String and Array values are converted into a Hash.
- # See Asciidoctor::Document#initialize for details about options.
- #
- # Returns the Document object if the converted String is written to a
- # file, otherwise the converted String
- def convert_file filename, options = {}
- ::File.open(filename, FILE_READ_MODE) {|file| convert file, options }
- end
+ # Public: Parse the contents of the AsciiDoc source file into an
+ # Asciidoctor::Document and convert it to the specified backend format.
+ #
+ # input - the String AsciiDoc source filename
+ # options - a String, Array or Hash of options to control processing (default: {})
+ # String and Array values are converted into a Hash.
+ # See Asciidoctor::Document#initialize for details about options.
+ #
+ # Returns the Document object if the converted String is written to a
+ # file, otherwise the converted String
+ def convert_file filename, options = {}
+ ::File.open(filename, FILE_READ_MODE) {|file| convert file, options }
+ end
- # Deprecated: Use {Asciidoctor.convert} instead.
- alias render convert
- module_function :render
+ # Deprecated: Use {Asciidoctor.convert} instead.
+ alias render convert
- # Deprecated: Use {Asciidoctor.convert_file} instead.
- alias render_file convert_file
- module_function :render_file
+ # Deprecated: Use {Asciidoctor.convert_file} instead.
+ alias render_file convert_file
+ end
end