Module: RageRender

Defined in:
lib/ragerender/functions.rb,
lib/ragerender/cflxml.rb,
lib/ragerender/jekyll.rb,
lib/ragerender/to_erb.rb,
lib/ragerender/language.rb,
lib/ragerender/to_liquid.rb,
lib/ragerender/jekyll/blog.rb,
lib/ragerender/jekyll/error.rb,
lib/ragerender/jekyll/comics.rb,
lib/ragerender/jekyll/search.rb,
lib/ragerender/jekyll/archive.rb,
lib/ragerender/jekyll/chapter.rb,
lib/ragerender/jekyll/overview.rb,
lib/ragerender/jekyll/pipettes.rb,
lib/ragerender/jekyll/pagination.rb,
lib/ragerender/jekyll/blog_archive.rb

Overview

Include this module to get ComicFury intrinsic functions available in templates.

Defined Under Namespace

Modules: Language, PaginationGenerator, Pipettes, TemplateFunctions Classes: ArchiveDrop, BlogArchiveDrop, BlogDrop, CFLXMLCommands, ChapterArchiveGenerator, ChapterArchivePaginator, ChapterDrop, ChapterFromComicsGenerator, ChapterFromDirectorySetter, ComicArchivePaginator, ComicDrop, ComicFromImageGenerator, DefaultCoverSetter, DefaultImageSetter, ErrorDrop, FrontpageGenerator, LatestComicGenerator, MainArchivePageGenerator, OverviewDrop, PaginatedBlogArchiveGenerator, PaginatedBlogDrop, PaginatedBlogsGenerator, SearchDrop, WebcomicDrop

Constant Summary collapse

HTML_FILES =
{
  overall: 'overall',
  overview: 'overview',
  viewblog: 'blog-display',
  comic: 'comic-page',
  archive: 'archive',
  blogarchive: 'blog-archive',
  error: 'error-page',
  search: 'search',
}
CSS_FILES =
{
  layoutcss: 'layout'
}
ERB_OPERATORS =
{
  'add' => '+',
  'subtract' => '-',
  'multiply' => '*',
  'divide' => '/',
}
LIQUID_FUNCTIONS =
{
  'add' => proc {|f| [Language::Function.new('plus', f.params)] },
  'subtract' => proc {|f| [Language::Function.new('minus', f.params)] },
  'multiply' => proc {|f| [Language::Function.new('times', f.params)] },
  'divide' => proc {|f| [Language::Function.new('divided_by', f.params)] },
  'removehtmltags' => proc {|f| Language::Function.new('strip_html', f.params) },
}
SPECIAL_COMIC_SLUGS =
%w{frontpage index}
BASE_DIR =
File.join(File.dirname(__FILE__), '..', '..', '..')
COMICS_PER_PAGE =
160
BLOGS_PER_PAGE =
15

Class Method Summary collapse

Class Method Details

.pack(html_srcdir, css_srcdir, dest) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/ragerender/cflxml.rb', line 35

