module Asciidoctor::Prawn::Extensions

Constants

FontAwesomeIconSets
FontStyleToSet
IconSetPrefixes
IconSets
InitialPageContent
LineMetrics
  • :height is the height of a line

  • :leading is spacing between adjacent lines

  • :padding_top is half line spacing, plus any line_gap in the font

  • :padding_bottom is half line spacing

  • :final_gap determines whether a gap is added below the last line

PlaceholderChar

NOTE must use a visible char for placeholder or else Prawn won't reserve space for the fragment

Public Instance Methods

advance_page(opts = {}) click to toggle source

This method is a smarter version of start_new_page. It calls start_new_page if the current page is the last page of the document. Otherwise, it simply advances to the next existing page.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 835
def advance_page opts = {}
  last_page? ? (start_new_page opts) : (go_to_page page_number + 1)
end
at_page_top?() click to toggle source

Returns whether the cursor is at the top of the page (i.e., margin box).

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 178
def at_page_top?
  @y == @margin_box.absolute_top
end
bounds_margin_left() click to toggle source

Returns the total left margin (to the page edge) for the current bounds.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 144
def bounds_margin_left
  bounds.absolute_left
end
bounds_margin_right() click to toggle source

Returns the total right margin (to the page edge) for the current bounds.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 150
def bounds_margin_right
  page.dimensions[2] - bounds.absolute_right
end
calc_line_metrics(line_height = 1, font = self.font, font_size = self.font_size) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 349
def calc_line_metrics line_height = 1, font = self.font, font_size = self.font_size
  line_height_length = line_height * font_size
  leading = line_height_length - font_size
  half_leading = leading / 2
  padding_top = half_leading + font.line_gap
  padding_bottom = half_leading
  LineMetrics.new line_height_length, leading, padding_top, padding_bottom, false
end
catalog() click to toggle source

Retrieves the catalog reference data for the PDF.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 39
def catalog
  state.store.root
end
delete_page() click to toggle source

Deletes the current page and move the cursor to the previous page.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 754
def delete_page
  pg = page_number
  pdf_store = state.store
  pdf_objs = pdf_store.instance_variable_get :@objects
  pdf_ids = pdf_store.instance_variable_get :@identifiers
  page_id = pdf_store.object_id_for_page pg
  content_id = page.content.identifier
  [page_id, content_id].each do |key|
    pdf_objs.delete key
    pdf_ids.delete key
  end
  pdf_store.pages.data[:Kids].pop
  pdf_store.pages.data[:Count] -= 1
  state.pages.pop
  if pg > 1
    go_to_page pg - 1
  else
    @page_number = 0
    state.page = nil
  end
end
dest_top(page_num = nil) click to toggle source

Generates a destination object that resolves to the top of the page specified by the page_num parameter or the current page if no page number is provided. The destination preserves the user's zoom level unlike the destinations generated by the outline builder.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 195
def dest_top page_num = nil
  dest_xyz 0, page_height, nil, (page_num ? state.pages[page_num - 1] : page)
end
draw_indented_formatted_line(string, opts) click to toggle source

NOTE override built-in draw_indented_formatted_line to set first_line flag

Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 411
def draw_indented_formatted_line string, opts
  super string, (opts.merge first_line: true)
end
dry_run(&block) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 883
def dry_run &block
  scratch = get_scratch_document
  # QUESTION should we use scratch.advance_page instead?
  scratch.start_new_page
  start_page_number = scratch.page_number
  start_y = scratch.y
  scratch_bounds = scratch.bounds
  original_x = scratch_bounds.absolute_left
  original_width = scratch_bounds.width
  scratch_bounds.instance_variable_set :@x, bounds.absolute_left
  scratch_bounds.instance_variable_set :@width, bounds.width
  scratch.font font_family, style: font_style, size: font_size do
    scratch.instance_exec(&block)
  end
  # NOTE don't count excess if cursor exceeds writable area (due to padding)
  full_page_height = scratch.effective_page_height
  partial_page_height = [full_page_height, start_y - scratch.y].min
  scratch_bounds.instance_variable_set :@x, original_x
  scratch_bounds.instance_variable_set :@width, original_width
  whole_pages = scratch.page_number - start_page_number
  [(whole_pages * full_page_height + partial_page_height), whole_pages, partial_page_height]
