class DocDiff::View

Constants

CONTEXT_POST_LENGTH
CONTEXT_PRE_LENGTH
HTMLEscapeDic
HTMLEscapePat
ManuedInsideEscapeDic
ManuedInsideEscapePat
ManuedOutsideEscapeDic
ManuedOutsideEscapePat
TTYEscapeDic
TTYEscapePat
UserEscapeDic
UserEscapePat
WDIFFEscapeDic
WDIFFEscapePat

Public Class Methods

new(difference, encoding, eol) click to toggle source

EOL_CHARS_PAT = Regexp.new(/rn|r(?!n)|(?:A|)n/m)

# File lib/docdiff/view.rb, line 29
  def initialize(difference, encoding, eol)
    @difference = difference
    @encoding = encoding
    @eol = eol
    @eol_char = {'CR'=>"\r", 'LF'=>"\n", 'CRLF'=>"\r\n"}[@eol]
#     if CharString::EOLChars[@eol]
#       @eol_char = CharString::EOLChars[@eol].eol_char
#     else
#       @eol_char = nil
#     end
  end

Public Instance Methods

apply_style(tags, headfoot = true) { |block || [].join| ... } click to toggle source
# File lib/docdiff/view.rb, line 56
def apply_style(tags, headfoot = true)
  result = []
  @difference.each{|block|
    operation = block.first
    if block_given?
      src = yield((block[1] || []).join)
      tgt = yield((block[1] || []).join)
    else
      src = (block[1] || []).join
      tgt = (block[2] || []).join
    end
    case operation
    when :common_elt_elt
      result << (tags[:start_common] + escape_outside(src, tags) + tags[:end_common])
    when :change_elt
      result << (tags[:start_before_change] + escape_inside(src, tags) + tags[:end_before_change] +
                 tags[:start_after_change]  + escape_inside(tgt, tags) + tags[:end_after_change])
    when :del_elt
      result << (tags[:start_del] + escape_inside(src, tags) + tags[:end_del])
    when :add_elt
      result << (tags[:start_add] + escape_inside(tgt, tags) + tags[:end_add])
    else
      raise "invalid attribute: #{block.first}\n"
    end
  }
  if headfoot == true
    result = tags[:header] + result + tags[:footer]
  end
  result.delete_if{|elem|elem==''}
