Module: Jekyll::Filters::Strings

Defined in:
lib/jekyll/filters/strings.rb

Constant Summary collapse

ALLOWED_ATTRIBUTES =
%w[style href src alt controls data-align data-multimedia data-multimedia-inner id name rel target referrerpolicy class colspan rowspan role data-turbo start type reversed].freeze
ALLOWED_TAGS =
%w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote figcaption a sub sup small table thead tbody tfoot tr th td br code].freeze

Instance Method Summary collapse

Instance Method Details

#allow_inclusive_language_in_markdown(input) ⇒ String

We often use * for inclusive language, where language is gendered. This clashes with Commonmark’s understanding of emphasis delimiters.

But we want to support inclusive language and we don’t necessarily need to know what a escape character is to do it.

This filter disables emphasis in favor of emphasis and escapes them.

Parameters:

  • :input (String)

Returns:

  • (String)

See Also:



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
# File 'lib/jekyll/filters/strings.rb', line 37

def allow_inclusive_language_in_markdown(input)
  return input if input.nil? || input.empty?
  return input unless input.to_s.include? '*'

  require 'securerandom'

  # Something that can't be accidentally replaced
  star_delimiter = "||#{SecureRandom.hex}||"
  escaped_delimiter = "||#{SecureRandom.hex}||"

  # 1. Exclude escaped stars
  #
  # 2. Exclude bold
  #
  # 3. Exclude list items
  #
  # 4. Escape remaining stars
  #
  # 5. Recover original stars
  input.to_s
       .gsub('\*', escaped_delimiter)
       .gsub('**', star_delimiter * 2)
       .gsub(/^(\s*)\*/, "\\1#{star_delimiter}")
       .gsub('*', '\*')
       .gsub(star_delimiter, '*')
       .gsub(escaped_delimiter, '\*')
end

#component_escape(input) ⇒ String

Escapes a string by percent encoding all reserved characters

Parameters:

  • :input (Any)

Returns:

  • (String)


73
74
75
76
77
78
# File 'lib/jekyll/filters/strings.rb', line 73

def component_escape(input)
  require 'addressable'

  @@component_escape ||= {}
  @@component_escape[input.to_s] ||= Addressable::URI.parse(input.to_s).normalize.to_s
end

#replace_last(input, search, replace) ⇒ String

Replaces the last ocurrence of a String

Parameters:

  • (String)
  • (String)
  • (String)

Returns:

  • (String)


17
18
19
20
21
22
# File 'lib/jekyll/filters/strings.rb', line 17

def replace_last(input, search, replace)
  hay = input.split search
  needle = "#{replace}#{hay.pop}"

  hay.join(search) + needle
end

#sanitize_html(input, tags = nil, attrs = nil) ⇒ Object

TODO:

Benchmark Jekyll cache, because it’ll need to hash all params

Sanitizes HTML. By default follows Sutty CMS allowlist.

Parameters:

  • input (String)
  • tags (String, Array<String>) (defaults to: nil)

    Allowed elements. Can be a comma-separated string

  • attrs (String, Array<String>) (defaults to: nil)

    Allowed attributes. Can be a comma-separated string



86
87
88
89
90
91
# File 'lib/jekyll/filters/strings.rb', line 86

def sanitize_html(input, tags = nil, attrs = nil)
  tags = list_to_array(tags, ALLOWED_TAGS)
  attrs = list_to_array(attrs, ALLOWED_ATTRIBUTES)

  sanitizer.sanitize(input.to_s.tr("\r", '').unicode_normalize, tags: tags, attributes: attrs).strip
end

#start_with(input, start) ⇒ Object

String#start_with?



7
8
9
# File 'lib/jekyll/filters/strings.rb', line 7

def start_with(input, start)
  input.to_s.start_with? start.to_s
end

#unescape(input) ⇒ Object



65
66
67
# File 'lib/jekyll/filters/strings.rb', line 65

def unescape(input)
  CGI.unescapeHTML input.to_s
end