Module: Pasta::Ingredients

Included in:
Recipes::Base
Defined in:
lib/pasta/ingredients.rb,
lib/pasta/ingredients/code.rb,
lib/pasta/ingredients/links.rb,
lib/pasta/ingredients/lists.rb,
lib/pasta/ingredients/anything.rb,
lib/pasta/ingredients/emphasis.rb,
lib/pasta/ingredients/codeblocks.rb,
lib/pasta/ingredients/paragraphs.rb,
lib/pasta/ingredients/blockquotes.rb,
lib/pasta/ingredients/empty_lines.rb,
lib/pasta/ingredients/page_breaks.rb,
lib/pasta/ingredients/atx_headings.rb,
lib/pasta/ingredients/html_entities.rb,
lib/pasta/ingredients/automatic_links.rb,
lib/pasta/ingredients/setext_headings.rb

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

CODE =
/(`+)(.+?)\1/
/([!]*)\[(.+?)\](\((.+?)\)|\s?\[(.*?)\])/
/^ {0,3}\[([\w\s]+?)\]: (.+?)(^\s*[\n\r]|\z)/m
LIST =
/\A\s{0,3}(([-*+]|([0-9]+)\.) .+?)((^\s*[\n\r])|\z)/m
ANYTHING =
/(.+)/
EMPHASIS =
/(?!\\)([*_]{1,2})(?!\s)(.+?)(?!\s)(?!\\)\1/
CODEBLOCK =
/\A( {4,}|\t)(.+?)(^\s{0,3}[\n\r]|\z)/m
PARAGRAPH =
/\A(?![>])(.+?)((^\s*[\n\r])|\z)/m
BLOCKQUOTE =
/\A {0,3}(>.+?)(^\s*[\n\r]|\z)/m
EMPTY_LINE =
/\A\s*[\n\r]+/
PAGE_BREAK =
/\A([*-_]\s?){3,}$/
ATX_HEADING =
/\A(\#{1,6})(.+?)\#*($|\z)/
HTML_ENTITIES =
{
  '&' => '&' 
}
/(?<!\]: )<(.+?):\/\/(.+?)>/
SETEXT_HEADING =
/\A(.+?)[\n\r]([=|-]+)([\n\r]|\z)/

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



4
5
6
# File 'lib/pasta/ingredients.rb', line 4

def self.included(base)
  base.extend ClassMethods
end

Instance Method Details

#anything(text, html) ⇒ Object



6
7
8
9
10
# File 'lib/pasta/ingredients/anything.rb', line 6

def anything(text,html)
  p text
  html << text
  [text,html]
end

#atx_headings(text, html) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/pasta/ingredients/atx_headings.rb', line 6

def atx_headings(text, html)   
  text.sub!(ATX_HEADING) do |match| 
    inner = $2
    if grammars.key? :heading
      grammars[:heading].each do |rule|
        inner, text = send(rule, $2, '')
      end
    end
    html << "<h#{$1.length}>#{inner.strip}</h#{$1.length}>\n" unless $2.nil?
    match = ''
  end
  [text, html]
end


6
7
8
9
10
11
12
# File 'lib/pasta/ingredients/automatic_links.rb', line 6

def automatic_links(text, html)
  text.gsub!(AUTOMATIC_LINKS) do |match|
    url = "#{$1}://#{$2}"
    match = "<a href=\"#{url}\">#{url}</a>"
  end
  [text, html]
end

#blockquotes(text, html) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/pasta/ingredients/blockquotes.rb', line 6

def blockquotes(text, html)
  text.sub!(BLOCKQUOTE) do |match|
    inner_text, inner_html = $1, ''
    inner_text.gsub!(/^>/, '')
    while inner_text != '' do
      if grammars.key? :blockquotes
        grammars[:blockquotes].each do |rule|
          inner_text, inner_html = send(rule, inner_text, inner_html)
        end
      end
    end
    html << "<blockquote>\n#{inner_html.strip}\n</blockquote>\n\n"
    match = ''
  end
  [text, html]   
end


44
45
46
47
48
49
# File 'lib/pasta/ingredients/links.rb', line 44

def clean_link_definitions(text)
  @link_definitions.each do |key,val|
    text.gsub!(/^ {0,3}\[#{key}\]: (.+?)(^\s*[\n\r]|\z)/mi, '')
  end
  text
end

#code(text, html) ⇒ Object



6
7
8
9
10
11
12
13
# File 'lib/pasta/ingredients/code.rb', line 6

def code(text, html)
  text.gsub!(CODE) do |match|
    require 'cgi'
    html = "<code>#{CGI::escapeHTML $2}</code>"
    match = html
  end
  [text, html]
end

#codeblocks(text, html) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/pasta/ingredients/codeblocks.rb', line 6

def codeblocks(text, html)     
  text.sub!(CODEBLOCK) do |match|
    require 'cgi'
    # clean the leading whitespace from the block and escape html
    new_text = $2
    new_text.gsub!(/^#{$1}/, '')
    new_text = CGI::escapeHTML new_text
    html << "<pre><code>#{new_text}</code></pre>\n\n"
    match = ''
  end
  [text, html]
end

#emphasis(text, html) ⇒ Object



6
7
8
9
10
11
12
# File 'lib/pasta/ingredients/emphasis.rb', line 6

def emphasis(text, html)
  html = text.gsub(EMPHASIS) do |match|
    tag = $1.length == 1 ? 'em' : 'strong'
    match = "<#{tag}>#{$2}</#{tag}>"
  end
  [text, html]
end

#empty_lines(text, html) ⇒ Object



6
7
8
9
10
11
# File 'lib/pasta/ingredients/empty_lines.rb', line 6

def empty_lines(text, html)
  text.sub!(EMPTY_LINE) do |match|
    match = ''
  end
  [text, html]
end


37
38
39
40
41
42
# File 'lib/pasta/ingredients/links.rb', line 37

def find_link_definitions(text)
  @link_definitions = {}
  text.gsub(LINK_DEFINITION) do |match|
    @link_definitions[$1.downcase] = {target: $2, used: false}
  end
end

#grammars(name = nil) ⇒ Object

Public. Returns the grammars of a recipe

name - the name of a grammar rule as a Symbol

Example

grammars(:html)
# => <Proc:>

Returns a Proc containing grammar rules



17
18
19
# File 'lib/pasta/ingredients.rb', line 17

def grammars(name=nil)
  return name.nil? ? self.class.grammars : self.class.grammars[name]
end

#html_entities(text, html) ⇒ Object



8
9
10
11
12
13
14
15
# File 'lib/pasta/ingredients/html_entities.rb', line 8

def html_entities(text, html)
  HTML_ENTITIES.each do |entity, transformation|
    html = text.gsub(/[#{entity}]/) do |match|
      match = transformation
    end
  end
  [text, html]
end


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/pasta/ingredients/links.rb', line 10

def links(text, html)
  find_link_definitions(text)
  
  text.gsub!(LINKS) do |match|
    link_text, target = $2, ''
    if $4
      # It's an inline link
      target = $4
    else
      # It's a reference link
      id = $5 == '' ? $2.downcase : $5.downcase
      break unless @link_definitions && @link_definitions.key?(id)
      target = @link_definitions[id][:target]
    end
    # format image or link
    url, title = parse_link target
    if $1 == '!'
      match = "<img src=\"#{url}\" alt=\"#{link_text}\"#{title} />"
    else
      match = "<a href=\"#{url}\"#{title}>#{link_text}</a>"
    end
  end
  
  text = clean_link_definitions(text)
  [text, html]
end

#list_items(text) ⇒ Object



22
23
24
25
26
27
28
29
# File 'lib/pasta/ingredients/lists.rb', line 22

def list_items(text)
  html = ''
  text.gsub(/^([-*+]|\d+\.) (.+?)$(?=([\n\r]([*+-]|(\d+\.))|\z))/m) do |match| 
    html << "<li>#{$2.gsub(/\n\s+/, ' ').strip}</li>\n"
    match = ''
  end
  html
end

#lists(text, html) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/pasta/ingredients/lists.rb', line 6

def lists(text, html)
  text.sub!(LIST) do |match|
    inner_text, inner_html, list_type = $1, '', 'ul'
    
    # determine the list_type
    list_type = 'ol' unless %w{- * +}.include? $1.strip[0]
    
    # extract list items
    inner_html = list_items(inner_text)
    
    html << "<#{list_type}>\n#{inner_html}</#{list_type}>\n\n"
    match = ''
  end
  [text, html]
end

#page_breaks(text, html) ⇒ Object



6
7
8
9
10
11
12
# File 'lib/pasta/ingredients/page_breaks.rb', line 6

def page_breaks(text, html)
  text.sub!(PAGE_BREAK) do |match|
    html << "<hr />"
    match = ''
  end
  [text, html]
end

#paragraphs(text, html) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/pasta/ingredients/paragraphs.rb', line 6

def paragraphs(text, html)
  text.sub!(PARAGRAPH) do |match| 

    inner_text, inner_html = $1, ''
    inner_text.gsub!(/[ ]{2,}[\n\r]/, "<br />\n")      
    inner_text.strip!

    if grammars.key? :paragraphs
      grammars[:paragraphs].each do |rule|
        inner_text, inner_html = send(rule, inner_text, '')
      end
      inner_text = inner_html unless inner_html == ''
    end

    html << "<p>#{inner_text}</p>\n\n" unless inner_text == ''
    match = ''
  end
  [text, html]  
end


51
52
53
54
55
56
# File 'lib/pasta/ingredients/links.rb', line 51

def parse_link(text)
  target = text.split(' ')
  url = target[0].gsub(/[<>]/, '')
  title = " title=#{target[1..-1].join(' ').strip}" if target.length > 1
  [url, title]
end

#setext_headings(text, html) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/pasta/ingredients/setext_headings.rb', line 6

def setext_headings(text, html)    
  text.sub!(SETEXT_HEADING) do |match| 
    if grammars.key? :heading
      grammars[:heading].each do |rule|
        inner = send(rule, $1, '')
      end
    end
    level = ($2[0] == '=') ? 1 : 2
    html << "<h#{level}>#{$1}</h#{level}>\n" unless $1.nil?
    match = ''
  end    
  [text, html]
end