nexmo_markdown_renderer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +54 -0
  4. data/config/code_languages.yml +138 -0
  5. data/config/dynamic_content.yml +1 -0
  6. data/config/locales/en.yml +176 -0
  7. data/lib/nexmo_markdown_renderer.rb +28 -0
  8. data/lib/nexmo_markdown_renderer/cli.rb +13 -0
  9. data/lib/nexmo_markdown_renderer/core_ext/html.rb +7 -0
  10. data/lib/nexmo_markdown_renderer/core_ext/string.rb +14 -0
  11. data/lib/nexmo_markdown_renderer/filters/anchor_filter.rb +14 -0
  12. data/lib/nexmo_markdown_renderer/filters/audio_filter.rb +18 -0
  13. data/lib/nexmo_markdown_renderer/filters/block_escape_filter.rb +21 -0
  14. data/lib/nexmo_markdown_renderer/filters/break_filter.rb +10 -0
  15. data/lib/nexmo_markdown_renderer/filters/code_filter.rb +62 -0
  16. data/lib/nexmo_markdown_renderer/filters/code_snippet_filter.rb +187 -0
  17. data/lib/nexmo_markdown_renderer/filters/code_snippet_list_filter.rb +26 -0
  18. data/lib/nexmo_markdown_renderer/filters/code_snippets_filter.rb +170 -0
  19. data/lib/nexmo_markdown_renderer/filters/collapsible_filter.rb +27 -0
  20. data/lib/nexmo_markdown_renderer/filters/columns_filter.rb +47 -0
  21. data/lib/nexmo_markdown_renderer/filters/concept_list_filter.rb +30 -0
  22. data/lib/nexmo_markdown_renderer/filters/dynamic_content_filter.rb +28 -0
  23. data/lib/nexmo_markdown_renderer/filters/external_link_filter.rb +29 -0
  24. data/lib/nexmo_markdown_renderer/filters/frontmatter_filter.rb +11 -0
  25. data/lib/nexmo_markdown_renderer/filters/heading_filter.rb +57 -0
  26. data/lib/nexmo_markdown_renderer/filters/i18n/frontmatter_filter.rb +16 -0
  27. data/lib/nexmo_markdown_renderer/filters/i18n/smartling_converter_filter.rb +22 -0
  28. data/lib/nexmo_markdown_renderer/filters/icon_filter.rb +19 -0
  29. data/lib/nexmo_markdown_renderer/filters/indent_filter.rb +17 -0
  30. data/lib/nexmo_markdown_renderer/filters/inline_escape_filter.rb +14 -0
  31. data/lib/nexmo_markdown_renderer/filters/js_sequence_diagram_filter.rb +18 -0
  32. data/lib/nexmo_markdown_renderer/filters/label_filter.rb +29 -0
  33. data/lib/nexmo_markdown_renderer/filters/language_filter.rb +12 -0
  34. data/lib/nexmo_markdown_renderer/filters/markdown_filter.rb +81 -0
  35. data/lib/nexmo_markdown_renderer/filters/mermaid_filter.rb +29 -0
  36. data/lib/nexmo_markdown_renderer/filters/modal_filter.rb +37 -0
  37. data/lib/nexmo_markdown_renderer/filters/partial_filter.rb +29 -0
  38. data/lib/nexmo_markdown_renderer/filters/php_inliner_filter.rb +11 -0
  39. data/lib/nexmo_markdown_renderer/filters/screenshot_filter.rb +22 -0
  40. data/lib/nexmo_markdown_renderer/filters/tab_filter.rb +298 -0
  41. data/lib/nexmo_markdown_renderer/filters/techio_filter.rb +20 -0
  42. data/lib/nexmo_markdown_renderer/filters/tooltip_filter.rb +18 -0
  43. data/lib/nexmo_markdown_renderer/filters/unfreeze_filter.rb +16 -0
  44. data/lib/nexmo_markdown_renderer/filters/use_case_list_filter.rb +20 -0
  45. data/lib/nexmo_markdown_renderer/initializers/doc_finder.rb +5 -0
  46. data/lib/nexmo_markdown_renderer/initializers/i18n.rb +4 -0
  47. data/lib/nexmo_markdown_renderer/initializers/redcarpet.rb +7 -0
  48. data/lib/nexmo_markdown_renderer/markdown_renderer.rb +47 -0
  49. data/lib/nexmo_markdown_renderer/models/code_language.rb +79 -0
  50. data/lib/nexmo_markdown_renderer/models/code_snippet.rb +72 -0
  51. data/lib/nexmo_markdown_renderer/models/concept.rb +83 -0
  52. data/lib/nexmo_markdown_renderer/models/tutorial.rb +148 -0
  53. data/lib/nexmo_markdown_renderer/models/use_case.rb +81 -0
  54. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/android.rb +25 -0
  55. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/base.rb +12 -0
  56. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/curl.rb +29 -0
  57. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/dotnet.rb +23 -0
  58. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/java.rb +32 -0
  59. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/javascript.rb +23 -0
  60. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/kotlin.rb +25 -0
  61. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/objective_c.rb +25 -0
  62. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/php.rb +23 -0
  63. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/python.rb +23 -0
  64. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/ruby.rb +23 -0
  65. data/lib/nexmo_markdown_renderer/services/code_snippet_renderer/swift.rb +25 -0
  66. data/lib/nexmo_markdown_renderer/services/doc_finder.rb +119 -0
  67. data/lib/nexmo_markdown_renderer/views/code_snippets/_application_messages_dispatch.html.erb +9 -0
  68. data/lib/nexmo_markdown_renderer/views/code_snippets/_application_rtc.html.erb +28 -0
  69. data/lib/nexmo_markdown_renderer/views/code_snippets/_application_voice.html.erb +24 -0
  70. data/lib/nexmo_markdown_renderer/views/code_snippets/_code_only.html.erb +6 -0
  71. data/lib/nexmo_markdown_renderer/views/code_snippets/_configure_client.html.erb +20 -0
  72. data/lib/nexmo_markdown_renderer/views/code_snippets/_dependencies.html.erb +11 -0
  73. data/lib/nexmo_markdown_renderer/views/code_snippets/_write_code.html.erb +13 -0
  74. data/lib/nexmo_markdown_renderer/views/code_snippets/list/plain.html.erb +10 -0
  75. data/lib/nexmo_markdown_renderer/views/concepts/list/plain.html.erb +5 -0
  76. data/lib/nexmo_markdown_renderer/views/use_case/_index.html.erb +41 -0
  77. data/lib/nexmo_markdown_renderer/views/use_case/index.html.erb +48 -0
  78. data/lib/nexmo_markdown_renderer/views/use_case/list/plain.html.erb +5 -0
  79. data/lib/nexmo_markdown_renderer/views/use_case/show.html.erb +8 -0
  80. data/lib/version.rb +7 -0
  81. metadata +322 -0
