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('--(.*?)--'),
  link: Regexp.new('\[([^\]\[]*?)\s+([^\s\[\]]*?)\]'),
  image: Regexp.new('\[([^\s\]\[]*?)\]')
}.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



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

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(line, block, format) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/txt2tags.rb', line 122

def apply(line, block, format)
  processed = line

  # an apply the BEAUTIFIERS and TITLES transformations?
  if block.nil? || (!block.nil? && BLOCKS[block][:apply_inline])
    [:BEAUTIFIERS, :TITLES].each do |type|
      type_array = Txt2Tags.const_get(type)
      type_array.keys.each do |rule|
        processed.gsub!(type_array[rule], format.const_get(type)[rule])
      end
    end
  end

  processed
end

#formatsObject

Discover available formats



139
140
141
142
143
144
145
146
# File 'lib/txt2tags.rb', line 139

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



149
150
151
152
# File 'lib/txt2tags.rb', line 149

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



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
# File 'lib/txt2tags.rb', line 65

def output(format)
  block = nil
  ignore_line = false

  # We can this multiples times
  @input.rewind if @input.eof?

  Enumerator.new do |y|
    # 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!

      if block.nil?
        # Searching for a new block...
        block = BLOCKS.find { |b| b[1][:begin_re].match line }

        # The begin of a block!
        unless block.nil?
          block = block[0]

          # 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]
        end
      elsif BLOCKS[block][:end_re].match line
        # We find the end of a block!
        # 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

      # More on line!
      y.yield process_line(line, block, format) unless ignore_line
      ignore_line = false if ignore_line
    end

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

#process_line(line, block, format) ⇒ Object



114
115
116
117
118
119
120
# File 'lib/txt2tags.rb', line 114

def process_line(line, block, format)
  # We can strip spaces from the begin of this line?
  processed = line
  processed.strip! if !block.nil? && BLOCKS[block][:strip]

  apply(processed, block, format)
end