Method: Asciidoctor.convert
- Defined in:
- lib/asciidoctor/convert.rb
.convert(input, options = {}) ⇒ Object Also known as: render
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.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/asciidoctor/convert.rb', line 34 def convert input, = {} ( = .merge).delete :parse to_dir = .delete :to_dir mkdirs = .delete :mkdirs case (to_file = .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, else [:to_file] = write_to_target = to_file unless (stream_output = to_file.respond_to? :write) end unless .key? :standalone if sibling_path || write_to_target [:standalone] = .fetch :header_footer, true elsif .key? :header_footer [:standalone] = [:header_footer] end end # NOTE outfile may be controlled by document attributes, so resolve outfile after loading if sibling_path [:to_dir] = outdir = ::File.dirname sibling_path elsif write_to_target if to_dir if to_file [:to_dir] = ::File.dirname ::File. to_file, to_dir else [:to_dir] = ::File. to_dir end elsif to_file [:to_dir] = ::File.dirname ::File. 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, 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 = (.key? :base_dir) ? (::File. [: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 # 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 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 # 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 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') == '' || 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 end doc else output end end |