end
apply_style_digest(tags, headfoot = true) { |entry || [].join| ... } click to toggle source
# File lib/docdiff/view.rb, line 94
def apply_style_digest(tags, headfoot = true)
  cxt_pre_pat  = Regexp.new('.{0,'+"#{CONTEXT_PRE_LENGTH}"+'}\Z',
                            Regexp::MULTILINE, encname_for_regexp(@encoding))
  cxt_post_pat = Regexp.new('\A.{0,'+"#{CONTEXT_POST_LENGTH}"+'}',
                            Regexp::MULTILINE, encname_for_regexp(@encoding))
  display = (tags and tags[:display]) || 'inline'
  result = []
  d1l = doc1_line_number = 1
  d2l = doc2_line_number = 1
  @difference.each_with_index{|entry, i|
    if block_given?
      src = yield((entry[1] || []).join)
      tgt = yield((entry[1] || []).join)
    else
      src = (entry[1] || []).join
      tgt = (entry[2] || []).join
    end
    cxt_pre = if i == 0
                 ""  # no pre context for the first entry
              else
                (@difference[i-1][1] || []).join.scan(cxt_pre_pat).join
              end
    cxt_post = if (i + 1) == @difference.size
                 ""  # no post context for the last entry
               else
                 (@difference[i+1][1] || []).join.scan(cxt_post_pat).join
               end
    # elements for an entry
    e_head     = Proc.new {|pos_str|
                           tags[:start_entry] + tags[:start_position] + pos_str + tags[:end_position]}
    e_cxt_pre  = tags[:start_prefix] + escape_outside(cxt_pre, tags) + tags[:end_prefix]
    e_src      = escape_inside(src, tags)
    e_chg      = tags[:start_before_change] + escape_inside(src, tags)  + tags[:end_before_change] +
                 tags[:start_after_change]  + escape_inside(tgt, tags)  + tags[:end_after_change]
    e_chgdel   = tags[:start_before_change] + escape_inside(src, tags)  + tags[:end_before_change]
    e_chgadd   = tags[:start_after_change]  + escape_inside(tgt, tags)  + tags[:end_after_change]
    e_del      = tags[:start_del]           + escape_outside(src, tags) + tags[:end_del]
    e_add      = tags[:start_add]           + escape_outside(tgt, tags) + tags[:end_add]
    e_cxt_post = tags[:start_postfix]       + escape_outside(cxt_post, tags) + tags[:end_postfix]
    e_foot     = tags[:end_entry] + (@eol_char||"")

    span1 = source_lines_involved = src.scan_lines(@eol).size
    span2 = target_lines_involved = tgt.scan_lines(@eol).size
    pos_str = ""
    case operation = entry.first
    when :common_elt_elt
      # skipping common part
    when :change_elt
      pos_str = "#{d1l}" + "#{if span1 > 1 then '-'+(d1l + span1 - 1).to_s; end}" +
                ",#{d2l}" + "#{if span2 > 1 then '-'+(d2l + span2 - 1).to_s; end}"
      case display
      when 'inline'
        result << (e_head.call(pos_str) + e_cxt_pre + e_chg + e_cxt_post + e_foot)
      when 'multi'
        result << (e_head.call(pos_str) + e_cxt_pre + e_chgdel + e_cxt_post +
                                          e_cxt_pre + e_chgadd + e_cxt_post + e_foot)
      else raise "Unsupported display type: #{display}"
      end
    when :del_elt
      pos_str = "#{d1l}" + "#{if span1 > 1 then '-'+(d1l + span1 - 1).to_s; end}" +
                ",(#{d2l})"
      case display
      when 'inline'
        result << (e_head.call(pos_str) + e_cxt_pre + e_del + e_cxt_post + e_foot)
      when 'multi'
        result << (e_head.call(pos_str) + e_cxt_pre + e_src + e_cxt_post +
                                          e_cxt_pre + e_del + e_cxt_post + e_foot)
      else raise "Unsupported display type: #{display}"
      end
    when :add_elt
      pos_str = "(#{d1l})" +
                ",#{d2l}" + "#{if span2 > 1 then '-'+(d2l + span2 - 1).to_s; end}"
      case display
      when 'inline'
        result << (e_head.call(pos_str) + e_cxt_pre + e_add + e_cxt_post + e_foot)
      when 'multi'
        result << (e_head.call(pos_str) + e_cxt_pre + e_src + e_cxt_post +
                                          e_cxt_pre + e_add + e_cxt_post + e_foot)
      else raise "Unsupported display type: #{display}"
      end
    else
      raise "invalid attribute: #{block.first}\n"
    end
    d1l += src.scan_eols(@eol).size
    d2l += tgt.scan_eols(@eol).size
  }
  result.unshift(tags[:start_digest_body])
  result.push(tags[:end_digest_body])
  result = tags[:header] + result + tags[:footer] if headfoot == true
  result.delete_if{|elem| elem == ''}
end
difference_digest() click to toggle source
# File lib/docdiff/view.rb, line 45
def difference_digest()
  #
end
difference_whole() click to toggle source
# File lib/docdiff/view.rb, line 41
def difference_whole()
  @difference
end
encname_for_regexp(encname) click to toggle source
# File lib/docdiff/view.rb, line 87
def encname_for_regexp(encname)
  # in 1.9.x, encoding names are deprecated except for N (ASCII-8BIT (binary))
  nil
end
escape_inside(str, tags) click to toggle source
# File lib/docdiff/view.rb, line 49
def escape_inside(str, tags)
  str.gsub(tags[:inside_escape_pat]){|m| tags[:inside_escape_dic][m]}
end
escape_outside(str, tags) click to toggle source
# File lib/docdiff/view.rb, line 52
def escape_outside(str, tags)
  str.gsub(tags[:outside_escape_pat]){|m| tags[:outside_escape_dic][m]}
end
html_header() click to toggle source

HTML (XHTML)

