@@ -56,11 +56,11 @@ module Asciidoctor
   LIST_CONTINUATION = '+'
 
   REGEXP = {
-    # [[Foo]]  (also allows, say, [[[]] or [[[Foo[f]], but I don't think it is supposed to (TODO))
-    :anchor           => /^\[(\[.+\])\]\s*$/,
+    # [[Foo]]
+    :anchor           => /^\[\[([^\[]+)\]\]\s*$/,
 
     # Foowhatevs [[Bar]]
-    :anchor_embedded  => /^(.*)\[\[([^\]]+)\]\]\s*$/,
+    :anchor_embedded  => /^(.*?)\s*\[\[([^\[]+)\]\]\s*$/,
 
     # +   Attribute values treat lines ending with ' +' as a continuation,
     #     not a line-break as elsewhere in the document, where this is
require 'rubygems'
require 'cgi'
require 'erb'
require 'tilt'

$:.unshift(File.dirname(__FILE__))
$:.unshift(File.join(File.dirname(__FILE__), '..', 'vendor'))

# Public: Methods for parsing Asciidoc input files and rendering documents
# using erb templates.
#
# Asciidoc documents comprise a header followed by zero or more sections.
# Sections are composed of blocks of content.  For example:
#
#   Doc Title
#   =========
#
#   SECTION 1
#   ---------
#
#   This is a paragraph block in the first section.
#
#   SECTION 2
#
#   This section has a paragraph block and an olist block.
#
#   1. Item 1
#   2. Item 2
#
# Examples:
#
# Use built-in templates:
#
#   lines = File.readlines("your_file.asc")
#   doc = Asciidoctor::Document.new(lines)
#   html = doc.render
#   File.open("your_file.html", "w+") do |file|
#     file.puts html
#   end
#
# Use custom (Tilt-supported) templates:
#
#   lines = File.readlines("your_file.asc")
#   doc = Asciidoctor::Document.new(lines, :template_dir => 'templates')
#   html = doc.render
#   File.open("your_file.html", "w+") do |file|
#     file.puts html
#   end
module Asciidoctor
  # The default document type
  # Can influence markup generated by render templates
  DEFAULT_DOCTYPE = 'article'

  LIST_CONTEXTS = [:ulist, :olist, :dlist]

  LIST_CONTINUATION = '+'

  REGEXP = {
    # [[Foo]]  (also allows, say, [[[]] or [[[Foo[f]], but I don't think it is supposed to (TODO))
    :anchor           => /^\[(\[.+\])\]\s*$/,

    # Foowhatevs [[Bar]]
    :anchor_embedded  => /^(.*)\[\[([^\]]+)\]\]\s*$/,

    # +   Attribute values treat lines ending with ' +' as a continuation,
    #     not a line-break as elsewhere in the document, where this is
    #     a forced line break. This should be the same regexp as :line_break,
    #     below, but it gets its own entry because readability ftw, even
    #     though repeating regexps ftl.
    :attr_continue    => /^(.*)[[:blank:]]\+[[:blank:]]*$/,

    # An attribute list above a block element
    #
    # Can be strictly positional:
    # [quote, Adam Smith, Wealth of Nations]
    # Or can have name/value pairs
    # [NOTE, caption="Good to know"]
    :attr_list_blk    => /^\[(\w.*)\]$/,

    # [[[Foo]]]  (does not suffer quite the same malady as :anchor, but almost. Allows [ but not ] in internal capture
    :biblio           => /\[\[\[([^\]]+)\]\]\]/,

    # <1> Foo
    :colist           => /^(\<\d+\>)\s*(.*)/,

    # ////
    # comment block
    # ////
    :comment_blk      => /^\/{4,}\s*$/,

    # // (and then whatever)
    :comment          => /^\/\/([^\/].*|)$/,

    # foo::  ||  foo;;
    # Should be followed by a definition line, e.g.,
    # foo::
    #    That which precedes 'bar' (see also, bar)
    :dlist            => /^\s*(?:\[\[([^\]]*)\]\])?(\w.*?)(:{2,4}|;;)(\s+(.*))?$/,
    :dlist_siblings   => {
                           # (?:.*?[^:])? - a non-capturing group which grabs longest sequence of characters that doesn't end w/ colon
                           '::' => /^\s*(?:\[\[([^\]]*)\]\])?(\w(?:.*[^:])?)(::)(\s+(.*))?$/,
                           ':::' => /^\s*(?:\[\[([^\]]*)\]\])?(\w(?:.*[^:])?)(:::)(\s+(.*))?$/,
                           '::::' => /^\s*(?:\[\[([^\]]*)\]\])?(\w(?:.*[^:])?)(::::)(\s+(.*))?$/,
                           ';;' => /^\s*(?:\[\[([^\]]*)\]\])?(\w.*)(;;)(\s+(.*))?$/
                         },
    # ====
    :example          => /^={4,}\s*$/,

    # image::filename.png[Caption]
    :image_blk        => /^image::(\S+?)\[(.*?)\]$/,

    # == Foo
    # ^ yields a level 2 title
    #
    # == Foo ==
    # ^ also yields a level 2 title
    #
    # both equivalent to this two-line version:
    # Foo
    # ~~~
    #
    # match[1] is the delimiter, whose length determines the level
    # match[2] is the title itself
    # match[3] is an optional repeat of the delimiter, which is dropped
    :level_title      => /^(={1,5})\s+(\S.*?)\s*(\s\1)?$/,

    # ======  || ------ || ~~~~~~ || ^^^^^^ || ++++++
    :line             => /^([=\-~^\+])+\s*$/,

    # +   From the Asciidoc User Guide: "A plus character preceded by at
    #     least one space character at the end of a non-blank line forces
    #     a line break. It generates a line break (br) tag for HTML outputs.
    #
    # +      (would not match because there's no space before +)
    #  +     (would match and capture '')
    # Foo +  (would and capture 'Foo')
    :line_break       => /([[:blank:]])\+[[:blank:]]*$/,

    # ----
    :listing          => /^\-{4,}\s*$/,

    # ....
    :lit_blk          => /^\.{4,}\s*$/,

    # <TAB>Foo  or one-or-more-spaces-or-tabs then whatever
    :lit_par          => /^([ \t]+.*)$/,

    # "Wooble"  ||  Wooble
    :name             => /^(["A-Za-z].*)\s*$/,  # I believe this fails to require " chars to be paired (TODO)

    # --
    :oblock           => /^\-\-\s*$/,

    # 1.Foo  ||  1. Foo  ||  . Foo
    :olist            => /^\s*(\d+\.|\. )(.*)$/,

    # ____
    :quote            => /^_{4,}\s*$/,

    # '''
    :ruler            => /^'{3,}\s*$/,

    # ****
    :sidebar_blk      => /^\*{4,}\s*$/,

    #     and blah blah blah
    # ^^^^  <--- whitespace
    :starts_with_whitespace => /\s+(.+)\s+\+\s*$/,

    # .Foo   but not  . Foo or ..Foo
    :title            => /^\.([^\s\.].*)\s*$/,

    # * Foo  ||  - Foo
    :ulist            => /^ \s* (- | \*{1,5}) \s+ (.*) $/x
  }

  ADMONITION_STYLES = ['NOTE', 'TIP', 'IMPORTANT', 'WARNING', 'CAUTION']

  INTRINSICS = Hash.new{|h,k| STDERR.puts "Missing intrinsic: #{k.inspect}"; "{#{k}}"}.merge(
    {
    'startsb'    => '[',
    'endsb'      => ']',
    'brvbar'     => '|',
    'caret'      => '^',
    'asterisk'   => '*',
    'tilde'      => '~',
    'litdd'      => '--',
    'plus'       => '+',
    'apostrophe' => '\'',
    'backslash'  => '\\',
    'backtick'   => '`',
    'empty'      => '',
    'sp'         => ' ',
    'two-colons' => '::',
    'two-semicolons' => ';;',
    'nbsp'       => '&#160;',
    'deg'        => '&#176;',
    'zwsp'       => '&#8203;',
    'lsquo'      => '&#8216;',
    'rsquo'      => '&#8217;',
    'ldquo'      => '&#8220;',
    'rdquo'      => '&#8221;',
    'wj'         => '&#8288;',
    'amp'        => '&',
    'lt'         => '<',
    'gt'         => '>',
    }
  )

  SPECIAL_CHARS = {
    '<' => '&lt;',
    '>' => '&gt;',
    '&' => '&amp;'
  }

  HTML_ELEMENTS = {
    'br-asciidoctor' => '<br/>'
  }

  require 'asciidoctor/block'
  require 'asciidoctor/debug'
  require 'asciidoctor/document'
  require 'asciidoctor/errors'
  require 'asciidoctor/lexer'
  require 'asciidoctor/list_item'
  require 'asciidoctor/reader'
  require 'asciidoctor/render_templates'
  require 'asciidoctor/renderer'
  require 'asciidoctor/section'
  require 'asciidoctor/string'
  require 'asciidoctor/version'
end

I don't understand the first `?` inside the first paren group. Does `?)` have a semantic meaning I've missed here? Otherwise, if `?` is 1-or-0-of-the-last-thing, and the last thing is `.*`, then that's the same as `.*`, isn't it? I'm still drug-addled, beware.