@@ -0,0 +1,27 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class CollapsibleFilter < Banzai::Filter
4
+ # Transforms matching input into a collapsible HTML element on NDP.
5
+ # Matching input example: | ## Heading\n|\nContent\n\n
6
+
7
+ def call(input)
8
+ input.gsub(/^\|\s(\#{1,6})(\s)?(.+?)\n^\|\n(.+?)\n\n/m) do |_s|
9
+ heading = $3
10
+ body = $4.gsub(/^\|\n/, "\n")
11
+ body = body.gsub(/^\|\s/, '')
12
+ parsed_body = Nexmo::Markdown::Renderer.new.call(body)
13
+
14
+ <<~HEREDOC
15
+ <div class="Vlt-accordion Vlt-box Vlt-box--lesspadding Nxd-accordion-emphasis">
16
+ <h5 class="Vlt-accordion__trigger" tabindex="0">#{heading}</h5>
17
+ <div class="Vlt-accordion__content Vlt-accordion__content--noborder">
18
+ #{parsed_body}
19
+ </div>
20
+ </div>
21
+ HEREDOC
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class ColumnsFilter < Banzai::Filter
4
+ def call(input)
5
+ input.gsub!(%r{{column\:([1-4])\/([1-4])}\n(.+?){end}}m) do
6
+ s = []
7
+ s << row_start if $1 == '1'
8
+ s << column_start($2)
9
+ s << $3
10
+ s << column_end
11
+ s << row_end if $1 == $2
12
+ s.join('')
13
+ end
14
+
15
+ input
16
+ end
17
+
18
+ private
19
+
20
+ def row_start
21
+ "FREEZESTART#{Base64.urlsafe_encode64('<div class="row">')}FREEZEEND\n"
22
+ end
23
+
24
+ def row_end
25
+ close_tag
26
+ end
27
+
28
+ def close_tag
29
+ "FREEZESTART#{Base64.urlsafe_encode64('</div>')}FREEZEEND"
30
+ end
31
+
32
+ def column_start(columns)
33
+ html = "<div class='column small-12 medium-#{part_size(columns)}'>"
34
+ "FREEZESTART#{Base64.urlsafe_encode64(html)}FREEZEEND\n"
35
+ end
36
+
37
+ def column_end
38
+ "FREEZESTART#{Base64.urlsafe_encode64('</div>')}FREEZEEND\n"
39
+ end
40
+
41
+ def part_size(columns)
42
+ 12 / Integer(columns)
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,30 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class ConceptListFilter < Banzai::Filter
4
+ def call(input)
5
+ input.gsub(/```concept_list(.+?)```/m) do |_s|
6
+ config = YAML.safe_load($1)
7
+
8
+ raise 'concept_list filter takes a YAML config' if config.nil?
9
+ raise "concept_list filter requires 'product' or 'concepts' key" unless config['product'] || config['concepts']
10
+
11
+ if config['product']
12
+ @product = config['product']
13
+ @concepts = Nexmo::Markdown::Concept.by_product(@product, @options[:language])
14
+ elsif config['concepts']
15
+ @concepts = Nexmo::Markdown::Concept.by_name(config['concepts'], @options[:language])
16
+ end
17
+
18
+ @concepts.reject!(&:ignore_in_list)
19
+
20
+ return '' if @concepts.empty?
21
+
22
+ erb = File.read("#{GEM_ROOT}/lib/nexmo_markdown_renderer/views/concepts/list/plain.html.erb")
23
+ html = ERB.new(erb).result(binding)
24
+ "FREEZESTART#{Base64.urlsafe_encode64(html)}FREEZEEND"
25
+ end
26
+ end
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class DynamicContentFilter < Banzai::Filter
4
+ def call(input)
5
+ input.gsub(/(\s|^)\[\~(.+?)\~\](\s|$)/) do
6
+ content = environment_value($2) || config_value($2) || "VALUE NOT SET: #{$2}"
7
+ "#{$1}#{content}#{$3}"
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def environment_value(key)
14
+ return nil unless ENV['DYNAMIC_CONTENT']
15
+
16
+ @environment_dynamic_content ||= YAML.safe_load(ENV['DYNAMIC_CONTENT'])
17
+ @environment_dynamic_content ||= YAML.safe_load(temp)
18
+ @environment_dynamic_content[key]
19
+ end
20
+
21
+ def config_value(key)
22
+ @config_dynamic_content ||= YAML.load_file("#{GEM_ROOT}/config/dynamic_content.yml")
23
+ @config_dynamic_content[key]
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class ExternalLinkFilter < Banzai::Filter
4
+ def call(input)
5
+ @input = input
6
+
7
+ document.css('a').each_with_index do |link, _index|
8
+ if link['href']&.start_with?('http') && link['class'] && !link['class'].include?('no-external-marker')
9
+ link['target'] = '_blank'
10
+ if link.css('svg').empty?
11
+ link.add_child <<~HEREDOC
12
+ &nbsp;<svg class="Vlt-icon Vlt-icon--smaller Vlt-icon--text-bottom Vlt-blue-dark"><use xlink:href="/symbol/volta-icons.svg#Vlt-icon-open"></use></svg>
13
+ HEREDOC
14
+ end
15
+ end
16
+ end
17
+
18
+ @document.to_html
19
+ end
20
+
21
+ private
22
+
23
+ def document
24
+ @document ||= Nokogiri::HTML::DocumentFragment.parse(@input)
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class FrontmatterFilter < Banzai::Filter
4
+ def call(input)
5
+ # Remove frontmatter from the input
6
+ input.gsub(/\A(---.+?---)/mo, '')
7
+ end
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,57 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class HeadingFilter < Banzai::Filter
4
+ def call(input)
5
+ @input = input
6
+ @headings = []
7
+ heading_tag_list = %w[h1 h2 h3 h4 h5 h6]
8
+ headings = document.children.select do |child|
9
+ heading_tag_list.include? child.name
10
+ end
11
+
12
+ headings.each do |heading|
13
+ parameterized_heading = parameterized_heading_without_collision(heading)
14
+ heading['id'] = parameterized_heading
15
+ heading['data-id'] = SecureRandom.hex
16
+ heading['class'] = heading[:class]
17
+ heading['class'] += ' Vlt-title--icon'
18
+
19
+ heading.prepend_child <<~HEREDOC
20
+ <a href="##{parameterized_heading}" class="heading-permalink">
21
+ <svg class="Vlt-grey"><use xlink:href=\"/symbol/volta-icons.svg#Vlt-icon-link\" /></svg>
22
+ </a>
23
+ HEREDOC
24
+ end
25
+
26
+ @document.to_html
27
+ end
28
+
29
+ private
30
+
31
+ def document
32
+ @document ||= Nokogiri::HTML::DocumentFragment.parse(@input)
33
+ end
34
+
35
+ def parameterized_heading_without_collision(heading)
36
+ parameterized_heading = nil
37
+ index = nil
38
+
39
+ loop do
40
+ if index
41
+ parameterized_heading = "#{heading.text.parameterize}-#{index}"
42
+ index += 1
43
+ else
44
+ parameterized_heading = heading.text.parameterize
45
+ index = 2
46
+ end
47
+
48
+ break if @headings.exclude? parameterized_heading
49
+ end
50
+
51
+ @headings << parameterized_heading
52
+ parameterized_heading
53
+ end
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,16 @@
1
+ module Nexmo
2
+ module Markdown
3
+ module I18n
4
+ class FrontmatterFilter < Banzai::Filter
5
+ def call(input)
6
+ input.gsub(/\A(---.+?---)/mo) do |frontmatter|
7
+ frontmatter.gsub(/(\w*:)/) do |_key|
8
+ "```#{$1}```"
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ module Nexmo
2
+ module Markdown
3
+ module I18n
4
+ class SmartlingConverterFilter < Banzai::Filter
5
+ def call(input)
6
+ input = input.gsub(/\A\*\*\* \*\* \* \*\* \*\*\*\n*(.*)\n*------------------------------------------/m) do |_frontmatter|
7
+ front = $1.gsub(/`(.*):`(.*)/) do |_config|
8
+ "#{$1}:#{$2}"
9
+ end
10
+ <<~FRONTMATTER
11
+ ---
12
+ #{front}
13
+ ---
14
+ FRONTMATTER
15
+ end
16
+ input.gsub('\-', '-').gsub('\|', '|')
17
+ end
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class IconFilter < Banzai::Filter
4
+ def call(input)
5
+ input.gsub!('✅', '<svg class="Vlt-green Vlt-icon Vlt-icon--small"><use xlink:href="/symbol/volta-icons.svg#Vlt-icon-check" /></svg>')
6
+ input.gsub!('❌', '<svg class="Vlt-red Vlt-icon Vlt-icon--small"><use xlink:href="/symbol/volta-icons.svg#Vlt-icon-cross" /></svg>')
7
+
8
+ input.gsub!(/\[icon="(.+?)"\]/) do
9
+ <<~HEREDOC
10
+ <svg class="Vlt-green Vlt-icon Vlt-icon--small"><use xlink:href="/symbol/volta-icons.svg#Vlt-icon-#{$1}" /></svg>
11
+ HEREDOC
12
+ end
13
+
14
+ input
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class IndentFilter < Banzai::Filter
4
+ def call(input)
5
+ input.gsub(/^^\s{4}\-\>\s(.+?)$/) do
6
+ body = Nexmo::Markdown::Renderer.new.call($1)
7
+ <<~HEREDOC
8
+ <div class="indent">
9
+ #{body}
10
+ </div>
11
+ HEREDOC
12
+ end
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class InlineEscapeFilter < Banzai::Filter
4
+ def call(input)
5
+ # Freeze to prevent Markdown formatting
6
+ input.gsub(/``(.+?)``/) do |_s|
7
+ frozen_code = Base64.urlsafe_encode64("<code>#{$1}</code>")
8
+ "FREEZESTART#{frozen_code}FREEZEEND"
9
+ end
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class JsSequenceDiagramFilter < Banzai::Filter
4
+ def call(input)
5
+ input.gsub(/```js_sequence_diagram(.+?)```/m) do |_s|
6
+ diagram = <<~HEREDOC
7
+ <div class="js-diagram">
8
+ #{$1}
9
+ </div>
10
+ HEREDOC
11
+
12
+ "FREEZESTART#{Base64.urlsafe_encode64(diagram)}FREEZEEND"
13
+ end
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class LabelFilter < Banzai::Filter
4
+ def call(input)
5
+ input.gsub(/\[(GET|POST|PUT|DELETE|OPTIONS)\]/i) do |_s|
6
+ "<span class='Vlt-badge #{class_name($1)}'>#{$1}</span> "
7
+ end
8
+ end
9
+
10
+ private
11
+
12
+ def class_name(text)
13
+ case text
14
+ when 'POST'
15
+ 'Vlt-badge--green'
16
+ when 'GET'
17
+ 'Vlt-badge--blue'
18
+ when 'DELETE'
19
+ 'Vlt-badge--red'
20
+ when 'PUT'
21
+ 'Vlt-badge--yellow'
22
+ when 'OPTIONS'
23
+ 'Vlt-badge--grey'
24
+ end
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class LanguageFilter < Banzai::Filter
4
+ def call(input)
5
+ input.gsub(/\[(.+?)\]\(lang:.+?(?:'(.+?)'|"(.+?)")\)/) do |_s|
6
+ "<span lang='#{$2}'>#{$1}</span>"
7
+ end
8
+ end
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,81 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class MarkdownFilter < Banzai::Filter
4
+ def call(input)
5
+ markdown.render(input)
6
+ end
7
+
8
+ private
9
+
10
+ def renderer
11
+ @renderer ||= VoltaRender.new(options)
12
+ end
13
+
14
+ def markdown
15
+ @markdown ||= Redcarpet::Markdown.new(renderer, {
16
+ no_intra_emphasis: true,
17
+ tables: true,
18
+ strikethrough: true,
19
+ superscript: true,
20
+ underline: true,
21
+ highlight: true,
22
+ fenced_code_blocks: true,
23
+ disable_indented_code_blocks: true,
24
+ start_inline: true,
25
+ })
26
+ end
27
+ end
28
+
29
+ class VoltaRender < HTML
30
+ def initialize(options)
31
+ @options = options
32
+ super(options)
33
+ end
34
+
35
+ def paragraph(text)
36
+ return text if @options[:skip_paragraph_surround]
37
+
38
+ "<p>#{text}</p>"
39
+ end
40
+
41
+ def table(header, body)
42
+ '<div class="Vlt-table Vlt-table--data Vlt-table--bordered">' \
43
+ '<table>' \
44
+ "<thead>#{header}</thead>" \
45
+ "<tbody>#{body}</tbody>" \
46
+ '</table>' \
47
+ '</div>'
48
+ end
49
+
50
+ def block_quote(quote)
51
+ '<div class="Vlt-callout Vlt-callout--tip">' \
52
+ '<i></i>' \
53
+ '<div class="Vlt-callout__content">' \
54
+ "#{quote}" \
55
+ '</div>' \
56
+ '</div>'
57
+ end
58
+
59
+ def image(link, _title, _alt_text)
60
+ '<figure>' \
61
+ '<img src="'\
62
+ "#{link}"\
63
+ '" alt="#{alt_text}">' \
64
+ '</figure>'
65
+ end
66
+
67
+ def list(contents, list_type)
68
+ if "#{list_type}" == 'unordered'
69
+ '<ul class="Vlt-list Vlt-list--simple">' \
70
+ "#{contents}" \
71
+ '</ul>'
72
+ else
73
+ '<ol class="Vlt-list Vlt-list--simple">' \
74
+ "#{contents}" \
75
+ '</ol>' \
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+