# File lib/docdiff/view.rb, line 248
def html_header()
  ["<?xml version=\"1.0\" encoding=\"#{@encoding||''}\"?>#{@eol_char||''}",
   "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"#{@eol_char||''}",
   "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">#{@eol_char||''}",
   "<html><head>#{@eol_char||''}",
   "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=#{@encoding||''}\" />#{@eol_char||''}",
   "<title>Difference</title>#{@eol_char||''}",
   "<style type=\"text/css\">#{@eol_char||''}" +
   " body {font-family: monospace;}#{@eol_char||''}" +
   " span.del {background: hotpink; border: thin inset;}#{@eol_char||''}" +
   " span.add {background: deepskyblue; font-weight: bolder; border: thin outset;}#{@eol_char||''}" +
   " span.before-change {background: yellow; border: thin inset;}#{@eol_char||''}" +
   " span.after-change {background: lime; font-weight: bolder; border: thin outset;}#{@eol_char||''}" +
   " li.entry .position {font-weight: bolder; margin-top: 0em; margin-bottom: 0em; padding-top: 0.5em; padding-bottom: 0em;}#{@eol_char||''}" +
   " li.entry .body {margin-top: 0em; margin-bottom: 0em; padding-top: 0em; padding-bottom: 0.5em;}#{@eol_char||''}" +
   " li.entry {border-top: thin solid gray;}#{@eol_char||''}" +
   "</style>#{@eol_char||''}",
   "</head><body><div>#{@eol_char||''}"]
end
html_tags() click to toggle source
# File lib/docdiff/view.rb, line 273
def html_tags()
  {:outside_escape_dic  => HTMLEscapeDic,
   :outside_escape_pat  => HTMLEscapePat,
   :inside_escape_dic   => HTMLEscapeDic,
   :inside_escape_pat   => HTMLEscapePat,
   :start_digest_body   => '<ul>',
   :end_digest_body     => '</ul>',
   :start_entry         => '<li class="entry">',
   :end_entry           => '</blockquote></li>',
   :start_position      => '<p class="position">',
   :end_position        => '</p><blockquote class="body">',
   :start_prefix        => '<p class="body">',
   :end_prefix          => '',
   :start_postfix       => '',
   :end_postfix         => '</p>',
   :header              => html_header(),
   :footer              => html_footer(),
   :start_common        => '<span class="common">',
   :end_common          => '</span>',
   :start_del           => '<span class="del"><del>',
   :end_del             => '</del></span>',
   :start_add           => '<span class="add"><ins>',
   :end_add             => '</ins></span>',
   :start_before_change => '<span class="before-change"><del>',
   :end_before_change   => '</del></span>',
   :start_after_change  => '<span class="after-change"><ins>',
   :end_after_change    => '</ins></span>'}
end
manued_header() click to toggle source

Manued

# File lib/docdiff/view.rb, line 313
def manued_header()
  ["defparentheses [ ]"        + (@eol_char||"\n"),
   "defdelete      /"          + (@eol_char||"\n"),
   "defswap        |"          + (@eol_char||"\n"),
   "defcomment     ;"          + (@eol_char||"\n"),
   "defescape      ~"          + (@eol_char||"\n"),
   "deforder       newer-last" + (@eol_char||"\n"),
   "defversion     0.9.5"      + (@eol_char||"\n")]
end
manued_tags() click to toggle source
# File lib/docdiff/view.rb, line 329
def manued_tags()
  {:inside_escape_dic   => ManuedInsideEscapeDic, 
   :inside_escape_pat   => ManuedInsideEscapePat,
   :outside_escape_dic  => ManuedOutsideEscapeDic,
   :outside_escape_pat  => ManuedOutsideEscapePat,
   :start_digest_body   => "----#{@eol_char||''}",
   :end_digest_body     => '',
   :start_entry         => '',
   :end_entry           => "----",
   :start_position      => '',
   :end_position        => "#{@eol_char||''}",
   :start_prefix        => '',
   :end_prefix          => '',
   :start_postfix       => '',
   :end_postfix         => "#{@eol_char||''}",
   :header              => manued_header(),
   :footer              => manued_footer(),
   :start_common        => '',
   :end_common          => '',
   :start_del           => '[',
   :end_del             => '/]',
   :start_add           => '[/',
   :end_add             => ']',
   :start_before_change => '[',
   :end_before_change   => '/',
   :start_after_change  => '',
   :end_after_change    => ']'
  }
