Module: Asciidoctor
- Defined in:
- lib/asciidoctor.rb,
lib/asciidoctor/list.rb,
lib/asciidoctor/block.rb,
lib/asciidoctor/table.rb,
lib/asciidoctor/inline.rb,
lib/asciidoctor/parser.rb,
lib/asciidoctor/reader.rb,
lib/asciidoctor/writer.rb,
lib/asciidoctor/helpers.rb,
lib/asciidoctor/logging.rb,
lib/asciidoctor/section.rb,
lib/asciidoctor/timings.rb,
lib/asciidoctor/version.rb,
lib/asciidoctor/callouts.rb,
lib/asciidoctor/document.rb,
lib/asciidoctor/converter.rb,
lib/asciidoctor/rouge_ext.rb,
lib/asciidoctor/extensions.rb,
lib/asciidoctor/cli/invoker.rb,
lib/asciidoctor/cli/options.rb,
lib/asciidoctor/stylesheets.rb,
lib/asciidoctor/substitutors.rb,
lib/asciidoctor/abstract_node.rb,
lib/asciidoctor/path_resolver.rb,
lib/asciidoctor/abstract_block.rb,
lib/asciidoctor/attribute_list.rb,
lib/asciidoctor/converter/html5.rb,
lib/asciidoctor/converter/manpage.rb,
lib/asciidoctor/converter/docbook5.rb,
lib/asciidoctor/converter/template.rb,
lib/asciidoctor/syntax_highlighter.rb,
lib/asciidoctor/converter/composite.rb,
lib/asciidoctor/syntax_highlighter/rouge.rb,
lib/asciidoctor/syntax_highlighter/coderay.rb,
lib/asciidoctor/syntax_highlighter/prettify.rb,
lib/asciidoctor/syntax_highlighter/pygments.rb,
lib/asciidoctor/syntax_highlighter/highlightjs.rb,
lib/asciidoctor/syntax_highlighter/html_pipeline.rb
Overview
Public: The main application interface (API) for Asciidoctor. This API provides methods to parse AsciiDoc content and convert it to various output formats using built-in or third-party converters or Tilt-supported templates.
An AsciiDoc document can be as simple as a single line of content, though it more commonly starts with a document header that declares the document title and document attribute definitions. The document header is then followed by zero or more section titles, optionally nested, to organize the paragraphs, blocks, lists, etc. of the document.
By default, the processor converts the AsciiDoc document to HTML 5 using a built-in converter. However, this behavior can be changed by specifying a different backend (e.g., docbook
). A backend is a keyword for an output format (e.g., DocBook). That keyword, in turn, is used to select a converter, which carries out the request to convert the document to that format.
In addition to this API, Asciidoctor also provides a command-line interface (CLI) named asciidoctor
for converting AsciiDoc content. See the provided man(ual) page for usage and options.
Examples
# Convert an AsciiDoc file
Asciidoctor.convert_file 'document.adoc', safe: :safe
# Convert an AsciiDoc string
puts Asciidoctor.convert "I'm using *Asciidoctor* version {asciidoctor-version}.", safe: :safe
# Convert an AsciiDoc file using Tilt-supported templates
Asciidoctor.convert_file 'document.adoc', safe: :safe, template_dir: '/path/to/templates'
# Parse an AsciiDoc file into a document object
doc = Asciidoctor.load_file 'document.adoc', safe: :safe
# Parse an AsciiDoc string into a document object
doc = Asciidoctor.load "= Document Title\n\nfirst paragraph\n\nsecond paragraph", safe: :safe
Defined Under Namespace
Modules: Cli, Compliance, Converter, Extensions, Helpers, LoggerManager, Logging, RougeExt, SafeMode, Substitutors, SyntaxHighlighter, VoidWriter, Writer Classes: AbstractBlock, AbstractNode, AttributeList, Block, Callouts, Document, Inline, List, ListItem, Logger, MemoryLogger, NullLogger, Parser, PathResolver, PreprocessorReader, Reader, Section, Stylesheets, Table, Timings
Constant Summary collapse
- RUBY_ENGINE_OPAL =
alias the RUBY_ENGINE constant inside the Asciidoctor namespace and define a precomputed alias for runtime
(RUBY_ENGINE = ::RUBY_ENGINE) == 'opal'
- ROOT_DIR =
The absolute root directory of the Asciidoctor RubyGem
::File.dirname ::File.absolute_path __dir__
- LIB_DIR =
The absolute lib directory of the Asciidoctor RubyGem
::File.join ROOT_DIR, 'lib'
- DATA_DIR =
The absolute data directory of the Asciidoctor RubyGem
::File.join ROOT_DIR, 'data'
- USER_HOME =
The user’s home directory, as best we can determine it
::Dir.home
- LF =
The newline character used for output; stored in constant table as an optimization
?\n
- NULL =
The null character to use for splitting attribute values
?\0
- TAB =
String for matching tab character
?\t
- MAX_INT =
Maximum integer value for “boundless” operations; equal to MAX_SAFE_INTEGER in JavaScript
9007199254740991
- UTF_8 =
Alias UTF_8 encoding for convenience / speed
::Encoding::UTF_8
- BOM_BYTES_UTF_8 =
Byte arrays for UTF-* Byte Order Marks
[0xef, 0xbb, 0xbf]
- BOM_BYTES_UTF_16LE =
[0xff, 0xfe]
- BOM_BYTES_UTF_16BE =
[0xfe, 0xff]
- FILE_READ_MODE =
The mode to use when opening a file for reading
RUBY_ENGINE_OPAL ? 'r' : 'rb:utf-8:utf-8'
- URI_READ_MODE =
The mode to use when opening a URI for reading
FILE_READ_MODE
- FILE_WRITE_MODE =
The mode to use when opening a file for writing
RUBY_ENGINE_OPAL ? 'w' : 'w:utf-8'
- DEFAULT_DOCTYPE =
The default document type Can influence markup generated by the converters
'article'
- DEFAULT_BACKEND =
The backend determines the format of the converted output, default to html5
'html5'
- DEFAULT_STYLESHEET_KEYS =
['', 'DEFAULT'].to_set
- DEFAULT_STYLESHEET_NAME =
'asciidoctor.css'
- BACKEND_ALIASES =
Pointers to the preferred version for a given backend.
{ 'html' => 'html5', 'docbook' => 'docbook5' }
- DEFAULT_PAGE_WIDTHS =
Default page widths for calculating absolute widths
{ 'docbook' => 425 }
- DEFAULT_EXTENSIONS =
Default extensions for the respective base backends
{ 'html' => '.html', 'docbook' => '.xml', 'pdf' => '.pdf', 'epub' => '.epub', 'manpage' => '.man', 'asciidoc' => '.adoc' }
- ASCIIDOC_EXTENSIONS =
Set of file extensions recognized as AsciiDoc documents (stored as a truth hash)
{ '.adoc' => true, '.asciidoc' => true, '.asc' => true, '.ad' => true, # TODO .txt should be deprecated '.txt' => true }
- SETEXT_SECTION_LEVELS =
{ '=' => 0, '-' => 1, '~' => 2, '^' => 3, '+' => 4 }
- ADMONITION_STYLES =
['NOTE', 'TIP', 'IMPORTANT', 'WARNING', 'CAUTION'].to_set
- ADMONITION_STYLE_HEADS =
['N', 'T', 'I', 'W', 'C'].to_set
- PARAGRAPH_STYLES =
['comment', 'example', 'literal', 'listing', 'normal', 'open', 'pass', 'quote', 'sidebar', 'source', 'verse', 'abstract', 'partintro'].to_set
- VERBATIM_STYLES =
['literal', 'listing', 'source', 'verse'].to_set
- DELIMITED_BLOCKS =
{ '--' => [:open, ['comment', 'example', 'literal', 'listing', 'pass', 'quote', 'sidebar', 'source', 'verse', 'admonition', 'abstract', 'partintro'].to_set], '----' => [:listing, ['literal', 'source'].to_set], '....' => [:literal, ['listing', 'source'].to_set], '====' => [:example, ['admonition'].to_set], '****' => [:sidebar, ::Set.new], '____' => [:quote, ['verse'].to_set], '++++' => [:pass, ['stem', 'latexmath', 'asciimath'].to_set], '|===' => [:table, ::Set.new], ',===' => [:table, ::Set.new], ':===' => [:table, ::Set.new], '!===' => [:table, ::Set.new], '////' => [:comment, ::Set.new], '```' => [:fenced_code, ::Set.new] }
- DELIMITED_BLOCK_HEADS =
{}.tap {|accum| DELIMITED_BLOCKS.each_key {|k| accum[k.slice 0, 2] = true } }
- DELIMITED_BLOCK_TAILS =
{}.tap {|accum| DELIMITED_BLOCKS.each_key {|k| accum[k] = k[k.length - 1] if k.length == 4 } }
- LAYOUT_BREAK_CHARS =
{ '\'' => :thematic_break, '<' => :page_break }
- MARKDOWN_THEMATIC_BREAK_CHARS =
{ '-' => :thematic_break, '*' => :thematic_break, '_' => :thematic_break }
- HYBRID_LAYOUT_BREAK_CHARS =
LAYOUT_BREAK_CHARS.merge MARKDOWN_THEMATIC_BREAK_CHARS
- NESTABLE_LIST_CONTEXTS =
LIST_CONTEXTS = [:ulist, :olist, :dlist, :colist]
[:ulist, :olist, :dlist]
- ORDERED_LIST_STYLES =
TODO validate use of explicit style name above ordered list (this list is for selecting an implicit style)
[:arabic, :loweralpha, :lowerroman, :upperalpha, :upperroman]
- ORDERED_LIST_KEYWORDS =
{ #'arabic' => '1', #'decimal' => '1', 'loweralpha' => 'a', 'lowerroman' => 'i', #'lowergreek' => 'a', 'upperalpha' => 'A', 'upperroman' => 'I' }
- ATTR_REF_HEAD =
'{'
- LIST_CONTINUATION =
'+'
- HARD_LINE_BREAK =
NOTE AsciiDoc Python allows + to be preceded by TAB; Asciidoctor does not
' +'
- LINE_CONTINUATION =
' \\'
- LINE_CONTINUATION_LEGACY =
' +'
- BLOCK_MATH_DELIMITERS =
{ asciimath: ['\$', '\$'], latexmath: ['\[', '\]'], }
- INLINE_MATH_DELIMITERS =
{ asciimath: ['\$', '\$'], latexmath: ['\(', '\)'], }
- FONT_AWESOME_VERSION =
'4.7.0'
- HIGHLIGHT_JS_VERSION =
'9.15.6'
- MATHJAX_VERSION =
'2.7.5'
- FLEXIBLE_ATTRIBUTES =
attributes which be changed within the content of the document (but not header) because it has semantic meaning; ex. sectnums
['sectnums']
- CC_ALL =
CC_ALL is any character, including newlines (must be accompanied by multiline regexp flag)
'.'
- CC_ANY =
CC_ANY is any character except newlines
'.'
- CC_EOL =
'$'
- CC_ALPHA =
CG_ALPHA = '\p{Alpha}'
- CC_ALNUM =
CG_ALNUM = '\p{Alnum}'
- CG_BLANK =
'\p{Blank}'
- CC_WORD =
CG_WORD = '\p{Word}'
- AuthorInfoLineRx =
Matches the author info line immediately following the document title.
Examples
Doc Writer <[email protected]> Mary_Sue Brontë
/^(#{CG_WORD}[#{CC_WORD}\-'.]*)(?: +(#{CG_WORD}[#{CC_WORD}\-'.]*))?(?: +(#{CG_WORD}[#{CC_WORD}\-'.]*))?(?: +<([^>]+)>)?$/
- AuthorDelimiterRx =
/;(?: |$)/
- RevisionInfoLineRx =
Matches the revision info line, which appears immediately following the author info line beneath the document title.
Examples
v1.0 2013-01-01 v1.0, 2013-01-01: Ring in the new year release 1.0, Jan 01, 2013
/^(?:[^\d{]*(#{CC_ANY}*?),)? *(?!:)(#{CC_ANY}*?)(?: *(?!^),?: *(#{CC_ANY}*))?$/
- ManpageTitleVolnumRx =
Matches the title and volnum in the manpage doctype.
Examples
= asciidoctor(1) = asciidoctor ( 1 )
/^(#{CC_ANY}+?) *\( *(#{CC_ANY}+?) *\)$/
- ManpageNamePurposeRx =
Matches the name and purpose in the manpage doctype.
Examples
asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
/^(#{CC_ANY}+?) +- +(#{CC_ANY}+)$/
- ConditionalDirectiveRx =
Matches a conditional preprocessor directive (e.g., ifdef, ifndef, ifeval and endif).
Examples
ifdef::basebackend-html[] ifndef::theme[] ifeval::["{asciidoctor-version}" >= "0.1.0"] ifdef::asciidoctor[Asciidoctor!] endif::theme[] endif::basebackend-html[] endif::[]
/^(\\)?(ifdef|ifndef|ifeval|endif)::(\S*?(?:([,+])\S*?)?)\[(#{CC_ANY}+)?\]$/
- EvalExpressionRx =
Matches a restricted (read as safe) eval expression.
Examples
"{asciidoctor-version}" >= "0.1.0"
/^(#{CC_ANY}+?) *([=!><]=|[><]) *(#{CC_ANY}+)$/
- IncludeDirectiveRx =
Matches an include preprocessor directive.
Examples
include::chapter1.ad[] include::example.txt[lines=1;2;5..10]
/^(\\)?include::([^\[][^\[]*)\[(#{CC_ANY}+)?\]$/
- TagDirectiveRx =
Matches a trailing tag directive in an include file.
Examples
// tag::try-catch[] try { someMethod(); catch (Exception e) { log(e); } // end::try-catch[]
NOTE m flag is required for Asciidoctor.js
/\b(?:tag|(e)nd)::(\S+?)\[\](?=$|[ \r])/m
- AttributeEntryRx =
Matches a document attribute entry.
Examples
:foo: bar :First Name: Dan :sectnums!: :!toc: :long-entry: Attribute value lines ending in ' \' \ are joined together as a single value, \ collapsing the line breaks and indentation to \ a single space.
/^:(!?#{CG_WORD}[^:]*):(?:[ \t]+(#{CC_ANY}*))?$/
- InvalidAttributeNameCharsRx =
Matches invalid characters in an attribute name.
/[^-#{CC_WORD}]/
- AttributeEntryPassMacroRx =
NOTE In JavaScript, ^ and $ match the boundaries of the string when the m flag is not set
/\Apass:([a-z]+(?:,[a-z-]+)*)?\[(.*)\]\Z/m
- AttributeReferenceRx =
Matches an inline attribute reference.
Examples
{foobar} or {app_name} or {product-version} {counter:sequence-name:1} {set:foo:bar} {set:name!}
/(\\)?\{(#{CG_WORD}[-#{CC_WORD}]*|(set|counter2?):#{CC_ANY}+?)(\\)?\}/
- BlockAnchorRx =
Matches an anchor (i.e., id + optional reference text) on a line above a block.
Examples
[[idname]] [[idname,Reference Text]]
/^\[\[(?:|([#{CC_ALPHA}_:][#{CC_WORD}:.-]*)(?:, *(#{CC_ANY}+))?)\]\]$/
- BlockAttributeListRx =
Matches an attribute list above a block element.
Examples
# strictly positional [quote, Adam Smith, Wealth of Nations] # name/value pairs [NOTE, caption="Good to know"] # as attribute reference [{lead}]
/^\[(|[#{CC_WORD}.#%{,"']#{CC_ANY}*)\]$/
- BlockAttributeLineRx =
A combined pattern that matches either a block anchor or a block attribute list.
TODO this one gets hit a lot, should be optimized as much as possible
/^\[(?:|[#{CC_WORD}.#%{,"']#{CC_ANY}*|\[(?:|[#{CC_ALPHA}_:][#{CC_WORD}:.-]*(?:, *#{CC_ANY}+)?)\])\]$/
- BlockTitleRx =
Matches a title above a block.
Examples
.Title goes here
/^\.(\.?[^ \t.]#{CC_ANY}*)$/
- AdmonitionParagraphRx =
Matches an admonition label at the start of a paragraph.
Examples
NOTE: Just a little note. TIP: Don't forget!
/^(#{ADMONITION_STYLES.to_a.join '|'}):[ \t]+/
- LiteralParagraphRx =
Matches a literal paragraph, which is a line of text preceded by at least one space.
Examples
<SPACE>Foo <TAB>Foo
/^([ \t]+#{CC_ANY}*)$/
- AtxSectionTitleRx =
Matches an Atx (single-line) section title.
Examples
== Foo // ^ a level 1 (h2) section title == Foo == // ^ also a level 1 (h2) section title
/^(=={0,5})[ \t]+(#{CC_ANY}+?)(?:[ \t]+\1)?$/
- ExtAtxSectionTitleRx =
Matches an extended Atx section title that includes support for the Markdown variant.
/^(=={0,5}|#\#{0,5})[ \t]+(#{CC_ANY}+?)(?:[ \t]+\1)?$/
- SetextSectionTitleRx =
Matches the title only (first line) of an Setext (two-line) section title. The title cannot begin with a dot and must have at least one alphanumeric character.
/^((?!\.)#{CC_ANY}*?#{CG_ALNUM}#{CC_ANY}*)$/
- InlineSectionAnchorRx =
Matches an anchor (i.e., id + optional reference text) inside a section title.
Examples
Section Title [[idname]] Section Title [[idname,Reference Text]]
/ (\\)?\[\[([#{CC_ALPHA}_:][#{CC_WORD}:.-]*)(?:, *(#{CC_ANY}+))?\]\]$/
- InvalidSectionIdCharsRx =
Matches invalid ID characters in a section title.
NOTE uppercase chars not included since expression is only run on a lowercase string
/<[^>]+>|&(?:[a-z][a-z]+\d{0,2}|#\d\d\d{0,4}|#x[\da-f][\da-f][\da-f]{0,3});|[^ #{CC_WORD}\-.]+?/
- SectionLevelStyleRx =
Matches an explicit section level style like sect1
/^sect\d$/
- AnyListRx =
Detects the start of any list item.
NOTE we only have to check as far as the blank character because we know it means non-whitespace follows. IMPORTANT if this regexp does not agree with the regexp for each list type, the parser will hang.
%r(^(?:[ \t]*(?:-|\*\**|\.\.*|\u2022|\d+\.|[a-zA-Z]\.|[IVXivx]+\))[ \t]|(?!//[^/])[ \t]*[^ \t]#{CC_ANY}*?(?::::{0,2}|;;)(?:$|[ \t])|<?\d+>[ \t]))
- UnorderedListRx =
Matches an unordered list item (one level for hyphens, up to 5 levels for asterisks).
Examples
* Foo - Foo
NOTE we know trailing (.*) will match at least one character because we strip trailing spaces
/^[ \t]*(-|\*\**|\u2022)[ \t]+(#{CC_ANY}*)$/
- OrderedListRx =
Matches an ordered list item (explicit numbering or up to 5 consecutive dots).
Examples
. Foo .. Foo 1. Foo (arabic, default) a. Foo (loweralpha) A. Foo (upperalpha) i. Foo (lowerroman) I. Foo (upperroman)
NOTE leading space match is not always necessary, but is used for list reader NOTE we know trailing (.*) will match at least one character because we strip trailing spaces
/^[ \t]*(\.\.*|\d+\.|[a-zA-Z]\.|[IVXivx]+\))[ \t]+(#{CC_ANY}*)$/
- OrderedListMarkerRxMap =
Matches the ordinals for each type of ordered list.
{ arabic: /\d+\./, loweralpha: /[a-z]\./, lowerroman: /[ivx]+\)/, upperalpha: /[A-Z]\./, upperroman: /[IVX]+\)/, #lowergreek: /[a-z]\]/, }
- DescriptionListRx =
Matches a description list entry.
Examples
foo:: bar::: baz:::: blah;; # the term may be followed by a description on the same line... foo:: The metasyntactic variable that commonly accompanies 'bar' (see also, <<bar>>). # ...or on a separate line, which may optionally be indented foo:: The metasyntactic variable that commonly accompanies 'bar' (see also, <<bar>>). # attribute references may be used in both the term and the description {foo-term}:: {foo-desc}
NOTE we know trailing (.*) will match at least one character because we strip trailing spaces NOTE must skip line comment when looking for next list item inside list
%r(^(?!//[^/])[ \t]*([^ \t]#{CC_ANY}*?)(:::{0,2}|;;)(?:$|[ \t]+(#{CC_ANY}*)$))
- DescriptionListSiblingRx =
Matches a sibling description list item (excluding the delimiter specified by the key). NOTE must skip line comment when looking for sibling list item
{ '::' => %r(^(?!//[^/])[ \t]*([^ \t]#{CC_ANY}*?[^:]|[^ \t:])(::)(?:$|[ \t]+(#{CC_ANY}*)$)), ':::' => %r(^(?!//[^/])[ \t]*([^ \t]#{CC_ANY}*?[^:]|[^ \t:])(:::)(?:$|[ \t]+(#{CC_ANY}*)$)), '::::' => %r(^(?!//[^/])[ \t]*([^ \t]#{CC_ANY}*?[^:]|[^ \t:])(::::)(?:$|[ \t]+(#{CC_ANY}*)$)), ';;' => %r(^(?!//[^/])[ \t]*([^ \t]#{CC_ANY}*?)(;;)(?:$|[ \t]+(#{CC_ANY}*)$)) }
- CalloutListRx =
Matches a callout list item.
Examples
<1> Explanation
or
<.> Explanation with automatic number
NOTE we know trailing (.*) will match at least one character because we strip trailing spaces
/^<(\d+|\.)>[ \t]+(#{CC_ANY}*)$/
- CalloutExtractRx =
Matches a callout reference inside literal text.
Examples
<1> (optionally prefixed by //, #, -- or ;; line comment chars) <1> <2> (multiple callouts on one line) <!--1--> (for XML-based languages) <.> (auto-numbered)
NOTE extract regexps are applied line-by-line, so we can use $ as end-of-line char
%r(((?://|#|--|;;) ?)?(\\)?<!?(|--)(\d+|\.)\3>(?=(?: ?\\?<!?\3(?:\d+|\.)\3>)*$))
- CalloutExtractRxt =
'(\\\\)?<()(\\d+|\\.)>(?=(?: ?\\\\?<(?:\\d+|\\.)>)*$)'
- CalloutExtractRxMap =
::Hash.new {|h, k| h[k] = /(#{k.empty? ? '' : "#{::Regexp.escape k} ?"})?#{CalloutExtractRxt}/ }
- CalloutScanRx =
NOTE special characters have not been replaced when scanning
/\\?<!?(|--)(\d+|\.)\1>(?=(?: ?\\?<!?\1(?:\d+|\.)\1>)*#{CC_EOL})/
- CalloutSourceRx =
NOTE special characters have already been replaced when converting to an SGML format
%r(((?://|#|--|;;) ?)?(\\)?<!?(|--)(\d+|\.)\3>(?=(?: ?\\?<!?\3(?:\d+|\.)\3>)*#{CC_EOL}))
- CalloutSourceRxt =
"(\\\\)?<()(\\d+|\\.)>(?=(?: ?\\\\?<(?:\\d+|\\.)>)*#{CC_EOL})"
- CalloutSourceRxMap =
::Hash.new {|h, k| h[k] = /(#{k.empty? ? '' : "#{::Regexp.escape k} ?"})?#{CalloutSourceRxt}/ }
- ListRxMap =
A Hash of regexps for lists used for dynamic access.
{ ulist: UnorderedListRx, olist: OrderedListRx, dlist: DescriptionListRx, colist: CalloutListRx, }
- ColumnSpecRx =
Parses the column spec (i.e., colspec) for a table.
Examples
1*h,2*,^3e
/^(?:(\d+)\*)?([<^>](?:\.[<^>]?)?|(?:[<^>]?\.)?[<^>])?(\d+%?|~)?([a-z])?$/
- CellSpecStartRx =
Parses the start and end of a cell spec (i.e., cellspec) for a table.
Examples
2.3+<.>m
FIXME use step-wise scan (or treetop) rather than this mega-regexp
/^[ \t]*(?:(\d+(?:\.\d*)?|(?:\d*\.)?\d+)([*+]))?([<^>](?:\.[<^>]?)?|(?:[<^>]?\.)?[<^>])?([a-z])?$/
- CellSpecEndRx =
/[ \t]+(?:(\d+(?:\.\d*)?|(?:\d*\.)?\d+)([*+]))?([<^>](?:\.[<^>]?)?|(?:[<^>]?\.)?[<^>])?([a-z])?$/
- CustomBlockMacroRx =
Matches the custom block macro pattern.
Examples
gist::123456[]
– NOTE we’ve relaxed the match for target to accomodate the short format (e.g., name::)
/^(#{CG_WORD}[-#{CC_WORD}]*)::(|\S|\S#{CC_ANY}*?\S)\[(#{CC_ANY}+)?\]$/
- BlockMediaMacroRx =
Matches an image, video or audio block macro.
Examples
image::filename.png[Caption] video::http://youtube.com/12345[Cats vs Dogs]
/^(image|video|audio)::(\S|\S#{CC_ANY}*?\S)\[(#{CC_ANY}+)?\]$/
- BlockTocMacroRx =
Matches the TOC block macro.
Examples
toc::[] toc::[levels=2]
/^toc::\[(#{CC_ANY}+)?\]$/
- InlineAnchorRx =
Matches an anchor (i.e., id + optional reference text) in the flow of text.
Examples
[[idname]] [[idname,Reference Text]] anchor:idname[] anchor:idname[Reference Text]
/(\\)?(?:\[\[([#{CC_ALPHA}_:][#{CC_WORD}:.-]*)(?:, *(#{CC_ANY}+?))?\]\]|anchor:([#{CC_ALPHA}_:][#{CC_WORD}:.-]*)\[(?:\]|(#{CC_ANY}*?[^\\])\]))/
- InlineAnchorScanRx =
Scans for a non-escaped anchor (i.e., id + optional reference text) in the flow of text.
/(?:^|[^\\\[])\[\[([#{CC_ALPHA}_:][#{CC_WORD}:.-]*)(?:, *(#{CC_ANY}+?))?\]\]|(?:^|[^\\])anchor:([#{CC_ALPHA}_:][#{CC_WORD}:.-]*)\[(?:\]|(#{CC_ANY}*?[^\\])\])/
- LeadingInlineAnchorRx =
Scans for a leading, non-escaped anchor (i.e., id + optional reference text).
/^\[\[([#{CC_ALPHA}_:][#{CC_WORD}:.-]*)(?:, *(#{CC_ANY}+?))?\]\]/
- InlineBiblioAnchorRx =
Matches a bibliography anchor at the start of the list item text (in a bibliography list).
Examples
[[[Fowler_1997]]] Fowler M. ...
/^\[\[\[([#{CC_ALPHA}_:][#{CC_WORD}:.-]*)(?:, *(#{CC_ANY}+?))?\]\]\]/
- InlineEmailRx =
Matches an inline e-mail address.
doc.writer@example.com
%r(([\\>:/])?#{CG_WORD}(?:&|[#{CC_WORD}.%+-])*@#{CG_ALNUM}[#{CC_ALNUM}_.-]*\.[a-zA-Z]{2,5}\b)
- InlineFootnoteMacroRx =
Matches an inline footnote macro, which is allowed to span multiple lines.
Examples
footnote:[text] (not referenceable) footnote:id[text] (referenceable) footnote:id[] (reference) footnoteref:[id,text] (legacy) footnoteref:[id] (legacy)
/\\?footnote(?:(ref):|:([\w-]+)?)\[(?:|(#{CC_ALL}*?[^\\]))\]/m
- InlineImageMacroRx =
Matches an image or icon inline macro.
Examples
image:filename.png[Alt Text] image:http://example.com/images/filename.png[Alt Text] image:filename.png[More [Alt\] Text] (alt text becomes "More [Alt] Text") icon:github[large]
NOTE be as non-greedy as possible by not allowing newline or left square bracket in target
/\\?i(?:mage|con):([^:\s\[](?:[^\n\[]*[^\s\[])?)\[(|#{CC_ALL}*?[^\\])\]/m
- InlineIndextermMacroRx =
Matches an indexterm inline macro, which may span multiple lines.
Examples
indexterm:[Tigers,Big cats] (((Tigers,Big cats))) indexterm2:[Tigers] ((Tigers))
/\\?(?:(indexterm2?):\[(#{CC_ALL}*?[^\\])\]|\(\((#{CC_ALL}+?)\)\)(?!\)))/m
- InlineKbdBtnMacroRx =
Matches either the kbd or btn inline macro.
Examples
kbd:[F3] kbd:[Ctrl+Shift+T] kbd:[Ctrl+\]] kbd:[Ctrl,T] btn:[Save]
/(\\)?(kbd|btn):\[(#{CC_ALL}*?[^\\])\]/m
- InlineLinkRx =
Matches an implicit link and some of the link inline macro.
Examples
https://github.com https://github.com[GitHub] <https://github.com> link:https://github.com[]
FIXME revisit! the main issue is we need different rules for implicit vs explicit
%r((^|link:|#{CG_BLANK}|<|[>\(\)\[\];])(\\?(?:https?|file|ftp|irc)://[^\s\[\]<]*([^\s.,\[\]<]))(?:\[(|#{CC_ALL}*?[^\\])\])?)m
- InlineLinkMacroRx =
Match a link or e-mail inline macro.
Examples
link:path[label] mailto:doc.writer@example.com[]
NOTE be as non-greedy as possible by not allowing space or left square bracket in target
/\\?(?:link|(mailto)):(|[^:\s\[][^\s\[]*)\[(|#{CC_ALL}*?[^\\])\]/m
- MacroNameRx =
Matches the name of a macro.
/^#{CG_WORD}[-#{CC_WORD}]*$/
- InlineStemMacroRx =
Matches a stem (and alternatives, asciimath and latexmath) inline macro, which may span multiple lines.
Examples
stem:[x != 0] asciimath:[x != 0] latexmath:[\sqrt{4} = 2]
/\\?(stem|(?:latex|ascii)math):([a-z]+(?:,[a-z-]+)*)?\[(#{CC_ALL}*?[^\\])\]/m
- InlineMenuMacroRx =
Matches a menu inline macro.
Examples
menu:File[Save As...] menu:View[Page Style > No Style] menu:View[Page Style, No Style]
/\\?menu:(#{CG_WORD}|[#{CC_WORD}&][^\n\[]*[^\s\[])\[ *(#{CC_ALL}*?[^\\])?\]/m
- InlineMenuRx =
Matches an implicit menu inline macro.
Examples
"File > New..."
/\\?"([#{CC_WORD}&][^"]*?[ \n]+>[ \n]+[^"]*)"/
- InlinePassRx =
Matches an inline passthrough, which may span multiple lines.
Examples
+text+ `text` (compat)
NOTE we always capture the attributes so we know when to use compatible (i.e., legacy) behavior
{ false => ['+', '`', /(^|[^#{CC_WORD};:])(?:\[([^\]]+)\])?(\\?(\+|`)(\S|\S#{CC_ALL}*?\S)\4)(?!#{CG_WORD})/m], true => ['`', nil, /(^|[^`#{CC_WORD}])(?:\[([^\]]+)\])?(\\?(`)([^`\s]|[^`\s]#{CC_ALL}*?\S)\4)(?![`#{CC_WORD}])/m] }
- SinglePlusInlinePassRx =
Matches an inline plus passthrough spanning multiple lines, but only when it occurs directly inside constrained monospaced formatting in non-compat mode.
Examples
+text+
/^(\\)?\+(\S|\S#{CC_ALL}*?\S)\+$/m
- InlinePassMacroRx =
Matches several variants of the passthrough inline macro, which may span multiple lines.
Examples
+++text+++ $$text$$ pass:quotes[text]
NOTE we have to support an empty pass:[] for compatibility with AsciiDoc Python
/(?:(?:(\\?)\[([^\]]+)\])?(\\{0,2})(\+\+\+?|\$\$)(#{CC_ALL}*?)\4|(\\?)pass:([a-z]+(?:,[a-z-]+)*)?\[(|#{CC_ALL}*?[^\\])\])/m
- InlineXrefMacroRx =
Matches an xref (i.e., cross-reference) inline macro, which may span multiple lines.
Examples
<<id,reftext>> xref:id[reftext]
NOTE special characters have already been escaped, hence the entity references NOTE { is included in start characters to support target that begins with attribute reference in title content
%r(\\?(?:<<([#{CC_WORD}#/.:{]#{CC_ALL}*?)>>|xref:([#{CC_WORD}#/.:{]#{CC_ALL}*?)\[(?:\]|(#{CC_ALL}*?[^\\])\])))m
- HardLineBreakRx =
NOTE In Ruby, ^ and $ always match start and end of line
/^(.*) \+$/
- MarkdownThematicBreakRx =
Matches a Markdown horizontal rule.
Examples
--- or - - - *** or * * * ___ or _ _ _
/^ {0,3}([-*_])( *)\1\2\1$/
- ExtLayoutBreakRx =
Matches an AsciiDoc or Markdown horizontal rule or AsciiDoc page break.
Examples
''' (horizontal rule) <<< (page break) --- or - - - (horizontal rule, Markdown) *** or * * * (horizontal rule, Markdown) ___ or _ _ _ (horizontal rule, Markdown)
/^(?:'{3,}|<{3,}|([-*_])( *)\1\2\1)$/
- BlankLineRx =
Matches consecutive blank lines.
Examples
one two
/\n{2,}/
- EscapedSpaceRx =
Matches whitespace (space, tab, newline) escaped by a backslash.
Examples
three\ blind\ mice
/\\([ \t\n])/
- ReplaceableTextRx =
Detects if text is a possible candidate for the replacements substitution.
/[&']|--|\.\.\.|\([CRT]M?\)/
- SpaceDelimiterRx =
Matches a whitespace delimiter, a sequence of spaces, tabs, and/or newlines. Matches the parsing rules of %w strings in Ruby.
Examples
one two three four five six
TODO change to /(?<!\)[ tn]+/ once lookbehind assertions are implemented in all modern browsers
/([^\\])[ \t\n]+/
- SubModifierSniffRx =
Matches a + or - modifier in a subs list
/[+-]/
- TrailingDigitsRx =
Matches one or more consecutive digits at the end of a line.
Examples
docbook5 html5
/\d+$/
- UriSniffRx =
Detects strings that resemble URIs.
Examples
http://domain https://domain file:///path data:info not c:/sample.adoc or c:\sample.adoc
%r(^#{CG_ALPHA}[#{CC_ALNUM}.+-]+:/{0,2})
- XmlSanitizeRx =
Detects XML tags
/<[^>]+>/
- INTRINSIC_ATTRIBUTES =
end
{ 'startsb' => '[', 'endsb' => ']', 'vbar' => '|', 'caret' => '^', 'asterisk' => '*', 'tilde' => '~', 'plus' => '+', 'backslash' => '\\', 'backtick' => '`', 'blank' => '', 'empty' => '', 'sp' => ' ', 'two-colons' => '::', 'two-semicolons' => ';;', 'nbsp' => ' ', 'deg' => '°', 'zwsp' => '​', 'quot' => '"', 'apos' => ''', 'lsquo' => '‘', 'rsquo' => '’', 'ldquo' => '“', 'rdquo' => '”', 'wj' => '⁠', 'brvbar' => '¦', 'pp' => '++', 'cpp' => 'C++', 'amp' => '&', 'lt' => '<', 'gt' => '>' }
- QUOTE_SUBS =
{}.tap do |accum| # unconstrained quotes:: can appear anywhere # constrained quotes:: must be bordered by non-word characters # NOTE these substitutions are processed in the order they appear here and # the order in which they are replaced is important accum[false] = normal = [ # **strong** [:strong, :unconstrained, /\\?(?:\[([^\]]+)\])?\*\*(#{CC_ALL}+?)\*\*/m], # *strong* [:strong, :constrained, /(^|[^#{CC_WORD};:}])(?:\[([^\]]+)\])?\*(\S|\S#{CC_ALL}*?\S)\*(?!#{CG_WORD})/m], # "`double-quoted`" [:double, :constrained, /(^|[^#{CC_WORD};:}])(?:\[([^\]]+)\])?"`(\S|\S#{CC_ALL}*?\S)`"(?!#{CG_WORD})/m], # '`single-quoted`' [:single, :constrained, /(^|[^#{CC_WORD};:`}])(?:\[([^\]]+)\])?'`(\S|\S#{CC_ALL}*?\S)`'(?!#{CG_WORD})/m], # ``monospaced`` [:monospaced, :unconstrained, /\\?(?:\[([^\]]+)\])?``(#{CC_ALL}+?)``/m], # `monospaced` [:monospaced, :constrained, /(^|[^#{CC_WORD};:"'`}])(?:\[([^\]]+)\])?`(\S|\S#{CC_ALL}*?\S)`(?![#{CC_WORD}"'`])/m], # __emphasis__ [:emphasis, :unconstrained, /\\?(?:\[([^\]]+)\])?__(#{CC_ALL}+?)__/m], # _emphasis_ [:emphasis, :constrained, /(^|[^#{CC_WORD};:}])(?:\[([^\]]+)\])?_(\S|\S#{CC_ALL}*?\S)_(?!#{CG_WORD})/m], # ##mark## (referred to in AsciiDoc Python as unquoted) [:mark, :unconstrained, /\\?(?:\[([^\]]+)\])?##(#{CC_ALL}+?)##/m], # #mark# (referred to in AsciiDoc Python as unquoted) [:mark, :constrained, /(^|[^#{CC_WORD}&;:}])(?:\[([^\]]+)\])?#(\S|\S#{CC_ALL}*?\S)#(?!#{CG_WORD})/m], # ^superscript^ [:superscript, :unconstrained, /\\?(?:\[([^\]]+)\])?\^(\S+?)\^/], # ~subscript~ [:subscript, :unconstrained, /\\?(?:\[([^\]]+)\])?~(\S+?)~/] ] accum[true] = compat = normal.drop 0 # ``quoted'' compat[2] = [:double, :constrained, /(^|[^#{CC_WORD};:}])(?:\[([^\]]+)\])?``(\S|\S#{CC_ALL}*?\S)''(?!#{CG_WORD})/m] # `quoted' compat[3] = [:single, :constrained, /(^|[^#{CC_WORD};:}])(?:\[([^\]]+)\])?`(\S|\S#{CC_ALL}*?\S)'(?!#{CG_WORD})/m] # ++monospaced++ compat[4] = [:monospaced, :unconstrained, /\\?(?:\[([^\]]+)\])?\+\+(#{CC_ALL}+?)\+\+/m] # +monospaced+ compat[5] = [:monospaced, :constrained, /(^|[^#{CC_WORD};:}])(?:\[([^\]]+)\])?\+(\S|\S#{CC_ALL}*?\S)\+(?!#{CG_WORD})/m] # #unquoted# #compat[8] = [:unquoted, *compat[8][1..-1]] # ##unquoted## #compat[9] = [:unquoted, *compat[9][1..-1]] # 'emphasis' compat.insert 3, [:emphasis, :constrained, /(^|[^#{CC_WORD};:}])(?:\[([^\]]+)\])?'(\S|\S#{CC_ALL}*?\S)'(?!#{CG_WORD})/m] end
- REPLACEMENTS =
NOTE order of replacements is significant
[ # (C) [/\\?\(C\)/, '©', :none], # (R) [/\\?\(R\)/, '®', :none], # (TM) [/\\?\(TM\)/, '™', :none], # foo -- bar (where either space character can be a newline) # NOTE this necessarily drops the newline if it appears at end of line [/(^|\n| |\\)--( |\n|$)/, ' — ', :none], # foo--bar [/(#{CG_WORD})\\?--(?=#{CG_WORD})/, '—​', :leading], # ellipsis [/\\?\.\.\./, '…​', :none], # right single quote [/\\?`'/, '’', :none], # apostrophe (inside a word) [/(#{CG_ALNUM})\\?'(?=#{CG_ALPHA})/, '’', :leading], # right arrow -> [/\\?->/, '→', :none], # right double arrow => [/\\?=>/, '⇒', :none], # left arrow <- [/\\?<-/, '←', :none], # left double arrow <= [/\\?<=/, '⇐', :none], # restore entities [/\\?(&)amp;((?:[a-zA-Z][a-zA-Z]+\d{0,2}|#\d\d\d{0,4}|#x[\da-fA-F][\da-fA-F][\da-fA-F]{0,3});)/, '', :bounding] ]
- VERSION =
'2.0.0'
Class Method Summary collapse
-
.convert(input, options = {}) ⇒ Object
(also: render)
Public: Parse the AsciiDoc source input into an Asciidoctor::Document and convert it to the specified backend format.
-
.convert_file(filename, options = {}) ⇒ Object
(also: render_file)
Public: Parse the contents of the AsciiDoc source file into an Asciidoctor::Document and convert it to the specified backend format.
-
.load(input, options = {}) ⇒ Object
Public: Parse the AsciiDoc source input into a Document.
-
.load_file(filename, options = {}) ⇒ Object
Public: Parse the contents of the AsciiDoc source file into an Asciidoctor::Document.
Instance Method Summary collapse
-
#const_missing(name) ⇒ Object
Internal: Automatically load the Asciidoctor::Extensions module.
Class Method Details
.convert(input, options = {}) ⇒ Object Also known as: render
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
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 |
# File 'lib/asciidoctor.rb', line 1365 def convert input, = {} = .merge .delete(:parse) to_file = .delete(:to_file) to_dir = .delete(:to_dir) mkdirs = .delete(:mkdirs) || false case to_file when true, nil write_to_same_dir = !to_dir && ::File === input stream_output = false write_to_target = to_dir to_file = nil when false write_to_same_dir = false stream_output = false write_to_target = false to_file = nil when '/dev/null' return self.load input, else write_to_same_dir = false write_to_target = (stream_output = to_file.respond_to? :write) ? false : ([:to_file] = to_file) end unless .key? :standalone if write_to_same_dir || write_to_target [:standalone] = true elsif .key? :header_footer [:standalone] = [:header_footer] end end # NOTE outfile may be controlled by document attributes, so resolve outfile after loading if write_to_same_dir input_path = ::File.absolute_path input.path [:to_dir] = (outdir = ::File.dirname input_path) elsif write_to_target if to_dir if to_file [:to_dir] = ::File.dirname ::File. ::File.join to_dir, to_file 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 = self.load input, if write_to_same_dir # write to file in same directory outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix}) if outfile == input_path raise ::IOError, %(input file and output file cannot be the same: #{outfile}) end 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 opts = outfile && !stream_output ? { 'outfile' => outfile, 'outdir' => outdir } : {} output = doc.convert opts 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').empty? 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 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 end end syntax_hl.write_stylesheet doc, stylesoutdir if copy_syntax_hl_stylesheet end end doc else output end end |
.convert_file(filename, options = {}) ⇒ Object Also known as: render_file
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
1522 1523 1524 |
# File 'lib/asciidoctor.rb', line 1522 def convert_file filename, = {} ::File.open(filename, FILE_READ_MODE) {|file| self.convert file, } end |
.load(input, options = {}) ⇒ Object
Public: Parse the AsciiDoc source input into a Document
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.
input - the AsciiDoc source as a IO, String or Array. options - a String, Array or Hash of options to control processing (default: {})
String and Array values are converted into a Hash.
See {Document#initialize} for details about these options.
Returns the Document
1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 |
# File 'lib/asciidoctor.rb', line 1233 def load input, = {} = .merge if (timings = [:timings]) timings.start :read end if (logger = [:logger]) && logger != LoggerManager.logger LoggerManager.logger = logger end if !(attrs = [:attributes]) attrs = {} elsif ::Hash === attrs attrs = attrs.merge elsif (defined? ::Java::JavaUtil::Map) && ::Java::JavaUtil::Map === attrs attrs = attrs.dup elsif ::Array === attrs attrs = {}.tap do |accum| attrs.each do |entry| k, _, v = entry.partition '=' accum[k] = v end end elsif ::String === attrs # condense and convert non-escaped spaces to null, unescape escaped spaces, then split on null attrs = {}.tap do |accum| attrs.gsub(SpaceDelimiterRx, '\1' + NULL).gsub(EscapedSpaceRx, '\1').split(NULL).each do |entry| k, _, v = entry.partition '=' accum[k] = v end end elsif (attrs.respond_to? :keys) && (attrs.respond_to? :[]) # coerce attrs to a real Hash attrs = {}.tap {|accum| attrs.keys.each {|k| accum[k] = attrs[k] } } else raise ::ArgumentError, %(illegal type for attributes option: #{attrs.class.ancestors.join ' < '}) end if ::File === input [:input_mtime] = input.mtime # TODO cli checks if input path can be read and is file, but might want to add check to API too input_path = ::File.absolute_path input.path # NOTE defer setting infile and indir until we get a better sense of their purpose attrs['docfile'] = input_path = ::File.absolute_path input.path attrs['docdir'] = ::File.dirname input_path attrs['docname'] = Helpers.basename input_path, (attrs['docfilesuffix'] = ::File.extname input_path) source = input.read elsif input.respond_to? :read # NOTE tty, pipes & sockets can't be rewound, but can't be sniffed easily either # just fail the rewind operation silently to handle all cases input.rewind rescue nil source = input.read elsif ::String === input source = input elsif ::Array === input source = input.drop 0 elsif input raise ::ArgumentError, %(unsupported input type: #{input.class}) end if timings timings.record :read timings.start :parse end [:attributes] = attrs doc = [:parse] == false ? (Document.new source, ) : (Document.new source, ).parse timings.record :parse if timings doc rescue => ex begin context = %(asciidoctor: FAILED: #{attrs['docfile'] || '<stdin>'}: Failed to load AsciiDoc document) if ex.respond_to? :exception # The original message must be explicitly preserved when wrapping a Ruby exception wrapped_ex = ex.exception %(#{context} - #{ex.}) # JRuby automatically sets backtrace; MRI did not until 2.6 wrapped_ex.set_backtrace ex.backtrace else # Likely a Java exception class wrapped_ex = ex.class.new context, ex wrapped_ex.stack_trace = ex.stack_trace end rescue wrapped_ex = ex end raise wrapped_ex end |
.load_file(filename, options = {}) ⇒ Object
Public: Parse the contents of the AsciiDoc source file into an Asciidoctor::Document
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 Asciidoctor::Document
1331 1332 1333 |
# File 'lib/asciidoctor.rb', line 1331 def load_file filename, = {} ::File.open(filename, FILE_READ_MODE) {|file| self.load file, } end |
Instance Method Details
#const_missing(name) ⇒ Object
Internal: Automatically load the Asciidoctor::Extensions module.
Requires the Asciidoctor::Extensions module if the name is :Extensions. Otherwise, delegates to the super method.
This method provides the same functionality as using autoload on Asciidoctor::Extensions, except that the constant isn’t recognized as defined prior to it being loaded.
Returns the resolved constant, if resolved, otherwise nothing.
1539 1540 1541 1542 1543 1544 1545 1546 |
# File 'lib/asciidoctor.rb', line 1539 def const_missing name if name == :Extensions require_relative 'asciidoctor/extensions' Extensions else super end end |