Class: JiraAdf
- Inherits:
-
Object
- Object
- JiraAdf
- Defined in:
- lib/jira_adf.rb,
lib/jira_adf/version.rb
Overview
A simple ADF (Atlassian Document Format) builder.
Usage example:
result = JiraAdf {
# Keyword args become "attrs".
heading(level: 3) { text('An h3 heading') }
ordered_list {
list_item { paragraph { text('Paragraph in listItem') } }
list_item {
paragraph {
text('Text with ')
# Methods chained at the end of the node become "marks". Their
# keyword args become "attrs" of the mark.
text('bold and superscript').strong.subsup(type: 'sub')
text(' styling in the middle.')
}
}
# Use a regular lambda for snippet reuse. Keep in mind that due to how
# closures work, if you call this lambda in sub-nested scopes, it will
# still add an item in the scope where it was defined. And it will not
# exist at higher / neighbor scopes.
item = -> string { list_item { paragraph { text(string) } } }
# Now you can use shorter syntax.
item['Item 3']
item['Item 4']
item['Item 5']
}
}
result.to_h # => Ruby Hash ready for converting to JSON.
Constant Summary collapse
- VERSION =
'0.1.0'
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(node = { 'version' => 1, 'type' => 'doc' }, &block) ⇒ JiraAdf
constructor
A new instance of JiraAdf.
- #method_missing(type, *args, **kwargs, &block) ⇒ Object
- #to_h ⇒ Object
Constructor Details
#initialize(node = { 'version' => 1, 'type' => 'doc' }, &block) ⇒ JiraAdf
Returns a new instance of JiraAdf.
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/jira_adf.rb', line 64 def initialize(node = { 'version' => 1, 'type' => 'doc' }, &block) @node = self.class.format_hash(node) instance_eval(&block) if block_given? # It's important that this variable is not yet set while instance_eval on # the previous line is being executed. This is how method_missing can # distinguish whether a method was called on a node, or it was called in an # instance_eval block. We use this fact to switch to adding `mark` fields # instead of `content` fields. @block_evaled_or_not_given = true end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(type, *args, **kwargs, &block) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/jira_adf.rb', line 87 def method_missing(type, *args, **kwargs, &block) if @block_evaled_or_not_given hash = { 'type' => type } hash.merge! 'attrs' => kwargs if kwargs.any? @node['marks'] ||= [] @node['marks'] << self.class.new(hash) self elsif type == :text self.class.new('type' => 'text', 'text' => args[0]).tap { |node| @node['content'] ||= [] @node['content'] << node } else hash = { 'type' => type } hash.merge! 'attrs' => kwargs if kwargs.any? self.class.new(hash, &block).tap { |node| @node['content'] ||= [] @node['content'] << node } end end |
Class Method Details
.camelize(term) ⇒ Object
58 59 60 61 |
# File 'lib/jira_adf.rb', line 58 def camelize(term) term.to_s.gsub(/(?:^|_+)([^_])/) { $1.upcase } .tap { |s| s[0] = s[0].downcase } end |
.format_hash(hash) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/jira_adf.rb', line 43 def format_hash(hash) hash.map { |k, v| key = camelize(k) [ key, if key == 'type'; camelize(v) elsif Hash === v; format_hash(v) elsif Symbol === v; v.to_s else; v end ] }.to_h end |
Instance Method Details
#to_h ⇒ Object
76 77 78 79 80 81 82 83 84 85 |
# File 'lib/jira_adf.rb', line 76 def to_h @node.transform_values { |v| case v when Array; v.map { |e| self.class === e ? e.to_h : e } when Hash; v.transform_values { |e| self.class === e ? e.to_h : e } when self.class; v.to_h else; v end } end |