end
effective_page_height() click to toggle source

Returns the effective (writable) height of the page

If inside a fixed-height bounding box, returns width of box.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 75
def effective_page_height
  reference_bounds.height
end
effective_page_width() click to toggle source

Returns the effective (writable) width of the page

If inside a bounding box, returns width of box.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 61
def effective_page_width
  reference_bounds.width
end
fill_absolute_bounds(f_color = fill_color) click to toggle source

Fills the absolute bounding box with the specified fill color. Before returning from this method, the original fill color on the document is restored.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 637
def fill_absolute_bounds f_color = fill_color
  canvas { fill_bounds f_color }
end
fill_and_stroke_bounds(f_color = fill_color, s_color = stroke_color, options = {}) click to toggle source

Fills the current bounds using the specified fill color and strokes the bounds using the specified stroke color. Sets the line with if specified in the options. Before returning from this method, the original fill color, stroke color and line width on the document are restored.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 646
def fill_and_stroke_bounds f_color = fill_color, s_color = stroke_color, options = {}
  no_fill = !f_color || f_color == 'transparent'
  no_stroke = !s_color || s_color == 'transparent' || options[:line_width] == 0
  return if no_fill && no_stroke
  save_graphics_state do
    radius = options[:radius] || 0

    # fill
    unless no_fill
      fill_color f_color
      fill_rounded_rectangle bounds.top_left, bounds.width, bounds.height, radius
    end

    # stroke
    unless no_stroke
      stroke_color s_color
      line_width(options[:line_width] || 0.5)
      # FIXME: think about best way to indicate dashed borders
      #if options.has_key? :dash_width
      #  dash options[:dash_width], space: options[:dash_space] || 1
      #end
      stroke_rounded_rectangle bounds.top_left, bounds.width, bounds.height, radius
      #undash if options.has_key? :dash_width
    end
  end
end
fill_bounds(f_color = fill_color) click to toggle source

Fills the current bounding box with the specified fill color. Before returning from this method, the original fill color on the document is restored.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 625
def fill_bounds f_color = fill_color
  if f_color && f_color != 'transparent'
    prev_fill_color = fill_color
    fill_color f_color
    fill_rectangle bounds.top_left, bounds.width, bounds.height
    fill_color prev_fill_color
  end
end
fill_formatted_text_box(text, opts) click to toggle source

NOTE override built-in fill_formatted_text_box to insert leading before second line when :first_line is true

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 394
def fill_formatted_text_box text, opts
  merge_text_box_positioning_options opts
  box = ::Prawn::Text::Formatted::Box.new text, opts
  remaining_text = box.render
  @no_text_printed = box.nothing_printed?
  @all_text_printed = box.everything_printed?

  if @final_gap || (opts[:first_line] && !(@no_text_printed || @all_text_printed))
    self.y -= box.height + box.line_gap + box.leading
  else
    self.y -= box.height
  end

  remaining_text
end
flow_bounding_box(left = 0, opts = {}) { || ... } click to toggle source

A flowing version of the bounding_box. If the content runs to another page, the cursor starts at the top of the page instead of the original cursor position. Similar to span, except you can specify an absolute left position and pass additional options through to bounding_box.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 608
def flow_bounding_box left = 0, opts = {}
  original_y = y
  # QUESTION should preserving original_x be an option?
  original_x = bounds.absolute_left - margin_box.absolute_left
  canvas do
    bounding_box [margin_box.absolute_left + original_x + left, margin_box.absolute_top], opts do
      self.y = original_y
      yield
    end
  end
end
font(name = nil, options = {}) click to toggle source

Enhances the built-in font method to allow the font size to be specified as the second option and to lazily load font-based icons.

Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 221
def font name = nil, options = {}
  if name
    options = { size: options } if ::Numeric === options
    if IconSets.include? name
      ::Prawn::Icon::FontData.load self, name
      options = options.reject {|k| k == :style } if options.key? :style
    end
  end
  super
end
font_family() click to toggle source