def self.pack html_srcdir, css_srcdir, dest
  layout = REXML::Element.new('layout')

  name = REXML::Element.new('name')
  name.text = "Downloaded ComicFury layout"
  layout.add name

  version = REXML::Element.new('cfxml')
  version.text = '1.2'
  layout.add version

  spage = REXML::Element.new('spage')
  spage.text = '1'
  layout.add spage

  ldata = REXML::Element.new('ldata')
  html_dir = Pathname.new(html_srcdir)
  css_dir = Pathname.new(css_srcdir)

  HTML_FILES.each do |(tag, filename)|
    elem = REXML::Element.new tag.to_s
    elem.text = Base64.strict_encode64 File.read html_dir.join(filename + '.html')
    ldata.add elem
  end

  CSS_FILES.each do |(tag, filename)|
    elem = REXML::Element.new tag.to_s
    elem.text = Base64.strict_encode64 File.read css_dir.join(filename + '.css')
    ldata.add elem
  end
  layout.add ldata

  # ComicFury will only accept backup files that have:
  # - A valid XML declaration using double quotes
  # – A comment as per below
  # – Tab indentation
  doc = REXML::Document.new(nil, prologue_quote: :quote)
  doc.add REXML::XMLDecl.new REXML::XMLDecl::DEFAULT_VERSION, REXML::XMLDecl::DEFAULT_ENCODING
  doc.add REXML::Comment.new 'This is a ComicFury layout backup, use the import layout function to restore this to a webcomic site. You can access this as follows: Go to your Webcomic Management, click "Edit Layout", then in the Box labelled "Useful", click "Restore Layout Backup"'
  doc.add layout

  # Pretty print, but *always* make text nodes take up a single line, no
  # matter how long they are
  formatter = REXML::Formatters::Pretty.new(1)
  formatter.compact = true
  formatter.width = Float::INFINITY

  # Replace the space indentation with tab indentation
  buf = StringIO.new
  formatter.write(doc, buf)
  buf.string.each_line do |line|
    dest << line.gsub(/^ +/) {|sp| "\t" * sp.size }
  end
end

.render_value(value, literals) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/ragerender/to_liquid.rb', line 13

def self.render_value value, literals
  case value
  when String
    case value
    when /^[0-9]+$/
      value
    when /"'/
      literals[value]
    else
      "\"#{value}\""
    end
  when Language::Variable
    if value.path.first == 'l' && value.path.last == 'iteration'
      'forloop.index0'
    elsif value.path.first == 'l' && value.path.last == 'aiteration'
      'forloop.index'
    else
      value.path.join('.')
    end
  when Language::Function
    params = value.params.map {|p| render_value p, literals }
    args = params.drop(1).map {|p| "#{value.name}: #{p}" }.join(' | ')
    [params.first, args.empty? ? value.name : args].join(' | ')
  when nil
    ""
  end
end

.to_erb(document) ⇒ Object



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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
# File 'lib/ragerender/to_erb.rb', line 11

def self.to_erb document
  document.map do |chunk|
    case chunk
    when String
      chunk

    when Language::Variable
      if chunk.path == ['l', 'aiteration']
        '<%= (index+1) %>'
      elsif chunk.path == ['l', 'iteration']
        '<%= index %>'
      else
        "<%= #{chunk.path.join('.')} rescue nil %>"
      end

    when Language::Conditional
      lhs = chunk.lhs.path.join('.')
      rhs = case chunk.rhs
      when Language::Variable
        chunk.rhs.path.join('.')
      when /^[0-9]+$/
        chunk.rhs
      when String
        "\"#{chunk.rhs}\""
      when nil
        ""
      end

      lhs, rhs, operator = case chunk.operator
      when '='
        [lhs, rhs, '==']
      when '%', '!%'
        ["#{lhs} % #{rhs}", 0, if chunk.operator[0] == '!' then '!=' else '==' end]
      when '~', '!~'
        ["#{lhs}.downcase", "#{rhs}.downcase", if chunk.operator[0] == '!' then '!=' else '==' end]
      else
        [lhs, rhs, chunk.operator]
      end

      if chunk.lhs.is_a?(Language::Variable) && chunk.lhs.path.first == "l"
        case chunk.lhs.path.last
        when "is_first", "is_last"
          lhs = "index"
          rhs = {"is_first" => "0", "is_last" => "(forloop.size - 1)"}[chunk.lhs.path.last]
          operator = "=="
        when "is_even", "is_odd"
          lhs = 'index % 2'
          rhs = '0'
          operator = {'is_even' => '==', 'is_odd' => '!='}[chunk.lhs.path.last]
        end
      end

      "<% if #{chunk.reversed ? 'not ' : ''} #{lhs} #{operator} #{rhs} %>"

    when Language::Function
      params = chunk.params.map do |param|
        case param
        when Language::Variable
          param.path.join('.')
        when /^[0-9]+$/
          param
        else
          "\"#{param.gsub(/['"]/) {|c| "\\" + c}}\""
        end
      end

      if ERB_OPERATORS.include? chunk.name
        "<%= #{params.join(ERB_OPERATORS[chunk.name])} %>"
      else
        "<%= #{chunk.name}(#{params.join(', ')}) %>"
      end

    when Language::Loop
      "<% #{chunk.path.join('.')}.each_with_object(#{chunk.path.join('.')}).each_with_index do |(l, forloop), index| %>"

    when Language::Layout
      "<%= #{chunk.name} %>"

    when Language::EndTag
      '<% end %>'
    end
  end
