Class: HTML::Pipeline::Mrkdwn

Inherits:
Filter
  • Object
show all
Defined in:
lib/html/pipeline/mrkdwn/mrkdwn_filter.rb,
lib/html/pipeline/mrkdwn/version.rb

Overview

HTML Filter for converting Slack’s ‘mrkdwn` markup language. api.slack.com/reference/surfaces/formatting#basics

Context options:

:emoji_image_tag - a Proc that returns an `img` tag for custom Emoji
:slack_channels - a hash of Slack channel ids and channel names
:slack_users - a hash of Slack user or bot ids and display names

Constant Summary collapse

VERSION =
"0.2.1"
EMOJI_AND_WHITESPACE_PATTERN =
/(?::[\w+-_]+?:|\s)+/.freeze
NON_CAPTURING_EMOJI_PATTERN =
/:[\w+-_]+?:/.freeze
MULTILINE_CODE_PATTERN =
/```(.+?)```/m.freeze
CODE_PATTERN =
/`(?=\S)(.+?)(?<=\S)`/.freeze
BLOCKQUOTE_PATTERN =
/(^&gt;[^\n]*\n?)+/.freeze
MENTION_PATTERN =
/
  &lt;
  ([@#!][a-z0-9][a-z0-9-]*)
  &gt;
/ix.freeze
/
  &lt;
  ((?:http|mailto)[^|]+)
  (?:\|(.+?))?
  &gt;
/x.freeze
LINE_BREAK_PATTERN =
/\n/.freeze
EMOJI_PATTERN =
/:([\w+-_]+?):/.freeze
STYLE_PATTERN =
/
  ([`*_~])
  (?=\S)(.+?)(?<=\S)
  \1
/x.freeze
IGNORE_PARENTS =
%w[pre code a].to_set
ELEMENTS =
{
  multiline_code: %w[```],
  code: %w[`],
  blockquote: %w[&gt;],
  mention: %w[@ # !],
  link: %w[&lt;],
  line_break: %W[\n \r\n],
  emoji: %w[:],
  style: %w[* _ ~],
  unescape: %w[&amp;lowbar;]
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(doc, context = nil, result = nil) ⇒ Mrkdwn

Returns a new instance of Mrkdwn.



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/html/pipeline/mrkdwn/mrkdwn_filter.rb', line 64

def initialize(doc, context = nil, result = nil)
  super

  default_emoji_image_tag = ->(emoji) { "<img src=\"#{emoji.image_filename}\" alt=\"#{emoji.name}\" class=\"emoji\">" }

  @emoji_image_tag = @context[:emoji_image_tag] || default_emoji_image_tag
  @large_emoji_image_tag = @context[:large_emoji_image_tag] || @emoji_image_tag
  @large_emoji_class = @context[:large_emoji_class] || "emoji-lg"
  @slack_channels = @context[:slack_channels] || {}
  @slack_users = @context[:slack_users] || {}
end

Instance Attribute Details

#large_emojiObject (readonly)

Returns the value of attribute large_emoji.



15
16
17
# File 'lib/html/pipeline/mrkdwn/mrkdwn_filter.rb', line 15

def large_emoji
  @large_emoji
end

Instance Method Details

#callObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/html/pipeline/mrkdwn/mrkdwn_filter.rb', line 76

def call
  div = doc.at_css("div")

  if wants_large_emoji?(div.content)
    @large_emoji = true
    div.add_class(@large_emoji_class)
  end

  ELEMENTS.each do |element, includes|
    process_text_nodes(includes) { |content| call_filter(element, content) }
  end

  doc
end

#validateObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/html/pipeline/mrkdwn/mrkdwn_filter.rb', line 91

def validate
  if context[:emoji_image_tag] && !context[:emoji_image_tag].is_a?(Proc)
    raise ArgumentError,
          "context[:emoji_image_tag] should return a Proc that takes an Emoji object as in the 'gemoji' gem."
  end

  if context[:large_emoji_image_tag] && !context[:large_emoji_image_tag].is_a?(Proc)
    raise ArgumentError,
          "context[:large_emoji_image_tag] should return a Proc that takes an Emoji object as in the 'gemoji' gem."
  end

  if context[:slack_channels] && !context[:slack_channels].is_a?(Hash)
    raise ArgumentError,
          "context[:slack_channels] should return a Hash whose keys are Slack channel ids and values are their names."
  end

  if context[:slack_users] && !context[:slack_users].is_a?(Hash)
    raise ArgumentError,
          "context[:slack_users] should return a Hash whose keys are Slack user or bot ids and values are their display names."
  end
end