end
source_lines() click to toggle source
# File lib/docdiff/view.rb, line 186
def source_lines()
  if @source_lines == nil
    @source_lines = @difference.collect{|entry| entry[1]}.join.scan_lines(@eol)
  end
  @source_lines
end
target_lines() click to toggle source
# File lib/docdiff/view.rb, line 192
def target_lines()
  if @target_lines == nil
    @target_lines = @difference.collect{|entry| entry[2]}.join.scan_lines(@eol)
  end
  @target_lines
end
to_debug() click to toggle source
# File lib/docdiff/view.rb, line 466
def to_debug()
end
to_html(overriding_opts = nil, headfoot = true) click to toggle source
# File lib/docdiff/view.rb, line 301
def to_html(overriding_opts = nil, headfoot = true)
  tags = html_tags()
  tags.update(overriding_opts) if overriding_opts
  apply_style(tags, headfoot)
end
to_html_digest(overriding_opts = nil, headfoot = true) click to toggle source
# File lib/docdiff/view.rb, line 306
def to_html_digest(overriding_opts = nil, headfoot = true)
  tags = html_tags()
  tags.update(overriding_opts) if overriding_opts
  apply_style_digest(tags, headfoot)
end
to_manued(overriding_opts = nil, headfoot = true) click to toggle source
# File lib/docdiff/view.rb, line 358
def to_manued(overriding_opts = nil, headfoot = true)  # [ / ; ]
  tags = manued_tags()
  tags.update(overriding_opts) if overriding_opts
  apply_style(tags, headfoot)
end
to_manued_digest(overriding_opts = nil, headfoot = true) click to toggle source
# File lib/docdiff/view.rb, line 363
def to_manued_digest(overriding_opts = nil, headfoot = true)  # [ / ; ]
  tags = manued_tags()
  # manued specific kludge: change should be [a/b] in inline, [a/][/b] in multi
  display = (overriding_opts and overriding_opts[:display]) || 'inline'
  if display == 'multi'
    tags.update({:end_before_change => '/]', :start_after_change => '[/'})
  end
  tags.update(overriding_opts) if overriding_opts
  apply_style_digest(tags, headfoot)
end
to_tty(overriding_opts = nil, headfoot = true) click to toggle source
# File lib/docdiff/view.rb, line 236
def to_tty(overriding_opts = nil, headfoot = true)  # color escape sequence
  tags = tty_tags()
  tags.update(overriding_opts) if overriding_opts
  apply_style(tags, headfoot)
end
to_tty_digest(overriding_opts = nil, headfoot = true) click to toggle source
# File lib/docdiff/view.rb, line 241
def to_tty_digest(overriding_opts = nil, headfoot = true)
  tags = tty_tags
  tags.update(overriding_opts) if overriding_opts
  apply_style_digest(tags, headfoot)
end
to_user(overriding_opts = nil, headfoot = true) click to toggle source
# File lib/docdiff/view.rb, line 455
def to_user(overriding_opts = nil, headfoot = true)
  tags = user_tags()
  tags.update(overriding_opts) if overriding_opts
  apply_style(tags, headfoot)
end
to_user_digest(overriding_opts = nil, headfoot = true) click to toggle source
# File lib/docdiff/view.rb, line 460
def to_user_digest(overriding_opts = nil, headfoot = true)
  tags = user_tags()
  tags.update(overriding_opts) if overriding_opts
  apply_style_digest(tags, headfoot)
end
to_wdiff(overriding_opts = nil, headfoot = true) click to toggle source
# File lib/docdiff/view.rb, line 411
def to_wdiff(overriding_opts = nil, headfoot = true)
  tags = wdiff_tags()
  tags.update(overriding_opts) if overriding_opts
  apply_style(tags)
