Module: ModelFormatting

Defined in:
lib/model_formatting.rb,
lib/model_formatting/instance_methods.rb

Defined Under Namespace

Modules: Init, InstanceMethods Classes: CodePart, Config, FormattedPart, Part

Constant Summary collapse

CODEBLOCK_RE =
/^(@@@|```)( ([a-z]+)\s*)?$/

Class Method Summary collapse

Class Method Details

.extract_regex(text, *regexes) {|text| ... } ⇒ Object

Yields:

  • (text)


143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/model_formatting.rb', line 143

def self.extract_regex(text, *regexes)
  # Extract pre blocks
  extractions = {}
  regexes.each do |regex|
    text.gsub!(regex) do |match|
      md5 = Digest::MD5.hexdigest(match)
      extractions[md5] ||= []
      extractions[md5] << match
      "{mkd-extraction-#{md5}}"
    end
  end
  yield text
  # In cases where multiple tag names are provided AND the tags mismatch or
  # overlap in non-conforming ways, it's possible for extracted sections to
  # have extractions in them. To keep content from being eaten by the markdown
  # extractor, loop until all of the extractions have been replaced.
  while !extractions.keys.empty?
    # Insert block extractions
    text.gsub!(/\{mkd-extraction-([0-9a-f]{32})\}/) do
      value = extractions[$1].pop
      extractions.delete($1) if extractions[$1].empty?
      value
    end
  end
  text
end

.extract_tag(text, *tag_names) ⇒ Object



174
175
176
177
178
# File 'lib/model_formatting.rb', line 174

def self.extract_tag(text, *tag_names)
  extract_regex text, *tag_names.map { |n| tag_name_to_regex(n) } do |text|
    yield text
  end
end

.gfm(text) ⇒ Object



180
181
182
183
184
185
186
187
188
189
# File 'lib/model_formatting.rb', line 180

def self.gfm(text)
  extract_tag(text, :pre) do |txt| 
    # in very clear cases, let newlines become <br /> tags
    #text.gsub!(/(\A|^$\n)(^\w[^\n]*\n)(^\w[^\n]*$)+/m) do |x|
    #  x.gsub(/^(.+)$/, "\\1  ")
    text.gsub!(/^[\w\<][^\n]*\n+/) do |x|
      x =~ /\n{2}/ ? x : (x.strip!; x << "  \n")
    end
  end
end

.parse_text_parts(format, options, text) ⇒ Object

Parse a string into a given array of [CodeBlcok, FormattedBlock, CodeBlock, FormattedBlock]

@@@ my code block
@@@ end code block

Blah blah formatted block

@@@ my code block
@@@ end code block

Blah blah formatted block


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/model_formatting.rb', line 114

def self.parse_text_parts(format, options, text)
  parts = []
  current_part  = nil
  in_code_block = false
  text.split("\n").each do |line|
    if line.rstrip =~ CODEBLOCK_RE
      line.rstrip!
      if in_code_block
        parts << current_part
        current_part = nil
      else
        if current_part then parts << current_part end
        current_part = CodePart.new(format, $3)
      end
      in_code_block = !in_code_block
    else
      if !in_code_block && current_part.is_a?(CodePart)
        parts << current_part
        current_part = nil
      end
      current_part ||= FormattedPart.new(format, options)
      current_part << line
    end
  end
  parts << current_part if current_part
  parts.compact!
  parts.each { |p| p.compact! }
end

.process(format, text, options = {}) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/model_formatting.rb', line 76

def self.process(format, text, options = {})
  parts  = parse_text_parts(format, options, text)
  string = parts.map { |p| p.formatted_string } * "\n"
  string.gsub! /\r/, ''
  if format == :html
    string.gsub! /code><\/pre>/, "code>\n</pre>" # do this so markdown registers ending </pre>'s as a linebreak
    string = gfm(string)
    string = process_markdown(string)
    string.gsub! /\s+<\/code>/, '</code>' # clear linebreak preceding closing <code>
  end
  if options[:after]
    extract_tag(string, :pre, :code) do |str|
      str.replace options[:after].call(format, str, options)
    end
  end
  if format == :html
    if options[:white_list]
      string = options[:white_list].sanitize(string)
    end
    string = process_tidy(string)
  end
  string.strip!
  format == :html ? "<div>#{string}</div>" : string
end

.tag_name_to_regex(name) ⇒ Object



170
171
172
# File 'lib/model_formatting.rb', line 170

def self.tag_name_to_regex(name)
  %r{<#{name}[^>]*>.*?</#{name}>}m
end