Retrieves the current font name (i.e., family).

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 234
def font_family
  font.options[:family]
end
Also aliased as: font_name
font_info() click to toggle source

Retrieves the current font info (family, style, size) as a Hash

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 242
def font_info
  { family: font.options[:family], style: (font.options[:style] || :normal), size: @font_size }
end
font_name()
Alias for: font_family
font_size(points = nil) click to toggle source

Applies points as a scale factor of the current font if the value provided is less than or equal to 1 or it's a string (e.g., 1.1em), then delegates to the super implementation to carry out the built-in functionality.

Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 268
def font_size points = nil
  return @font_size unless points
  if points == 1
    super @font_size
  elsif String === points
    if points.end_with? 'rem'
      super @root_font_size * points.to_f
    elsif points.end_with? 'em'
      super @font_size * points.to_f
    elsif points.end_with? '%'
      super @font_size * (points.to_f / 100)
    else
      super points.to_f
    end
  # FIXME: HACK assume em value
  elsif points < 1
    super @font_size * points
  else
    super points
  end
end
font_style(style = nil) { || ... } click to toggle source

Sets the font style for the scope of the block to which this method yields. If the style is nil and no block is given, return the current font style.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 250
def font_style style = nil
  if block_given?
    font font.options[:family], style: style do
      yield
    end
  elsif style
    font font.options[:family], style: style
  else
    font.options[:style] || :normal
  end
end
font_styles(style = font_style) click to toggle source

Retreives the collection of font styles from the given font style key, which defaults to the current font style.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 303
def font_styles style = font_style
  FontStyleToSet[style].dup
end
fragment_font(fragment) { || ... } click to toggle source

Apply the font settings (family, size, styles and character spacing) from the fragment to the document, then yield to the block.

The original font settings are restored before this method returns.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 312
def fragment_font fragment
  f_info = font_info
  f_family = fragment[:font] || f_info[:family]
  f_size = fragment[:size] || f_info[:size]
  if (f_styles = fragment[:styles])
    f_style = resolve_font_style f_styles
  else
    f_style = :normal
  end

  if (c_spacing = fragment[:character_spacing])
    character_spacing c_spacing do
      font f_family, size: f_size, style: f_style do
        yield
      end
    end
  else
    font f_family, size: f_size, style: f_style do
      yield
    end
  end
end
generate_margin_box() click to toggle source

workaround for github.com/prawnpdf/prawn/issues/1121

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 80
def generate_margin_box
  page_w, page_h = (page = state.page).dimensions.slice 2, 2
  page_m = page.margins
  prev_margin_box, @margin_box = @margin_box, (::Prawn::Document::BoundingBox.new self, nil, [page_m[:left], page_h - page_m[:top]], width: page_w - page_m[:left] - page_m[:right], height: page_h - page_m[:top] - page_m[:bottom])

  # update bounding box if not flowing from the previous page
  unless @bounding_box&.parent
    prev_margin_box = @bounding_box
    @bounding_box = @margin_box
  end

  # maintains indentation settings across page breaks
  if prev_margin_box
    @margin_box.add_left_padding prev_margin_box.total_left_padding
    @margin_box.add_right_padding prev_margin_box.total_right_padding
  end

  nil
end
get_scratch_document() click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 858
def get_scratch_document
  # marshal if not using transaction feature
  #Marshal.load Marshal.dump @prototype

  # use cached instance, tests show it's faster
  #@prototype ||= ::Prawn::Document.new
  @scratch ||= if defined? @prototype # rubocop:disable Naming/MemoizedInstanceVariableName
                 scratch = Marshal.load Marshal.dump @prototype
                 scratch.instance_variable_set :@prototype, @prototype
                 scratch.instance_variable_set :@tmp_files, @tmp_files
                 # TODO: set scratch number on scratch document
                 scratch
               else
                 logger.warn 'no scratch prototype available; instantiating fresh scratch document'
                 ::Prawn::Document.new
               end
end
group_if(verdict) { || ... } click to toggle source

Conditional group operation

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 849
def group_if verdict
  if verdict
    state.optimize_objects = false # optimize_objects breaks group
    group { yield }
  else
    yield
  end
