Module: ClayText

Defined in:
lib/clayoven/claytext.rb

Defined Under Namespace

Classes: Paragraph

Constant Summary collapse

PARAGRAPH_TYPES =

These are the values that Paragraph.type can take

[:plain, :emailquote, :codeblock, :header, :footer]
HTMLESCAPE_RULES =
{
  "&" => "&",
  "\"" => """,
  "'" => "'",
  "<" => "&lt;",
  ">" => "&gt;"
}
PARAGRAPH_RULES =

Key is used to match a paragraph, and value is the lambda that’ll act on it.

{

  # If all the lines in a paragraph, begin with "> ", the
  # paragraph is marked as an :emailquote.
  Proc.new { |line| line.start_with? "&gt; " } => lambda { |paragraph|
    paragraph.type = :emailquote },

  # If all the lines in a paragraph, begin with "   ", the paragraph is
  # marked as an :coeblock
  Proc.new { |line| line.start_with? "    " } => lambda { |paragraph|
    paragraph.type = :codeblock },

  # If all the lines in a paragraph, begin with " ", the paragraph
  # is marked as :footer.  Also, a regex substitution runs on each
  # line turning every link like http://a-url-over-67-characters
  # to <a href="http://google.com">64-characters-of-the-li...</a>
  Proc.new { |line| /^\[\d+\]: / =~ line } => lambda do |paragraph|
    paragraph.type = :footer
    paragraph.content.gsub!(%r{^(\[\d+\]:) (.*://(.*))}) do
      "#{$1} <a href=\"#{$2}\">#{$3[0, 64]}#{%{...} if $3.length > 67}</a>"
    end
  end
}

Class Method Summary collapse

Class Method Details

.process!(body) ⇒ Object

Takes a body of claytext, breaks it up into paragraphs, and applies various rules on it.

Returns a list of Paragraphs



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
# File 'lib/clayoven/claytext.rb', line 71

def self.process!(body)

  # First, htmlescape the body text
  body.gsub!(/[&"'<>]/, ClayText::HTMLESCAPE_RULES)

  # Split the body into Paragraphs
  paragraphs = []
  body.split("\n\n").each do |content|
    paragraphs << Paragraph.new(content)
  end

  # Special matching for the first paragraph.  This paragraph will
  # be marked header:
  #
  # (This is a really long first paragraph blah-blah-blah-blah-blah
  # that spans to two lines)
  paragraphs[0].first = true
  if paragraphs[0].content.start_with? "(" and
      paragraphs[0].content.end_with? ")"
    paragraphs[0].type = :header
  end

  # Apply the PARAGRAPH_RULES on all the paragraphs
  paragraphs.each do |paragraph|
    ClayText::PARAGRAPH_RULES.each do |proc_match, lambda_cb|
      if paragraph.content.lines.all? &proc_match
        lambda_cb.call paragraph
      end
    end
  end

  # body is the useless version.  If someone is too lazy to use all
  # the paragraphs individually in their template, they can just use
  # this.
  body = paragraphs.map(&:content).join("\n\n")
  
  paragraphs
end