"Fossies" - the Fresh Open Source Software Archive

Member "asciidoctor-2.0.10/lib/asciidoctor/convert.rb" (1 Jun 2019, 8685 Bytes) of package /linux/www/asciidoctor-2.0.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Ruby source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "convert.rb": 2.0.9_vs_2.0.10.

    1 module Asciidoctor
    2   module_function
    3 
    4   # Public: Parse the AsciiDoc source input into an Asciidoctor::Document and
    5   # convert it to the specified backend format.
    6   #
    7   # Accepts input as an IO (or StringIO), String or String Array object. If the
    8   # input is a File, the object is expected to be opened for reading and is not
    9   # closed afterwards by this method. Information about the file (filename,
   10   # directory name, etc) gets assigned to attributes on the Document object.
   11   #
   12   # If the :to_file option is true, and the input is a File, the output is
   13   # written to a file adjacent to the input file, having an extension that
   14   # corresponds to the backend format. Otherwise, if the :to_file option is
   15   # specified, the file is written to that file. If :to_file is not an absolute
   16   # path, it is resolved relative to :to_dir, if given, otherwise the
   17   # Document#base_dir. If the target directory does not exist, it will not be
   18   # created unless the :mkdirs option is set to true. If the file cannot be
   19   # written because the target directory does not exist, or because it falls
   20   # outside of the Document#base_dir in safe mode, an IOError is raised.
   21   #
   22   # If the output is going to be written to a file, the header and footer are
   23   # included unless specified otherwise (writing to a file implies creating a
   24   # standalone document). Otherwise, the header and footer are not included by
   25   # default and the converted result is returned.
   26   #
   27   # input   - the String AsciiDoc source filename
   28   # options - a String, Array or Hash of options to control processing (default: {})
   29   #           String and Array values are converted into a Hash.
   30   #           See Asciidoctor::Document#initialize for details about options.
   31   #
   32   # Returns the Document object if the converted String is written to a
   33   # file, otherwise the converted String
   34   def convert input, options = {}
   35     (options = options.merge).delete :parse
   36     to_dir = options.delete :to_dir
   37     mkdirs = options.delete :mkdirs
   38 
   39     case (to_file = options.delete :to_file)
   40     when true, nil
   41       unless (write_to_target = to_dir)
   42         sibling_path = ::File.absolute_path input.path if ::File === input
   43       end
   44       to_file = nil
   45     when false
   46       to_file = nil
   47     when '/dev/null'
   48       return load input, options
   49     else
   50       options[:to_file] = write_to_target = to_file unless (stream_output = to_file.respond_to? :write)
   51     end
   52 
   53     unless options.key? :standalone
   54       if sibling_path || write_to_target
   55         options[:standalone] = options.fetch :header_footer, true
   56       elsif options.key? :header_footer
   57         options[:standalone] = options[:header_footer]
   58       end
   59     end
   60 
   61     # NOTE outfile may be controlled by document attributes, so resolve outfile after loading
   62     if sibling_path
   63       options[:to_dir] = outdir = ::File.dirname sibling_path
   64     elsif write_to_target
   65       if to_dir
   66         if to_file
   67           options[:to_dir] = ::File.dirname ::File.expand_path ::File.join to_dir, to_file
   68         else
   69           options[:to_dir] = ::File.expand_path to_dir
   70         end
   71       elsif to_file
   72         options[:to_dir] = ::File.dirname ::File.expand_path to_file
   73       end
   74     end
   75 
   76     # NOTE :to_dir is always set when outputting to a file
   77     # NOTE :to_file option only passed if assigned an explicit path
   78     doc = load input, options
   79 
   80     if sibling_path # write to file in same directory
   81       outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
   82       raise ::IOError, %(input file and output file cannot be the same: #{outfile}) if outfile == sibling_path
   83     elsif write_to_target # write to explicit file or directory
   84       working_dir = (options.key? :base_dir) ? (::File.expand_path options[:base_dir]) : ::Dir.pwd
   85       # QUESTION should the jail be the working_dir or doc.base_dir???
   86       jail = doc.safe >= SafeMode::SAFE ? working_dir : nil
   87       if to_dir
   88         outdir = doc.normalize_system_path(to_dir, working_dir, jail, target_name: 'to_dir', recover: false)
   89         if to_file
   90           outfile = doc.normalize_system_path(to_file, outdir, nil, target_name: 'to_dir', recover: false)
   91           # reestablish outdir as the final target directory (in the case to_file had directory segments)
   92           outdir = ::File.dirname outfile
   93         else
   94           outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
   95         end
   96       elsif to_file
   97         outfile = doc.normalize_system_path(to_file, working_dir, jail, target_name: 'to_dir', recover: false)
   98         # establish outdir as the final target directory (in the case to_file had directory segments)
   99         outdir = ::File.dirname outfile
  100       end
  101 
  102       if ::File === input && outfile == (::File.absolute_path input.path)
  103         raise ::IOError, %(input file and output file cannot be the same: #{outfile})
  104       end
  105 
  106       if mkdirs
  107         Helpers.mkdir_p outdir
  108       else
  109         # NOTE we intentionally refer to the directory as it was passed to the API
  110         raise ::IOError, %(target directory does not exist: #{to_dir} (hint: set :mkdirs option)) unless ::File.directory? outdir
  111       end
  112     else # write to stream
  113       outfile = to_file
  114       outdir = nil
  115     end
  116 
  117     if outfile && !stream_output
  118       output = doc.convert 'outfile' => outfile, 'outdir' => outdir
  119     else
  120       output = doc.convert
  121     end
  122 
  123     if outfile
  124       doc.write output, outfile
  125 
  126       # NOTE document cannot control this behavior if safe >= SafeMode::SERVER
  127       # NOTE skip if stylesdir is a URI
  128       if !stream_output && doc.safe < SafeMode::SECURE && (doc.attr? 'linkcss') && (doc.attr? 'copycss') &&
  129           (doc.basebackend? 'html') && !((stylesdir = (doc.attr 'stylesdir')) && (Helpers.uriish? stylesdir))
  130         if (stylesheet = doc.attr 'stylesheet')
  131           if DEFAULT_STYLESHEET_KEYS.include? stylesheet
  132             copy_asciidoctor_stylesheet = true
  133           elsif !(Helpers.uriish? stylesheet)
  134             copy_user_stylesheet = true
  135           end
  136         end
  137         copy_syntax_hl_stylesheet = (syntax_hl = doc.syntax_highlighter) && (syntax_hl.write_stylesheet? doc)
  138         if copy_asciidoctor_stylesheet || copy_user_stylesheet || copy_syntax_hl_stylesheet
  139           stylesoutdir = doc.normalize_system_path(stylesdir, outdir, doc.safe >= SafeMode::SAFE ? outdir : nil)
  140           if mkdirs
  141             Helpers.mkdir_p stylesoutdir
  142           else
  143             raise ::IOError, %(target stylesheet directory does not exist: #{stylesoutdir} (hint: set :mkdirs option)) unless ::File.directory? stylesoutdir
  144           end
  145 
  146           if copy_asciidoctor_stylesheet
  147             Stylesheets.instance.write_primary_stylesheet stylesoutdir
  148           # FIXME should Stylesheets also handle the user stylesheet?
  149           elsif copy_user_stylesheet
  150             if (stylesheet_src = doc.attr 'copycss').empty?
  151               stylesheet_src = doc.normalize_system_path stylesheet
  152             else
  153               # NOTE in this case, copycss is a source location (but cannot be a URI)
  154               stylesheet_src = doc.normalize_system_path stylesheet_src
  155             end
  156             stylesheet_dest = doc.normalize_system_path stylesheet, stylesoutdir, (doc.safe >= SafeMode::SAFE ? outdir : nil)
  157             # NOTE don't warn if src can't be read and dest already exists (see #2323)
  158             if stylesheet_src != stylesheet_dest && (stylesheet_data = doc.read_asset stylesheet_src,
  159                 warn_on_failure: !(::File.file? stylesheet_dest), label: 'stylesheet')
  160               ::File.write stylesheet_dest, stylesheet_data, mode: FILE_WRITE_MODE
  161             end
  162           end
  163           syntax_hl.write_stylesheet doc, stylesoutdir if copy_syntax_hl_stylesheet
  164         end
  165       end
  166       doc
  167     else
  168       output
  169     end
  170   end
  171 
  172   # Public: Parse the contents of the AsciiDoc source file into an
  173   # Asciidoctor::Document and convert it to the specified backend format.
  174   #
  175   # input   - the String AsciiDoc source filename
  176   # options - a String, Array or Hash of options to control processing (default: {})
  177   #           String and Array values are converted into a Hash.
  178   #           See Asciidoctor::Document#initialize for details about options.
  179   #
  180   # Returns the Document object if the converted String is written to a
  181   # file, otherwise the converted String
  182   def convert_file filename, options = {}
  183     ::File.open(filename, FILE_READ_MODE) {|file| convert file, options }
  184   end
  185 
  186   # Deprecated: Use {Asciidoctor.convert} instead.
  187   alias render convert
  188   module_function :render
  189 
  190   # Deprecated: Use {Asciidoctor.convert_file} instead.
  191   alias render_file convert_file
  192   module_function :render_file
  193 end