????JFIF??x?x????'
| Server IP : 172.67.174.47  /  Your IP : 216.73.216.113 Web Server : LiteSpeed System : Linux premium151.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64 User : tempvsty ( 647) PHP Version : 8.0.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /proc/thread-self/./root/opt/alt/ruby18/lib64/ruby/1.8/rdoc/ri/ | 
| Upload File : | 
module RI
  class TextFormatter
    attr_reader :indent
    
    def initialize(options, indent)
      @options = options
      @width   = options.width
      @indent  = indent
    end
    
    
    ######################################################################
    
    def draw_line(label=nil)
      len = @width
      len -= (label.size+1) if label
      print "-"*len
      if label
        print(" ")
        bold_print(label) 
      end
      puts
    end
    
    ######################################################################
    
    def wrap(txt,  prefix=@indent, linelen=@width)
      return unless txt && !txt.empty?
      work = conv_markup(txt)
      textLen = linelen - prefix.length
      patt = Regexp.new("^(.{0,#{textLen}})[ \n]")
      next_prefix = prefix.tr("^ ", " ")
      res = []
      while work.length > textLen
        if work =~ patt
          res << $1
          work.slice!(0, $&.length)
        else
          res << work.slice!(0, textLen)
        end
      end
      res << work if work.length.nonzero?
      puts(prefix + res.join("\n" + next_prefix))
    end
    ######################################################################
    def blankline
      puts
    end
    
    ######################################################################
    # called when we want to ensure a nbew 'wrap' starts on a newline
    # Only needed for HtmlFormatter, because the rest do their
    # own line breaking
    def break_to_newline
    end
    
    ######################################################################
    def bold_print(txt)
      print txt
    end
    ######################################################################
    def raw_print_line(txt)
      puts txt
    end
    ######################################################################
    # convert HTML entities back to ASCII
    def conv_html(txt)
      txt.
          gsub(/>/, '>').
          gsub(/</, '<').
          gsub(/"/, '"').
          gsub(/&/, '&')
          
    end
    # convert markup into display form
    def conv_markup(txt)
      txt.
          gsub(%r{<tt>(.*?)</tt>}) { "+#$1+" } .
          gsub(%r{<code>(.*?)</code>}) { "+#$1+" } .
          gsub(%r{<b>(.*?)</b>}) { "*#$1*" } .
          gsub(%r{<em>(.*?)</em>}) { "_#$1_" }
    end
    ######################################################################
    def display_list(list)
      case list.type
      when SM::ListBase::BULLET 
        prefixer = proc { |ignored| @indent + "*   " }
      when SM::ListBase::NUMBER,
      SM::ListBase::UPPERALPHA,
      SM::ListBase::LOWERALPHA
        start = case list.type
                when SM::ListBase::NUMBER      then 1
                when  SM::ListBase::UPPERALPHA then 'A'
                when SM::ListBase::LOWERALPHA  then 'a'
                end
        prefixer = proc do |ignored|
          res = @indent + "#{start}.".ljust(4)
          start = start.succ
          res
        end
        
      when SM::ListBase::LABELED
        prefixer = proc do |li|
          li.label
        end
      when SM::ListBase::NOTE
        longest = 0
        list.contents.each do |item|
          if item.kind_of?(SM::Flow::LI) && item.label.length > longest
            longest = item.label.length
          end
        end
        prefixer = proc do |li|
          @indent + li.label.ljust(longest+1)
        end
      else
        fail "unknown list type"
      end
      list.contents.each do |item|
        if item.kind_of? SM::Flow::LI
          prefix = prefixer.call(item)
          display_flow_item(item, prefix)
        else
          display_flow_item(item)
        end
       end
    end
    ######################################################################
    def display_flow_item(item, prefix=@indent)
      case item
      when SM::Flow::P, SM::Flow::LI
        wrap(conv_html(item.body), prefix)
        blankline
        
      when SM::Flow::LIST
        display_list(item)
      when SM::Flow::VERB
        display_verbatim_flow_item(item, @indent)
      when SM::Flow::H
        display_heading(conv_html(item.text), item.level, @indent)
      when SM::Flow::RULE
        draw_line
      else
        fail "Unknown flow element: #{item.class}"
      end
    end
    ######################################################################
    def display_verbatim_flow_item(item, prefix=@indent)
        item.body.split(/\n/).each do |line|
          print @indent, conv_html(line), "\n"
        end
        blankline
    end
    ######################################################################
    def display_heading(text, level, indent)
      text = strip_attributes(text)
      case level
      when 1
        ul = "=" * text.length
        puts
        puts text.upcase
        puts ul
#        puts
        
      when 2
        ul = "-" * text.length
        puts
        puts text
        puts ul
#        puts
      else
        print indent, text, "\n"
      end
    end
    def display_flow(flow)
      flow.each do |f|
        display_flow_item(f)
      end
    end
    def strip_attributes(txt)
      tokens = txt.split(%r{(</?(?:b|code|em|i|tt)>)})
      text = [] 
      attributes = 0
      tokens.each do |tok|
        case tok
        when %r{^</(\w+)>$}, %r{^<(\w+)>$}
          ;
        else
          text << tok
        end
      end
      text.join
    end
  end
  
  
  ######################################################################
  # Handle text with attributes. We're a base class: there are
  # different presentation classes (one, for example, uses overstrikes
  # to handle bold and underlining, while another using ANSI escape
  # sequences
  
  class AttributeFormatter < TextFormatter
    
    BOLD      = 1
    ITALIC    = 2
    CODE      = 4
    ATTR_MAP = {
      "b"    => BOLD,
      "code" => CODE,
      "em"   => ITALIC,
      "i"    => ITALIC,
      "tt"   => CODE
    }
    # TODO: struct?
    class AttrChar
      attr_reader :char
      attr_reader :attr
      def initialize(char, attr)
        @char = char
        @attr = attr
      end
    end
    
    class AttributeString
      attr_reader :txt
      def initialize
        @txt = []
        @optr = 0
      end
      def <<(char)
        @txt << char
      end
      def empty?
        @optr >= @txt.length
      end
      # accept non space, then all following spaces
      def next_word
        start = @optr
        len = @txt.length
        while @optr < len && @txt[@optr].char != " "
          @optr += 1
        end
        while @optr < len && @txt[@optr].char == " "
          @optr += 1
        end
        @txt[start...@optr]
      end
    end
    ######################################################################
    # overrides base class. Looks for <tt>...</tt> etc sequences
    # and generates an array of AttrChars. This array is then used
    # as the basis for the split
    def wrap(txt,  prefix=@indent, linelen=@width)
      return unless txt && !txt.empty?
      txt = add_attributes_to(txt)
      next_prefix = prefix.tr("^ ", " ")
      linelen -= prefix.size
      line = []
      until txt.empty?
        word = txt.next_word
        if word.size + line.size > linelen
          write_attribute_text(prefix, line)
          prefix = next_prefix
          line = []
        end
        line.concat(word)
      end
      write_attribute_text(prefix, line) if line.length > 0
    end
    protected
    # overridden in specific formatters
    def write_attribute_text(prefix, line)
      print prefix
      line.each do |achar|
        print achar.char
      end
      puts
    end
    # again, overridden
    def bold_print(txt)
      print txt
    end
    private
    def add_attributes_to(txt)
      tokens = txt.split(%r{(</?(?:b|code|em|i|tt)>)})
      text = AttributeString.new
      attributes = 0
      tokens.each do |tok|
        case tok
        when %r{^</(\w+)>$} then attributes &= ~(ATTR_MAP[$1]||0)
        when %r{^<(\w+)>$}  then attributes  |= (ATTR_MAP[$1]||0)
        else
          tok.split(//).each {|ch| text << AttrChar.new(ch, attributes)}
        end
      end
      text
    end
  end
  ##################################################
  
  # This formatter generates overstrike-style formatting, which
  # works with pagers such as man and less.
  class OverstrikeFormatter < AttributeFormatter
    BS = "\C-h"
    def write_attribute_text(prefix, line)
      print prefix
      line.each do |achar|
        attr = achar.attr
        if (attr & (ITALIC+CODE)) != 0
          print "_", BS
        end
        if (attr & BOLD) != 0
          print achar.char, BS
        end
        print achar.char
      end
      puts
    end
    # draw a string in bold
    def bold_print(text)
      text.split(//).each do |ch|
        print ch, BS, ch
      end
    end
  end
  ##################################################
  
  # This formatter uses ANSI escape sequences
  # to colorize stuff
  # works with pages such as man and less.
  class AnsiFormatter < AttributeFormatter
    def initialize(*args)
      print "\033[0m"
      super
    end
    def write_attribute_text(prefix, line)
      print prefix
      curr_attr = 0
      line.each do |achar|
        attr = achar.attr
        if achar.attr != curr_attr
          update_attributes(achar.attr)
          curr_attr = achar.attr
        end
        print achar.char
      end
      update_attributes(0) unless curr_attr.zero?
      puts
    end
    def bold_print(txt)
      print "\033[1m#{txt}\033[m"
    end
    HEADINGS = {
      1 => [ "\033[1;32m", "\033[m" ] ,
      2 => ["\033[4;32m", "\033[m" ],
      3 => ["\033[32m", "\033[m" ]
    }
    def display_heading(text, level, indent)
      level = 3 if level > 3
      heading = HEADINGS[level]
      print indent
      print heading[0]
      print strip_attributes(text)
      puts heading[1]
    end
    
    private
    ATTR_MAP = {
      BOLD   => "1",
      ITALIC => "33",
      CODE   => "36"
    }
    def update_attributes(attr)
      str = "\033["
      for quality in [ BOLD, ITALIC, CODE]
        unless (attr & quality).zero?
          str << ATTR_MAP[quality]
        end
      end
      print str, "m"
    end
  end
  ##################################################
  
  # This formatter uses HTML.
  class HtmlFormatter < AttributeFormatter
    def initialize(*args)
      super
    end
    def write_attribute_text(prefix, line)
      curr_attr = 0
      line.each do |achar|
        attr = achar.attr
        if achar.attr != curr_attr
          update_attributes(curr_attr, achar.attr)
          curr_attr = achar.attr
        end
        print(escape(achar.char))
      end
      update_attributes(curr_attr, 0) unless curr_attr.zero?
    end
    def draw_line(label=nil)
      if label != nil
        bold_print(label)
      end
      puts("<hr>")
    end
    def bold_print(txt)
      tag("b") { txt }
    end
    def blankline()
      puts("<p>")
    end
    def break_to_newline
      puts("<br>")
    end
    def display_heading(text, level, indent)
      level = 4 if level > 4
      tag("h#{level}") { text }
      puts
    end
    
    ######################################################################
    def display_list(list)
      case list.type
      when SM::ListBase::BULLET 
        list_type = "ul"
        prefixer = proc { |ignored| "<li>" }
      when SM::ListBase::NUMBER,
      SM::ListBase::UPPERALPHA,
      SM::ListBase::LOWERALPHA
        list_type = "ol"
        prefixer = proc { |ignored| "<li>" }
        
      when SM::ListBase::LABELED
        list_type = "dl"
        prefixer = proc do |li|
          "<dt><b>" + escape(li.label) + "</b><dd>"
        end
      when SM::ListBase::NOTE
        list_type = "table"
        prefixer = proc do |li|
          %{<tr valign="top"><td>#{li.label.gsub(/ /, ' ')}</td><td>}
        end
      else
        fail "unknown list type"
      end
      print "<#{list_type}>"
      list.contents.each do |item|
        if item.kind_of? SM::Flow::LI
          prefix = prefixer.call(item)
          print prefix
          display_flow_item(item, prefix)
        else
          display_flow_item(item)
        end
      end
      print "</#{list_type}>"
    end
    def display_verbatim_flow_item(item, prefix=@indent)
        print("<pre>")
        puts item.body
        puts("</pre>")
    end
    private
    ATTR_MAP = {
      BOLD   => "b>",
      ITALIC => "i>",
      CODE   => "tt>"
    }
    def update_attributes(current, wanted)
      str = ""
      # first turn off unwanted ones
      off = current & ~wanted
      for quality in [ BOLD, ITALIC, CODE]
        if (off & quality) > 0
          str << "</" + ATTR_MAP[quality]
        end
      end
      # now turn on wanted
      for quality in [ BOLD, ITALIC, CODE]
        unless (wanted & quality).zero?
          str << "<" << ATTR_MAP[quality]
        end
      end
      print str
    end
    def tag(code)
        print("<#{code}>")
        print(yield)
        print("</#{code}>")
    end
    def escape(str)
      str.
          gsub(/&/n, '&').
          gsub(/\"/n, '"').
          gsub(/>/n, '>').
          gsub(/</n, '<')
    end
  end
  ##################################################
  
  # This formatter reduces extra lines for a simpler output.
  # It improves way output looks for tools like IRC bots.
  class SimpleFormatter < TextFormatter
    ######################################################################
    # No extra blank lines
    def blankline
    end
    ######################################################################
    # Display labels only, no lines
    def draw_line(label=nil)
      unless label.nil? then
        bold_print(label) 
        puts
      end
    end
    ######################################################################
    # Place heading level indicators inline with heading.
    def display_heading(text, level, indent)
      text = strip_attributes(text)
      case level
      when 1
        puts "= " + text.upcase
      when 2
        puts "-- " + text
      else
        print indent, text, "\n"
      end
    end
  end
  # Finally, fill in the list of known formatters
  class TextFormatter
    FORMATTERS = {
      "ansi"   => AnsiFormatter,
      "bs"     => OverstrikeFormatter,
      "html"   => HtmlFormatter,
      "plain"  => TextFormatter,
      "simple" => SimpleFormatter,
    }
      
    def TextFormatter.list
      FORMATTERS.keys.sort.join(", ")
    end
    def TextFormatter.for(name)
      FORMATTERS[name.downcase]
    end
  end
end