end
hyphenate_text(text, hyphenator) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 479
def hyphenate_text text, hyphenator
  hyphenate_words_pcdata text, hyphenator
end
icon_font_data(family) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 341
def icon_font_data family
  ::Prawn::Icon::FontData.load self, family
end
image_page(file, options = {}) click to toggle source

Create a new page for the specified image. If the canvas option is true, the image is positioned relative to the boundaries of the page.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 805
def image_page file, options = {}
  start_new_page_discretely
  image_page_number = page_number
  if options.delete :canvas
    canvas { image file, ({ position: :center, vposition: :center }.merge options) }
  else
    image file, (options.merge position: :center, vposition: :center, fit: [bounds.width, bounds.height])
  end
  # NOTE advance to newly created page just in case the image function threw off the cursor
  go_to_page image_page_number
  nil
end
import_page(file, opts = {}) { || ... } click to toggle source

Import the specified page into the current document.

By default, advance to the next page afterwards, creating it if necessary. This behavior can be disabled by passing the option `advance: false`. However, due to how page creation works in Prawn, understand that advancing to the next page is necessary to prevent the size & layout of the imported page from affecting a newly created page.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 783
def import_page file, opts = {}
  prev_page_layout = page.layout
  prev_page_size = page.size
  state.compress = false if state.compress # can't use compression if using template
  prev_text_rendering_mode = (defined? @text_rendering_mode) ? @text_rendering_mode : nil
  delete_page if opts[:replace]
  # NOTE use functionality provided by prawn-templates
  start_new_page_discretely template: file, template_page: opts[:page]
  # prawn-templates sets text_rendering_mode to :unknown, which breaks running content; revert
  @text_rendering_mode = prev_text_rendering_mode
  yield if block_given?
  if opts.fetch :advance, true
    # NOTE set page size & layout explicitly in case imported page differs
    # I'm not sure it's right to start a new page here, but unfortunately there's no other
    # way atm to prevent the size & layout of the imported page from affecting subsequent pages
    advance_page size: prev_page_size, layout: prev_page_layout
  end
  nil
end
inflate_indent(value) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 571
def inflate_indent value
  (::Array === value ? (value.slice 0, 2) : (::Array.new 2, value)).map(&:to_f)
end
inflate_padding(padding) click to toggle source

TODO: memoize the result

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 576
def inflate_padding padding
  padding = (Array padding || 0).slice 0, 4
  case padding.size
  when 1
    [padding[0], padding[0], padding[0], padding[0]]
  when 2
    [padding[0], padding[1], padding[0], padding[1]]
  when 3
    [padding[0], padding[1], padding[2], padding[1]]
  else
    padding
  end
end
is_scratch?()
Alias for: scratch?
keep_together(&block) click to toggle source

Attempt to keep the objects generated in the block on the same page

TODO: short-circuit nested usage

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 914
def keep_together &block
  available_space = cursor
  total_height, = dry_run(&block)
  # NOTE technically, if we're at the page top, we don't even need to do the
  # dry run, except several uses of this method rely on the calculated height
  if total_height > available_space && !at_page_top? && total_height <= effective_page_height
    advance_page
    started_new_page = true
  else
    started_new_page = false
  end

  # HACK: yield doesn't work here on JRuby (at least not when called from AsciidoctorJ)
  #yield remainder, started_new_page
  instance_exec(total_height, started_new_page, &block)
end
keep_together_if(verdict) { || ... } click to toggle source

Attempt to keep the objects generated in the block on the same page if the verdict parameter is true.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 934
def keep_together_if verdict, &block
  if verdict
    keep_together(&block)
  else
    yield
  end
end
last_page?() click to toggle source

Returns whether the current page is the last page in the document.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 184
def last_page?
  page_number == page_count
end
left_margin()

deprecated

Alias for: page_margin_left
min_version() click to toggle source

Retrieves the compatiblity version of the PDF.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 45
def min_version
  state.version
end
move_down(n) click to toggle source

Short-circuits the call to the built-in move_down operation when n is 0.

Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 501
def move_down n
  super unless n == 0
end
move_text_position(h;) click to toggle source

