Module: AdvertisementHelper

Defined in:
app/helpers/advertisement_helper.rb

Constant Summary collapse

RTL_BLOCK_START =

Character ordinal for the start of the Unicode RTL characters block.

0x0590
RTL_BLOCK_END =

Character ordinal for the end of the Unicode RTL characters block.

0x06FF

Instance Method Summary collapse

Instance Method Details

#community_icon(icon_path) ⇒ Magick::ImageList

Loads and returns a Magick image either from local files or from a URI for use in generating composite Magick images.

Examples:

Load an image from app/assets/images:

# This uses the path from which the image would be accessed via HTTP.
helpers.community_icon('/assets/codidact.png')

Parameters:

  • icon_path (String)

    A path or URI from which to load the image. If using a path this should be the asset path as it would be accessible through the Rails server - see example.

Returns:

  • (Magick::ImageList)

    An ImageList containing the icon.



85
86
87
88
89
90
91
92
93
94
# File 'app/helpers/advertisement_helper.rb', line 85

def community_icon(icon_path)
  if icon_path.start_with? '/assets/'
    icon = Magick::ImageList.new("./app/assets/images/#{File.basename(icon_path)}")
  else
    icon = Magick::ImageList.new
    icon_path_content = URI.open(icon_path).read # rubocop:disable Security/Open
    icon.from_blob(icon_path_content)
  end
  icon
end

#do_rtl_witchcraft(str) ⇒ String

Used to artificially fix RTL text in environments that are incapable of rendering mixed LTR and RTL text. Parses the given string in sections of LTR and RTL; at each boundary between sections, dumps the section into an output buffer - forwards if the section was LTR, reversed if the section was RTL - and clears the scan buffer. This has the effect of reversing RTL sections in-place, which seems to correct their direction.

Parameters:

  • str (String)

    The mixed-text string on which to do witchcraft.

Returns:

  • (String)

    A “fixed” string suitable to render in RTL-ignorant environments. ImageMagick, for instance.



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
# File 'app/helpers/advertisement_helper.rb', line 13

def do_rtl_witchcraft(str)
  chars = str.chars
  output_buffer = ''
  scan_buffer = []
  current_mode = rtl?(chars[0]) ? :rtl : :ltr
  chars.each.with_index do |c, i|
    new_mode = if c.match?(/\s/)
                 if chars[i - 1].present? && chars[i + 1].present? && rtl?(chars[i - 1]) && rtl?(chars[i + 1])
                   :rtl
                 else
                   :ltr
                 end
               else
                 rtl?(c) ? :rtl : :ltr
               end
    next if new_mode.nil?

    if new_mode != current_mode
      output_buffer += if current_mode == :rtl
                         scan_buffer.join.reverse
                       else
                         scan_buffer.join
                       end
      scan_buffer = []
    end
    current_mode = new_mode
    scan_buffer << c
  end

  output_buffer += if current_mode == :rtl
                     scan_buffer.join.reverse
                   else
                     scan_buffer.join
                   end
end

#rtl?(char) ⇒ Boolean

Returns true if the provided character is part of an RTL character set.

Parameters:

  • char (String)

    A single-character string.

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)

    If the string provided is longer than one character.



54
55
56
57
58
59
# File 'app/helpers/advertisement_helper.rb', line 54

def rtl?(char)
  return false if char.nil?
  raise ArgumentError, 'More than one character provided' if char.length > 1

  char.ord >= RTL_BLOCK_START && char.ord <= RTL_BLOCK_END
end

#wrap_text(text, width, font_size) ⇒ String

Estimates the width of text for rendering in ImageMagick and attempts to wrap it over multiple lines to avoid text being cut off or too short.

Parameters:

  • text (String)

    The text to wrap.

  • width (Integer)

    The available width in pixels.

  • font_size (Integer)

    The font size in which the text will be rendered.

Returns:

  • (String)

    The wrapped text, as one string with line breaks in the right places.



68
69
70
71
72
73
74
# File 'app/helpers/advertisement_helper.rb', line 68

def wrap_text(text, width, font_size)
  columns = (width * 2.5 / font_size).to_i
  # Source: http://viseztrance.com/2011/03/texts-over-multiple-lines-with-rmagick.html
  text.split("\n").collect do |line|
    line.length > columns ? line.gsub(/(.{1,#{columns}})(\s+|$)/, "\\1\n").strip : line
  end * "\n"
end