module Clayoven::Claytext
The claytext paragraph processor
The actual transformation rules are the constants in Clayoven::Claytext::Transforms
.
Constants
- HTMLESCAPE_RULES
We only HTML escape very few things, for simplicity
Public Class Methods
fenced_transforms!(paragraphs)
click to toggle source
Perform the transforms in Clayoven::Claytext::Transforms::FENCED on Paragraph
entries in-place
# File lib/clayoven/claytext.rb, line 56 def self.fenced_transforms!(paragraphs) # For MathJax, exercises, codeblocks, and other fenced content Transforms::FENCED.each do |delims, lambda_cb| blocks = merge_fenced! paragraphs, delims[0], delims[1] blocks.each { |blk| lambda_cb.call blk.block, blk.fc, blk.lc } end end
inline_transforms!(paragraphs)
click to toggle source
Insert <{mark, strong, em, a, br}> into the paragraph after escaping HTML
# File lib/clayoven/claytext.rb, line 86 def self.inline_transforms!(paragraphs) paragraphs.each do |p| p.replace p .gsub(/[<>&]/, HTMLESCAPE_RULES) .gsub(/`([^`]+)`/, '<mark>\1</mark>') .gsub(/!\{([^\}]+)\}/, '<strong>\1</strong>') .gsub(/!_\{([^\}]+)\}/, '<em>\1</em>') .gsub(/\[([^\[\]]+)\]\(([^)]+)\)/, '<a href="\2">\1</a>') .gsub("\u{23CE}", "<br>") end end
line_transforms!(paragraphs)
click to toggle source
Perform the transforms in Clayoven::Claytext::Transforms::LINE on Paragraph
entries in-place
# File lib/clayoven/claytext.rb, line 65 def self.line_transforms!(paragraphs) # Preprocess lines ending with ' \\' and insert a special unicode char for conversion to <br> paragraphs.each { |p| p.gsub! " \\\\\n", "\u{23CE}" } # Now do the all the line transforms, never operating on a line more than once Transforms::LINE.each do |regex, lambda_cb| paragraphs .filter { |p| p.type == :plain and p.split("\n").all? regex } .each do |p| # Strip the regex before calling the lambda match = p.match regex p.gsub! regex, "" lambda_cb.call p, match end end end
merge_fenced!(paragraphs, fregex, lregex)
click to toggle source
Merge Paragraph
entries with fences marked by the start regex fregex and end regex lregex
# File lib/clayoven/claytext.rb, line 30 def self.merge_fenced!(paragraphs, fregex, lregex) mb = Struct.new(:block, :fc, :lc) matched_blocks = [] paragraphs.each_with_index do |p, pidx| pmatch = fregex.match p next unless pmatch paragraphs[pidx..].each_with_index do |q, idx| qmatch = lregex.match q next unless qmatch # Replace paragraph p with all the paragraphs from pidx to pidx + idx, # after stripping out the delims. # The final result, the "fenced paragraph" sits at pidx. p.replace(Util.slice_strip_fences!(paragraphs, pidx, idx + 1)) matched_blocks << mb.new(p, pmatch, qmatch) # The final result is at pidx; throw out all the idx paragraphs, starting at pidx + 1 paragraphs.slice! pidx + 1, idx break end end matched_blocks end
process(body)
click to toggle source
Takes a body of claytext (String
), breaks it up into paragraphs, and applies various rules on it.
Returns an Array
of Paragraph
# File lib/clayoven/claytext.rb, line 102 def self.process(body) # Split the body into Paragraphs paragraphs = body.split("\n\n").map { |p| Paragraph.new p.rstrip } # First, do the fenced transforms on all paragraphs fenced_transforms! paragraphs # Then, do the line transforms on paragraphs untouched by the fenced transforms line_transforms! (paragraphs.filter { |p| p.type == :plain }) # Finally, do inline transforms on paragraphs untouched by the fenced transforms inline_transforms! ( paragraphs.reject { |p| %i[codeblock images mathjax].count(p.type).positive? } ) # Result: paragraphs paragraphs end