Override built-in move_text_position method to prevent Prawn from advancing to next page if image doesn't fit before rendering image.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 496
def move_text_position h; end
move_up(n) click to toggle source

Short-circuits the call to the built-in move_up operation when n is 0.

Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 488
def move_up n
  super unless n == 0
end
pad(top, bottom = nil) { || ... } click to toggle source

Overrides the built-in pad operation to allow for asymmetric paddings.

Example:

pad 20, 10 do
  text 'A paragraph with twice as much top padding as bottom padding.'
end
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 515
def pad top, bottom = nil
  move_down top
  yield
  move_down(bottom || top)
end
pad_box(padding) { || ... } click to toggle source

Combines the built-in pad and indent operations into a single method.

Padding may be specified as an array of four values, or as a single value. The single value is used as the padding around all four sides of the box.

If padding is nil, this method simply yields to the block and returns.

Example:

pad_box 20 do
  text 'A paragraph inside a blox with even padding on all sides.'
end

pad_box [10, 10, 10, 20] do
  text 'An indented paragraph inside a box with equal padding on all sides.'
end
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 538
def pad_box padding
  if padding
    # TODO: implement shorthand combinations like in CSS
    p_top, p_right, p_bottom, p_left = ::Array === padding ? padding : (::Array.new 4, padding)
    begin
      # logic is intentionally inlined
      move_down p_top
      bounds.add_left_padding p_left
      bounds.add_right_padding p_right
      yield
      # NOTE support negative bottom padding for use with quote block
      if p_bottom < 0
        # QUESTION should we return to previous page if top of page is reached?
        p_bottom < cursor - reference_bounds.top ? (move_cursor_to reference_bounds.top) : (move_down p_bottom)
      else
        p_bottom < cursor ? (move_down p_bottom) : reference_bounds.move_past_bottom
      end
    ensure
      bounds.subtract_left_padding p_left
      bounds.subtract_right_padding p_right
    end
  else
    yield
  end

  # alternate, delegated logic
  #pad padding[0], padding[2] do
  #  indent padding[1], padding[3] do
  #    yield
  #  end
  #end
end
page_height() click to toggle source

Returns the height of the current page from edge-to-edge

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 67
def page_height
  page.dimensions[3]
end
page_margin() click to toggle source

Returns the margins for the current page as a 4 element array (top, right, bottom, left)

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 110
def page_margin
  [page.margins[:top], page.margins[:right], page.margins[:bottom], page.margins[:left]]
end
page_margin_bottom() click to toggle source

Returns the width of the bottom margin for the current page

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 138
def page_margin_bottom
  page.margins[:bottom]
end
page_margin_left() click to toggle source

Returns the width of the left margin for the current page

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 116
def page_margin_left
  page.margins[:left]
end
Also aliased as: left_margin
page_margin_right() click to toggle source

Returns the width of the right margin for the current page

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 124
def page_margin_right
  page.margins[:right]
end
Also aliased as: right_margin
page_margin_top() click to toggle source

Returns the width of the top margin for the current page

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 132
def page_margin_top
  page.margins[:top]
end
page_side(pgnum = nil, invert = nil) click to toggle source

Returns the side the current page is facing, :recto or :verso.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 156
def page_side pgnum = nil, invert = nil
  if invert
    (recto_page? pgnum) ? :verso : :recto
  else
    (recto_page? pgnum) ? :recto : :verso
  end
end
page_width() click to toggle source

Returns the width of the current page from edge-to-edge

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 53
def page_width
  page.dimensions[2]
end
parse_text(string, options = {}) click to toggle source

Parse the text into an array of fragments using the text formatter.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 373
def parse_text string, options = {}
  return [] if string.nil?

  options = options.dup
  if (format_option = options.delete :inline_format)
    format_option = [] unless ::Array === format_option
    fragments = text_formatter.format string, *format_option
  else
    fragments = [text: string]
  end

  if (color = options.delete :color)
    fragments.map do |fragment|
      fragment[:color] ? fragment : fragment.merge(color: color)
    end
  else
    fragments
  end
end
perform_discretely() { || ... } click to toggle source