end
to_wdiff_digest(overriding_opts = nil, headfoot = true) click to toggle source
# File lib/docdiff/view.rb, line 416
def to_wdiff_digest(overriding_opts = nil, headfoot = true)
  tags = wdiff_tags()
  tags.update(overriding_opts) if overriding_opts
  apply_style_digest(tags, headfoot)
end
tty_header() click to toggle source

tty (terminal)

# File lib/docdiff/view.rb, line 200
def tty_header()
  []
end
tty_tags() click to toggle source
# File lib/docdiff/view.rb, line 208
def tty_tags()
  {:outside_escape_dic  => TTYEscapeDic,
   :outside_escape_pat  => TTYEscapePat,
   :inside_escape_dic   => TTYEscapeDic,
   :inside_escape_pat   => TTYEscapePat,
   :start_digest_body   => "----#{@eol_char||''}",
   :end_digest_body     => '',
   :start_entry         => '',
   :end_entry           => "----",
   :start_position      => '',
   :end_position        => "#{@eol_char||''}",
   :start_prefix        => '',
   :end_prefix          => '',
   :start_postfix       => '',
   :end_postfix         => "#{@eol_char||''}",
   :header              => tty_header(),
   :footer              => tty_footer(),
   :start_common        => '',
   :end_common          => '',
   :start_del           => "\033[7;4;31m",  # Inverted, Underlined, Red
   :end_del             => "\033[0m",
   :start_add           => "\033[7;1;34m",  # Inverted, Bold, Blue
   :end_add             => "\033[0m",
   :start_before_change => "\033[7;4;33m",  # Inverted, Underlined, Yellow
   :end_before_change   => "\033[0m",
   :start_after_change  => "\033[7;1;32m",  # Inverted, Bold, Green
   :end_after_change    => "\033[0m"}
end
user_header() click to toggle source

user defined markup

# File lib/docdiff/view.rb, line 423
def user_header(); []; end
user_tags() click to toggle source
# File lib/docdiff/view.rb, line 427
def user_tags()
  {:outside_escape_dic  => UserEscapeDic,
   :outside_escape_pat  => UserEscapePat,
   :inside_escape_dic   => UserEscapeDic,
   :inside_escape_pat   => UserEscapePat,
   :start_digest_body   => '',
   :end_digest_body     => '',
   :start_entry         => '',
   :end_entry           => '',
   :start_position      => '',
   :end_position        => ' ',
   :start_prefix        => '',
   :end_prefix          => '',
   :start_postfix       => '',
   :end_postfix         => '',
   :header              => user_header(),
   :footer              => user_footer(),
   :start_common        => '',
   :end_common          => '',
   :start_del           => '',
   :end_del             => '',
   :start_add           => '',
   :end_add             => '',
   :start_before_change => '',
   :end_before_change   => '',
   :start_after_change  => '',
   :end_after_change    => ''}
end
wdiff_header() click to toggle source

wdiff-like

# File lib/docdiff/view.rb, line 375
def wdiff_header()
  []
end
wdiff_tags() click to toggle source
# File lib/docdiff/view.rb, line 383
def wdiff_tags()
  {:outside_escape_dic  => WDIFFEscapeDic,
   :outside_escape_pat  => WDIFFEscapePat,
   :inside_escape_dic   => WDIFFEscapeDic,
   :inside_escape_pat   => WDIFFEscapePat,
   :start_digest_body   => "----#{@eol_char||''}",
   :end_digest_body     => '',
   :start_entry         => '',
   :end_entry           => "----",
   :start_position      => '',
   :end_position        => "#{@eol_char||''}",
   :start_prefix        => '',
   :end_prefix          => '',
   :start_postfix       => '',
   :end_postfix         => "#{@eol_char||''}",
   :header              => wdiff_header(),
   :footer              => wdiff_footer(),
   :start_common        => '',
   :end_common          => '',
   :start_del           => '[-',
   :end_del             => '-]',
   :start_add           => '{+',
   :end_add             => '+}',
   :start_before_change => '[-',
   :end_before_change   => '-]',
   :start_after_change  => '{+',
   :end_after_change    => '+}'}
end