Class: Txt2Tags

Inherits:
Object
  • Object
show all
Defined in:
lib/txt2tags.rb

Overview

TXT2Tags - Converts t2t files to another formats

Constant Summary collapse

BEAUTIFIERS =

The basic transformations

One regexp by mark, the content must be in a group: (.*?)

{
  monospace: Regexp.new('``(.*?)``'),
  bold: Regexp.new('\*\*(.*?)\*\*'),
  italic: Regexp.new('//(.*?)//'),
  underline: Regexp.new('__(.*?)__'),
  strike: Regexp.new('--(.*?)--')
}.freeze
TITLES =

Only one linners transformations

One regexp by mark, the content must be in a group: (.*?)

{
  title1: Regexp.new('\A= (.*?) ='),
  title2: Regexp.new('\A== (.*?) =='),
  title3: Regexp.new('\A=== (.*?) ===')
}.freeze
BLOCKS =

Define blocks os lines transformation

  • begin_re -> identify the begin of a blocks

  • end_re -> identify the end of a blocks

  • apply_inline -> can apply the BEAUTIFIERS and TITLES transformations?

  • strip -> can strip spaces from line begin?

  • ignore_match_line -> begin and end lines will be discarded?

{
  quote: {
    begin_re: Regexp.new('\A\s+'),
    end_re: Regexp.new('\A\Z'),
    apply_inline: true,
    strip: true,
    ignore_match_line: false
  },
  verbatim: {
    begin_re: Regexp.new('\A```\Z'),
    end_re: Regexp.new('\A```\Z'),
    apply_inline: false,
    strip: false,
    ignore_match_line: true
  }
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ Txt2Tags

Save input type



52
53
54
55
56
57
58
59
60
# File 'lib/txt2tags.rb', line 52

def initialize(input)
  if input.respond_to?(:read)
    @input = input
  elsif input.respond_to?(:to_s)
    @input = StringIO.new(input.to_s)
  else
    raise 'Cannot read this.'
  end
end

Instance Attribute Details

#BEAUTIFIERSObject (readonly)

Returns the value of attribute BEAUTIFIERS.



5
6
7
# File 'lib/txt2tags.rb', line 5

def BEAUTIFIERS
  @BEAUTIFIERS
end

#BLOCKSObject (readonly)

Returns the value of attribute BLOCKS.



5
6
7
# File 'lib/txt2tags.rb', line 5

def BLOCKS
  @BLOCKS
end

#TITLESObject (readonly)

Returns the value of attribute TITLES.



5
6
7
# File 'lib/txt2tags.rb', line 5

def TITLES
  @TITLES
end

Instance Method Details

#apply_marks!(conversion, line) ⇒ Object

Apply the basic conversions (no BLOCKS) to a line



136
137
138
139
140
141
142
143
# File 'lib/txt2tags.rb', line 136

def apply_marks!(conversion, line)
  [:BEAUTIFIERS, :TITLES].each do |type|
    type_array = Txt2Tags.const_get(type)
    type_array.keys.each do |rule|
      line.gsub!(type_array[rule], conversion.const_get(type)[rule])
    end
  end
end

#formatsObject

Discover available formats



146
147
148
149
150
151
152
153
# File 'lib/txt2tags.rb', line 146

def formats
  format_list = []
  Dir[File.join(__dir__, 'txt2tags', '*.rb')].each do |format|
    format_list.push File.basename(format, '.rb')
  end

  format_list
end

#load_format(name) ⇒ Object

Require the format using a string as reference



156
157
158
159
# File 'lib/txt2tags.rb', line 156

def load_format(name)
  require "txt2tags/#{name}"
  Object.const_get(File.basename(name, '.rb').capitalize!)
end

#output(format) ⇒ Object

Process conform ‘format’ and return a iterator with processed input



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/txt2tags.rb', line 63

def output(format)
  block = nil
  ignore_line = false

  Enumerator.new do |y|
    # We can this multiples times
    begin
      @input.rewind
    rescue Errno::ESPIPE
    end

    # Comments are discarded (lines beginnig with %)
    @input.readlines.reject { |l| l.start_with?('%') }.each do |line|
      # right space are discarded (line terminators, tabs and spaces)
      line.rstrip!

      # We are already inside a block?
      if !block.nil?
        # We find the end of a block?
        if BLOCKS[block][:end_re].match line
          # Send the end mark for this format
          y.yield format::BLOCKS[block][:end]

          # We can ignore the actual line?
          if BLOCKS[block][:ignore_match_line]
            block = nil
            next
          end
        end
      else
        # Searching for a new block...
        BLOCKS.keys.each do |m|
          # No...
          next unless BLOCKS[m][:begin_re].match line

          # Yes!
          block = m
          # We can ignore the actual line?
          ignore_line = BLOCKS[block][:ignore_match_line]

          # Send the begin mark for this format
          y.yield format::BLOCKS[block][:begin]

          # We already figured out what to do, we do not have to keep looking
          break
        end
      end

      # Ignore this line? The others we'll find out.
      if ignore_line
        # The next line we still do not know if we ignore
        ignore_line = false
        next
      end

      # We can strip spaces from the begin of this line?
      line.strip! if !block.nil? && BLOCKS[block][:strip]

      # an apply the BEAUTIFIERS and TITLES transformations?
      if block.nil? || (!block.nil? && BLOCKS[block][:apply_inline])
        apply_marks!(format, line)
      end

      # More on line!
      y.yield line
    end

    # There are a close block pending?
    y.yield format::BLOCKS[block][:end] unless block.nil?
  end
end