Perform an operation (such as creating a new page) without triggering the on_page_create callback

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 820
def perform_discretely
  if (saved_callback = state.on_page_create_callback)
    # equivalent to calling `on_page_create`
    state.on_page_create_callback = nil
    yield
    # equivalent to calling `on_page_create &saved_callback`
    state.on_page_create_callback = saved_callback
  else
    yield
  end
end
recto_page?(pgnum = nil) click to toggle source

Returns whether the page is a recto page.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 166
def recto_page? pgnum = nil
  (pgnum || page_number).odd?
end
register_font(data) click to toggle source

Registers a new custom font described in the data parameter after converting the font name to a String.

Example:

register_font Roboto: {
  normal: 'fonts/roboto-normal.ttf',
  italic: 'fonts/roboto-italic.ttf',
  bold: 'fonts/roboto-bold.ttf',
  bold_italic: 'fonts/roboto-bold_italic.ttf'
}
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 213
def register_font data
  font_families.update data.transform_keys(&:to_s)
end
resolve_font_style(styles) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 290
def resolve_font_style styles
  if styles.include? :bold
    (styles.include? :italic) ? :bold_italic : :bold
  elsif styles.include? :italic
    :italic
  else
    :normal
  end
end
resolve_legacy_icon_name(name) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 345
def resolve_legacy_icon_name name
  ::Prawn::Icon::Compatibility::SHIMS[%(fa-#{name})]
end
right_margin()

deprecated

Alias for: page_margin_right
scratch?() click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 876
def scratch?
  (@_label ||= (state.store.info.data[:Scratch] ? :scratch : :primary)) == :scratch
rescue
  false # NOTE this method may get called before the state is initialized
end
Also aliased as: is_scratch?
set_page_margin(margin) click to toggle source

Set the margins for the current page.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 102
def set_page_margin margin
  # FIXME: is there a cleaner way to set margins? does it make sense to override create_new_page?
  apply_margin_options margin: margin
  generate_margin_box
end
shade_box(color, line_color = nil, options = {}) { || ... } click to toggle source

Fills and, optionally, strokes the current bounds using the fill and stroke color specified, then yields to the block. The only_if option can be used to conditionally disable this behavior.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 677
def shade_box color, line_color = nil, options = {}
  if (!options.key? :only_if) || options[:only_if]
    # FIXME: could use save_graphics_state here
    previous_fill_color = current_fill_color
    fill_color color
    fill_rectangle [bounds.left, bounds.top], bounds.right, bounds.top - bounds.bottom
    fill_color previous_fill_color
    if line_color
      line_width 0.5
      previous_stroke_color = current_stroke_color
      stroke_color line_color
      stroke_bounds
      stroke_color previous_stroke_color
    end
  end
  yield
end
span_page_width_if(verdict) { || ... } click to toggle source

Stretch the current bounds to the left and right edges of the current page while yielding the specified block if the verdict argument is true. Otherwise, simply yield the specified block.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 594
def span_page_width_if verdict
  if verdict
    indent(-bounds_margin_left, -bounds_margin_right) do
      yield
    end
  else
    yield
  end
end
start_new_page_discretely(options = {}) click to toggle source

Start a new page without triggering the on_page_create callback

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 841
def start_new_page_discretely options = {}
  perform_discretely { start_new_page options }
end
stroke_horizontal_rule(rule_color = stroke_color, options = {}) click to toggle source

Strokes a horizontal line using the current bounds. The width of the line can be specified using the line_width option. The offset from the cursor can be set using the at option.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 699
def stroke_horizontal_rule rule_color = stroke_color, options = {}
  rule_y = cursor - (options[:at] || 0)
  rule_style = options[:line_style]
  rule_width = options[:line_width] || 0.5
  rule_x_start = bounds.left
  rule_x_end = bounds.right
  rule_inked = false
  save_graphics_state do
    line_width rule_width
    stroke_color rule_color
    case rule_style
    when :dashed
      dash rule_width * 4
    when :dotted
      dash rule_width
    when :double
      stroke_horizontal_line rule_x_start, rule_x_end, at: (rule_y + rule_width)
      stroke_horizontal_line rule_x_start, rule_x_end, at: (rule_y - rule_width)
      rule_inked = true
    end if rule_style
    stroke_horizontal_line rule_x_start, rule_x_end, at: rule_y unless rule_inked
  end
end
stroke_vertical_rule(rule_color = stroke_color, options = {}) click to toggle source

A compliment to the stroke_horizontal_rule method, strokes a vertical line using the current bounds. The width of the line can be specified using the line_width option. The horizontal (x) position can be specified using the at option.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 728
def stroke_vertical_rule rule_color = stroke_color, options = {}
  rule_x = options[:at] || 0
  rule_y_from = bounds.top
  rule_y_to = bounds.bottom
  rule_style = options[:line_style]
  rule_width = options[:line_width] || 0.5
  save_graphics_state do
    line_width rule_width
    stroke_color rule_color
    case rule_style
    when :dashed
      dash rule_width * 4
    when :dotted
      dash rule_width
    when :double
      stroke_vertical_line rule_y_from, rule_y_to, at: (rule_x - rule_width)
      rule_x += rule_width
    end if rule_style
    stroke_vertical_line rule_y_from, rule_y_to, at: rule_x
  end
end
text_with_formatted_first_line(string, first_line_opts, opts) click to toggle source

Performs the same work as Prawn::Text.text except that the first_line_opts are applied to the first line of text renderered. It's necessary to use low-level APIs in this method so we only style the first line and not the remaining lines (which is the default behavior in Prawn).

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 418
def text_with_formatted_first_line string, first_line_opts, opts
  color = opts.delete :color
  fragments = parse_text string, opts
  # NOTE the low-level APIs we're using don't recognize the :styles option, so we must resolve
  if (styles = opts.delete :styles)
    opts[:style] = resolve_font_style styles
  end
  if (first_line_styles = first_line_opts.delete :styles)
    first_line_opts[:style] = resolve_font_style first_line_styles
  end
  first_line_color = (first_line_opts.delete :color) || color
  opts = opts.merge document: self
  # QUESTION should we merge more carefully here? (hand-select keys?)
  first_line_opts = opts.merge(first_line_opts).merge single_line: true, first_line: true
  box = ::Prawn::Text::Formatted::Box.new fragments, first_line_opts
  # NOTE get remaining_fragments before we add color to fragments on first line
  if (text_indent = opts.delete :indent_paragraphs)
    remaining_fragments = indent text_indent do
      box.render dry_run: true
    end
  else
    remaining_fragments = box.render dry_run: true
  end
  # NOTE color must be applied per-fragment
  fragments.each {|fragment| fragment[:color] ||= first_line_color } if first_line_color
  if text_indent
    indent text_indent do
      fill_formatted_text_box fragments, first_line_opts
    end
  else
    fill_formatted_text_box fragments, first_line_opts
  end
  unless remaining_fragments.empty?
    # NOTE color must be applied per-fragment
    remaining_fragments.each {|fragment| fragment[:color] ||= color } if color
    remaining_fragments = fill_formatted_text_box remaining_fragments, opts
    draw_remaining_formatted_text_on_new_pages remaining_fragments, opts
  end
end
transform_text(text, transform) click to toggle source

Apply the text transform to the specified text.

Supported transform values are “uppercase”, “lowercase”, or “none” (passed as either a String or a Symbol). When the uppercase transform is applied to the text, it correctly uppercases visible text while leaving markup and named character entities unchanged. The none transform returns the text unmodified.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 466
def transform_text text, transform
  case transform
  when :uppercase, 'uppercase'
    uppercase_pcdata text
  when :lowercase, 'lowercase'
    lowercase_pcdata text
  when :capitalize, 'capitalize'
    capitalize_words_pcdata text
  else
    text
  end
end
verso_page?(pgnum = nil) click to toggle source

Returns whether the page is a verso page.

# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 172
def verso_page? pgnum = nil
  (pgnum || page_number).even?
end
width_of_string(string, options = {}) click to toggle source

Override width of string to check for placeholder char, which uses character spacing to control width

Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 337
def width_of_string string, options = {}
  string == PlaceholderChar ? @character_spacing : super
end
with_dry_run(&block) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 906
def with_dry_run &block
  total_height, = dry_run(&block)
  instance_exec total_height, &block
end