class HikiDoc
Constants
- BLANK
- BLOCKQUOTE_RE
- BLOCK_PRE_CLOSE_RE
- BLOCK_PRE_OPEN_RE
- BRACKET_LINK_RE
-
Inline Level
- COMMENT_RE
- DEL
- DEL_RE
- DLIST_RE
- EM
- EM_RE
- HEADER_RE
- HRULE_RE
- IMAGE_EXTS
- INDENTED_PRE_RE
- LIST_RE
- MODIFIER_RE
- MODTAG
- OLIST
- PARAGRAPH_END_RE
- STRONG
- STRONG_RE
- TABLE_RE
- TT
- TT_RE
- ULIST
- URI_RE
- VERSION
- WIKI_NAME_RE
Public Class Methods
Source
# File lib/hikidoc.rb, line 56 def initialize(output, options = {}) @output = output @options = default_options.merge(options) @header_re = nil @level = options[:level] || 1 @plugin_syntax = options[:plugin_syntax] || method(:valid_plugin_syntax?) end
Source
# File lib/hikidoc.rb, line 48 def HikiDoc.to_html(src, options = {}) new(HTMLOutput.new(">"), options).compile(src) end
Source
# File lib/hikidoc.rb, line 52 def HikiDoc.to_xhtml(src, options = {}) new(HTMLOutput.new(" />"), options).compile(src) end
Public Instance Methods
Source
# File lib/hikidoc.rb, line 64 def compile(src) @output.reset escape_plugin_blocks(src) {|escaped| compile_blocks escaped @output.finish } end
Source
# File lib/hikidoc.rb, line 73 def to_html $stderr.puts("warning: HikiDoc#to_html is deprecated. Please use HikiDoc.to_html or HikiDoc.to_xhtml instead.") self.class.to_html(@output, @options) end
for backward compatibility
Private Instance Methods
Source
# File lib/hikidoc.rb, line 456 def can_image_link?(uri) image?(uri) and @options[:allow_bracket_inline_image] end
Source
# File lib/hikidoc.rb, line 339 def compile_block_pre(f) m = BLOCK_PRE_OPEN_RE.match(f.gets) or raise UnexpectedError, "must not happen" str = restore_plugin_block(f.break(BLOCK_PRE_CLOSE_RE).join.chomp) f.gets @output.block_preformatted(str, m[1]) end
Source
# File lib/hikidoc.rb, line 316 def compile_blockquote(f) @output.blockquote_open lines = [] f.while_match(BLOCKQUOTE_RE) do |line| lines.push line.sub(BLOCKQUOTE_RE, "") skip_comments f end compile_blocks lines.join("") @output.blockquote_close end
Source
# File lib/hikidoc.rb, line 155 def compile_blocks(src) f = LineInput.new(StringIO.new(src)) while line = f.peek case line when COMMENT_RE f.gets when HEADER_RE compile_header f.gets when HRULE_RE f.gets compile_hrule when LIST_RE compile_list f when DLIST_RE compile_dlist f when TABLE_RE compile_table f when BLOCKQUOTE_RE compile_blockquote f when INDENTED_PRE_RE compile_indented_pre f when BLOCK_PRE_OPEN_RE compile_block_pre f else if /^$/ =~ line f.gets next end compile_paragraph f end end end
Block Level
Source
# File lib/hikidoc.rb, line 436 def compile_bracket_link(link) if m = /\A(.*)\|/.match(link) title = m[0].chop uri = m.post_match fixed_uri = fix_uri(uri) if can_image_link?(uri) @output.image_hyperlink(fixed_uri, title) else @output.hyperlink(fixed_uri, compile_modifier(title)) end else fixed_link = fix_uri(link) if can_image_link?(link) @output.image_hyperlink(fixed_link) else @output.hyperlink(fixed_link, @output.text(link)) end end end
Source
# File lib/hikidoc.rb, line 261 def compile_dlist(f) @output.dlist_open f.while_match(DLIST_RE) do |line| dt, dd = split_dlitem(line.sub(DLIST_RE, "")) @output.dlist_item compile_inline(dt), compile_inline(dd) skip_comments f end @output.dlist_close end
Source
# File lib/hikidoc.rb, line 197 def compile_header(line) @header_re ||= /\A!{1,#{7 - @level}}/ level = @level + (line.slice!(@header_re).size - 1) title = strip(line) @output.headline level, compile_inline(title) end
Source
# File lib/hikidoc.rb, line 329 def compile_indented_pre(f) lines = f.span(INDENTED_PRE_RE)\ .map {|line| rstrip(line.sub(INDENTED_PRE_RE, "")) } text = restore_plugin_block(lines.join("\n")) @output.preformatted(@output.text(text)) end
Source
# File lib/hikidoc.rb, line 399 def compile_inline(str, buf = nil) buf ||= @output.container re = inline_syntax_re pending_str = nil while m = re.match(str) str = m.post_match link, uri, mod, wiki_name = m[1, 4] if wiki_name and wiki_name[0, 1] == "^" pending_str = m.pre_match + wiki_name[1..-1] + str next end pre_str = "#{pending_str}#{m.pre_match}" pending_str = nil evaluate_plugin_block(pre_str, buf) compile_inline_markup(buf, link, uri, mod, wiki_name) end evaluate_plugin_block(pending_str || str, buf) buf end
Source
# File lib/hikidoc.rb, line 421 def compile_inline_markup(buf, link, uri, mod, wiki_name) case when link buf << compile_bracket_link(link[2...-2]) when uri buf << compile_uri_autolink(uri) when mod buf << compile_modifier(mod) when wiki_name buf << @output.wiki_name(wiki_name) else raise UnexpectedError, "must not happen" end end
Source
# File lib/hikidoc.rb, line 214 def compile_list(f) typestack = [] level = 0 @output.list_begin f.while_match(LIST_RE) do |line| list_type = (line[0,1] == ULIST ? "ul" : "ol") new_level = line.slice(LIST_RE).size item = strip(line.sub(LIST_RE, "")) if new_level > level (new_level - level).times do typestack.push list_type @output.list_open list_type @output.listitem_open end @output.listitem compile_inline(item) elsif new_level < level (level - new_level).times do @output.listitem_close @output.list_close typestack.pop end @output.listitem_close @output.listitem_open @output.listitem compile_inline(item) elsif list_type == typestack.last @output.listitem_close @output.listitem_open @output.listitem compile_inline(item) else @output.listitem_close @output.list_close typestack.pop @output.list_open list_type @output.listitem_open @output.listitem compile_inline(item) typestack.push list_type end level = new_level skip_comments f end level.times do @output.listitem_close @output.list_close typestack.pop end @output.list_end end
Source
# File lib/hikidoc.rb, line 501 def compile_modifier(str) buf = @output.container while m = / (#{MODIFIER_RE}) /xo.match(str) evaluate_plugin_block(m.pre_match, buf) case when chunk = m[1] mod, s = split_mod(chunk) mid = MODTAG[mod] buf << @output.__send__(mid, compile_inline(s)) else raise UnexpectedError, "must not happen" end str = m.post_match end evaluate_plugin_block(str, buf) buf end
Source
# File lib/hikidoc.rb, line 352 def compile_paragraph(f) lines = f.break(PARAGRAPH_END_RE)\ .reject {|line| COMMENT_RE =~ line } if lines.size == 1 and /\A\0(\d+)\0\z/ =~ strip(lines[0]) @output.block_plugin plugin_block($1.to_i) else line_buffer = @output.container(:paragraph) lines.each_with_index do |line, i| buffer = @output.container line_buffer << buffer compile_inline(lstrip(line).chomp, buffer) end @output.paragraph(line_buffer) end end
Source
# File lib/hikidoc.rb, line 282 def compile_table(f) lines = [] f.while_match(TABLE_RE) do |line| lines.push line skip_comments f end @output.table_open lines.each do |line| @output.table_record_open split_columns(line.sub(TABLE_RE, "")).each do |col| mid = col.sub!(/\A!/, "") ? "table_head" : "table_data" span = col.slice!(/\A[\^>]*/) rs = span_count(span, "^") cs = span_count(span, ">") @output.__send__(mid, compile_inline(col), rs, cs) end @output.table_record_close end @output.table_close end
Source
# File lib/hikidoc.rb, line 460 def compile_uri_autolink(uri) if image?(uri) @output.image_hyperlink(fix_uri(uri)) else @output.hyperlink(fix_uri(uri), @output.text(uri)) end end
Source
# File lib/hikidoc.rb, line 80 def default_options { allow_bracket_inline_image: true, use_wiki_name: true, use_not_wiki_name: true, } end
Source
# File lib/hikidoc.rb, line 96 def escape_plugin_blocks(text) s = StringScanner.new(text) buf = "" @plugin_blocks = [] while chunk = s.scan_until(/\{\{/) chunk[-2, 2] = "" buf << chunk if block = extract_plugin_block(s) @plugin_blocks.push block buf << "\0#{@plugin_blocks.size - 1}\0" else buf << "{{" end end buf << s.rest yield(buf) end
Source
# File lib/hikidoc.rb, line 120 def evaluate_plugin_block(str, buf = nil) buf ||= @output.container str.split(/(\0\d+\0)/).each do |s| if s[0, 1] == "\0" and s[-1, 1] == "\0" buf << @output.inline_plugin(plugin_block(s[1..-2].to_i)) else buf << @output.text(s) end end buf end
Source
# File lib/hikidoc.rb, line 136 def extract_plugin_block(s) pos = s.pos buf = "" while chunk = s.scan_until(/\}\}/) buf << chunk buf.chomp!("}}") if @plugin_syntax.call(buf) return buf end buf << "}}" end s.pos = pos nil end
Source
# File lib/hikidoc.rb, line 468 def fix_uri(uri) if /\A(?:https?|ftp|file):(?!\/\/)/ =~ uri uri.sub(/\A\w+:/, "") else uri end end
Source
# File lib/hikidoc.rb, line 478 def image?(uri) IMAGE_EXTS.include?(uri[/\.[^.]+\z/].to_s.downcase) end
Source
# File lib/hikidoc.rb, line 376 def inline_syntax_re if @options[:use_wiki_name] if @options[:use_not_wiki_name] / (#{BRACKET_LINK_RE}) | (#{URI_RE}) | (#{MODIFIER_RE}) | (\^?#{WIKI_NAME_RE}) /xo else / (#{BRACKET_LINK_RE}) | (#{URI_RE}) | (#{MODIFIER_RE}) | (#{WIKI_NAME_RE}) /xo end else / (#{BRACKET_LINK_RE}) | (#{URI_RE}) | (#{MODIFIER_RE}) /xo end end
Source
# File lib/hikidoc.rb, line 543 def lstrip(str) str.sub(/\A[ \t\r\n\v\f]+/, "") end
Source
# File lib/hikidoc.rb, line 132 def plugin_block(id) @plugin_blocks[id] or raise UnexpectedError, "must not happen: #{id.inspect}" end
Source
# File lib/hikidoc.rb, line 114 def restore_plugin_block(str) str.gsub(/\0(\d+)\0/) { "{{" + plugin_block($1.to_i) + "}}" } end
Source
# File lib/hikidoc.rb, line 539 def rstrip(str) str.sub(/[ \t\r\n\v\f]+\z/, "") end
Source
# File lib/hikidoc.rb, line 190 def skip_comments(f) f.while_match(COMMENT_RE) do |line| end end
Source
# File lib/hikidoc.rb, line 309 def span_count(str, ch) c = str.count(ch) c == 0 ? nil : c + 1 end
Source
# File lib/hikidoc.rb, line 303 def split_columns(str) cols = str.split(/\|\|/) cols.pop if cols.last.chomp.empty? cols end
Source
# File lib/hikidoc.rb, line 271 def split_dlitem(line) re = /\A((?:#{BRACKET_LINK_RE}|.)*?):/o if m = re.match(line) return m[1], m.post_match else return line, "" end end
Source
# File lib/hikidoc.rb, line 520 def split_mod(str) case str when /\A'''/ return str[0, 3], str[3...-3] when /\A''/ return str[0, 2], str[2...-2] when /\A==/ return str[0, 2], str[2...-2] when /\A``/ return str[0, 2], str[2...-2] else raise UnexpectedError, "must not happen: #{str.inspect}" end end
Source
# File lib/hikidoc.rb, line 92 def valid_plugin_syntax?(code) /['"]/ !~ code.gsub(/\\\\/, "").gsub(/\\['"]/,"").gsub(/'[^']*'|"[^"]*"/m, "") end
Plugin