Class: Booky::Layout::Base::Code

Inherits:
Element
  • Object
show all
Includes:
Helpers
Defined in:
lib/booky/layout/base/code.rb

Defined Under Namespace

Classes: LanguageMissing

Constant Summary collapse

OPTIONS =
{
  :align => :left,
  :size => 12
}
COLORS =
{
  :default                => 'FFFFFF',
  :background             => '2B2B2B',
  :background_2           => '383838',
  
  :line_number => {
    :number               => '9C9C9C',
    :background           => 'E2E2E2'
  },
  
  :comment                => 'BC9458',
  :keyword                => 'EC922E',
  :constant               => 'FFFFFF',
  :operator               => 'FFFFFF',
  :ident                  => 'FFC66D',
  :instance_variable      => 'D0D0FF',
  :integer                => 'A5C261',
  :float                  => 'A5C261',
  :string                 => 'A5C261',
  :delimiter              => 'A5C261',
  :content                => 'A5C261',
  :inline_delimiter       => '519F50'
}

Instance Attribute Summary

Attributes inherited from Element

#ast, #document, #index, #options

Instance Method Summary collapse

Methods included from Helpers

#add_to_toc, #is_first_rendering?, #update_levels

Methods inherited from Element

#initialize, #method_missing, #next_option, #previous_option

Constructor Details

This class inherits a constructor from Booky::Layout::Element

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Booky::Layout::Element

Instance Method Details

#convert_entities(token) ⇒ Object



70
71
72
73
74
75
76
77
78
# File 'lib/booky/layout/base/code.rb', line 70

def convert_entities(token)
  [
    ['>', '>'],
    ['<', '&lt;']
  ].each do |entity|
    token.gsub! entity.first, entity.last
  end
  token
end

#create_headingObject



61
62
63
64
65
66
67
68
# File 'lib/booky/layout/base/code.rb', line 61

def create_heading
  return unless @options[:title]
  
  fill_color Booky::Layout::Base::COLORS[1]
  text @options[:title], OPTIONS
  fill_color Booky::Layout::Base::COLORS[0]
  move_down 0.2.cm
end

#make_highlightingObject



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/booky/layout/base/code.rb', line 94

def make_highlighting
  return if @options[:language] == 'text'
  @stack = []
  @source = ""
  until @tokens.empty? do
    token, type = @tokens.shift(2)
    color = COLORS.key?(type) ? COLORS[type] : COLORS[:default]
    
    # Keep track of current stack level
    @stack << type    if token == :begin_group
    @stack.pop        if token == :end_group
    
    @source << "</color>" if type == :content
    
    case token
      when :begin_group then  @source << "<color rgb='#{color}'>"
      when :end_group   then  @source << "</color>"
      else
        token = convert_entities(token)
        if @stack.empty?
          @source << (type == :space ? token : "<color rgb='#{color}'>#{token}</color>")
        else
          group_color = COLORS.key?(type) ? COLORS[type] : false
          @source << (group_color ? token.split("\n").map{ |token| "<color rgb='#{group_color}'>#{token}</color>" }.join("\n") : token)
        end
    end
  end
  
  # Keep text indentation at the beginning of the lines by replacing the " " with unicode NBSPs
  @source.gsub! " ", "\u00a0"
end

#make_tableObject



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/booky/layout/base/code.rb', line 126

def make_table
  @line = 0
  @lines = @source.split("\n").map do |line|
    @line += 1
    line = "\u00a0" if line.length == 28
    line    = make_cell(
      :content  => line,
      :padding  => [2, 2, 2, 7]
    )
    number  = make_cell(
      :content          => "<color rgb='#{COLORS[:line_number][:number]}'>#{@line}</color>", 
      :align            => :right,
      :background_color => COLORS[:line_number][:background],
      :padding          => [2, 7, 2, 2]
    )
    [number, line]
  end
  
  font 'Monaco' do
    table(@lines,
      :header => false,
      :width  => bounds.width,
      :column_widths => { 0 => 1.cm },
      :row_colors => [COLORS[:background], COLORS[:background]],
      :cell_style => { 
        :inline_format  => true,
        :borders        => [],
        :border_widths  => [0] * 4,
        :border_color   => COLORS[:background],
        :size           => 8
      }
    )
  end
  move_down 1.cm
end

#make_text_tokensObject



85
86
87
88
89
90
91
92
# File 'lib/booky/layout/base/code.rb', line 85

def make_text_tokens
  @source = @options[:text].lines.collect do |line|
    line.gsub! "\n", ""
    "<color rgb='#{COLORS[:default]}'>#{convert_entities(line)}</color>\n"
  end
  @source.pop
  @source = @source.join
end

#make_tokensObject



80
81
82
83
# File 'lib/booky/layout/base/code.rb', line 80

def make_tokens
  make_text_tokens and return if @options[:language] == 'text'
  @tokens = CodeRay.scan(@options[:text], @options[:language].to_sym).tokens
end

#start_new_page_if_neededObject



162
163
164
# File 'lib/booky/layout/base/code.rb', line 162

def start_new_page_if_needed
  start_new_page if cursor < (bounds.bottom + 4.cm)
end

#to_prawnObject

Raises:



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/booky/layout/base/code.rb', line 166

def to_prawn
  raise LanguageMissing.new(@options[:text]) if @options[:language].nil?
  
  start_new_page_if_needed
  
  Booky::Layout.config.patch_table_cell = true
  
  make_tokens
  make_highlighting
  
  create_heading
  make_table
  
  Booky::Layout.config.patch_table_cell = false
end