Class: Brut::TUI::MarkupString

Inherits:
Object
  • Object
show all
Defined in:
lib/brut/tui/markup_string.rb

Overview

A string that responds to limited markup that can be used to apply styles to the string

Constant Summary collapse

DELIMITERS =
{
  "*" => :bold,
  "_" => :weak,
  "`" => :code,
  "~" => :strike,
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(string) ⇒ MarkupString

Returns a new instance of MarkupString.



12
13
14
# File 'lib/brut/tui/markup_string.rb', line 12

def initialize(string)
  @string = string
end

Class Method Details

.from_string(string) ⇒ Brut::TUI::MarkupString

Create a MarkupString from a normal string.

Parameters:

Returns:

  • (Brut::TUI::MarkupString)

    if string is a Brut::TUI::MarkupString already, returns that, otherwise, wraps string in a Brut::TUI::MarkupString.



8
9
10
# File 'lib/brut/tui/markup_string.rb', line 8

def self.from_string(string)
  string.kind_of?(Brut::TUI::MarkupString) ? string : self.new(string.to_s)
end

Instance Method Details

#parse {|directive, value| ... } ⇒ Object

Parse the string for known markup, yielding at key parsing events.

Yields:

  • (directive, value)

    called for each parsing event, where value depends on directive. The block will be called for all parts of the string.

Yield Parameters:

  • directive (Symbol)

    one of :start, :stop, or :text. :text is for any text and doesn't include the markup characters. :start and :stop are called when a markup start or stop is found.

  • value (String|Symbol)

    For the :text directive, this is the text fragment from the string, so for the string "*foo*", :text would be called with "foo". For :start or :stop, the value is the type of markup encountered, one of :bold, :weak, :code, or :strike.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/brut/tui/markup_string.rb', line 32

def parse(&block)
  in_delimiter = DELIMITERS.keys.map { [ it, false ] }.to_h

  previous_character          = nil
  previous_previous_character = nil

  @string.each_char do |char|
    if DELIMITERS.key?(char) && previous_character != "\\" && previous_previous_character != "\\"
      style = DELIMITERS[char]
      if in_delimiter[char]
        block.(:stop, style)
        in_delimiter[char] = false
      else
        inside_code = in_delimiter["`"]
        if inside_code
          block.(:text, char)
        else
          block.(:start, style)
          in_delimiter[char] = true
        end
      end
    else
      if char == "\\"
        if previous_character == "\\"
          block.(:text, char)
        else
          # eat it - it is escaping something maybe
        end
      else
        block.(:text, char)
      end
    end
    previous_previous_character = previous_character
    previous_character          = char
  end
end