end

.to_liquid(document) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
113
114
115
116
# File 'lib/ragerender/to_liquid.rb', line 41

def self.to_liquid document
  tag_stack = Array.new
  literals = Hash.new {|cache, l| cache[l] = "str" + Digest::MD5.hexdigest(l)}

  chunks = document.map do |chunk|
    case chunk
    when String
      chunk

    when Language::Variable
      "{{ #{render_value chunk, literals} }}"

    when Language::Conditional
      tag_stack << (chunk.reversed ? :endunless : :endif)

      lhs = render_value chunk.lhs, literals
      rhs = render_value chunk.rhs, literals
      operator = chunk.operator

      if chunk.lhs.is_a?(Language::Variable) && chunk.lhs.path.first == "l"
        case chunk.lhs.path.last
        when "is_first", "is_last"
          lhs = "forloop.#{chunk.lhs.path.last[3..]}"
        when "is_even", "is_odd"
          lhs = 'forloop.index0'
          rhs = '2'
          operator = (chunk.lhs.path.last == 'is_even' ? '%' : '!%')
        end
      end

      output = Array.new
      case operator
      when '~', '!~'
        # case insensitive comparison: we need to manually do this
        output << "{% assign lhs = #{lhs} | downcase %}"
        output << "{% assign rhs = #{rhs} | downcase %}"
        lhs = "lhs"
        rhs = "rhs"
        operator = {'~' => '==', '!~' => '!='}[operator]
      when '%', '!%'
        # modulo comparison with zero
        output << "{% assign lhs = #{lhs} | modulo: #{rhs} %}"
        lhs = "lhs"
        rhs = "0"
        operator = {'%' => '==', '!%' => '!='}[operator]
      end

      operator = (operator == '=' ? '==' : operator)
      output << "{% #{chunk.reversed ? 'unless' : 'if'} #{lhs} #{operator} #{rhs} %}"
      output.join

    when Language::Function
      *output, func = LIQUID_FUNCTIONS.fetch(chunk.name, proc{|f| f}).call(chunk)
      output << "{{ #{render_value(func, literals)} }}"
      output.join

    when Language::Loop
      tag_stack << :endfor
      "{% for l in #{chunk.path.join('.')} %}"

    when Language::Layout
      "{{ #{chunk.name} }}"

    when Language::EndTag
      if tag_stack.empty?
        '[/]'
      else
        "{% #{tag_stack.pop.to_s} %}"
      end
    end
  end

  literals.map do |(value, name)|
    "{% capture #{name} %}#{value}{% endcapture %}"
  end + chunks
end

.unpack(src, html_dest, css_dest) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/ragerender/cflxml.rb', line 21

def self.unpack src, html_dest, css_dest
  doc = REXML::Document.new(src).elements
  html_dir = Pathname.new(html_dest)
  css_dir = Pathname.new(css_dest)

  HTML_FILES.each do |(tag, filename)|
    File.write html_dir.join(filename + '.html'), Base64.decode64(doc["/layout/ldata/#{tag.to_s}/text()"].value)
  end

  CSS_FILES.each do |(tag, filename)|
    File.write css_dir.join(filename + '.css'), Base64.decode64(doc["/layout/ldata/#{tag.to_s}/text()"].value)
  end
end