nexmo_markdown_renderer 0.2.1 → 0.4.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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/config/locales/en.yml +1 -0
  3. data/lib/nexmo_markdown_renderer.rb +24 -1
  4. data/lib/nexmo_markdown_renderer/filters/block_escape_filter.rb +3 -3
  5. data/lib/nexmo_markdown_renderer/filters/code_filter.rb +17 -17
  6. data/lib/nexmo_markdown_renderer/filters/code_snippet/binding.rb +41 -0
  7. data/lib/nexmo_markdown_renderer/filters/code_snippet/create_application.rb +61 -0
  8. data/lib/nexmo_markdown_renderer/filters/code_snippet/import_dependencies.rb +38 -0
  9. data/lib/nexmo_markdown_renderer/filters/code_snippet/initialize_dependencies.rb +41 -0
  10. data/lib/nexmo_markdown_renderer/filters/code_snippet/install_dependencies.rb +38 -0
  11. data/lib/nexmo_markdown_renderer/filters/code_snippet/instructions.rb +46 -0
  12. data/lib/nexmo_markdown_renderer/filters/code_snippet/renderable.rb +62 -0
  13. data/lib/nexmo_markdown_renderer/filters/code_snippet/run.rb +29 -0
  14. data/lib/nexmo_markdown_renderer/filters/code_snippet_filter.rb +22 -159
  15. data/lib/nexmo_markdown_renderer/filters/concerns/prism_code_snippet.rb +22 -0
  16. data/lib/nexmo_markdown_renderer/filters/markdown_filter.rb +13 -10
  17. data/lib/nexmo_markdown_renderer/filters/partial_filter.rb +1 -1
  18. data/lib/nexmo_markdown_renderer/filters/screenshot_filter.rb +1 -1
  19. data/lib/nexmo_markdown_renderer/filters/tab_filter.rb +73 -70
  20. data/lib/nexmo_markdown_renderer/filters/utils.rb +50 -0
  21. data/lib/nexmo_markdown_renderer/models/code_language.rb +1 -1
  22. data/lib/nexmo_markdown_renderer/models/tutorial.rb +116 -72
  23. data/lib/nexmo_markdown_renderer/models/tutorial/file_loader.rb +32 -0
  24. data/lib/nexmo_markdown_renderer/models/tutorial/metadata.rb +57 -0
  25. data/lib/nexmo_markdown_renderer/models/tutorial/prerequisite.rb +35 -0
  26. data/lib/nexmo_markdown_renderer/models/tutorial/task.rb +49 -0
  27. data/lib/nexmo_markdown_renderer/models/use_case.rb +3 -16
  28. data/lib/nexmo_markdown_renderer/services/doc_finder.rb +7 -2
  29. data/lib/nexmo_markdown_renderer/views/code_snippets/_application_rtc.html.erb +1 -1
  30. data/lib/nexmo_markdown_renderer/views/code_snippets/_application_voice.html.erb +1 -1
  31. data/lib/nexmo_markdown_renderer/views/code_snippets/_configure_client.html.erb +2 -2
  32. data/lib/nexmo_markdown_renderer/views/code_snippets/_import_dependencies.html.erb +18 -0
  33. data/lib/version.rb +1 -1
  34. metadata +17 -2
@@ -0,0 +1,29 @@
1
+ module Nexmo
2
+ module Markdown
3
+ module Filters
4
+ module CodeSnippet
5
+ class Run
6
+ include OcticonsHelper
7
+ include Renderable
8
+
9
+ def initialize(config, snippet)
10
+ @config = config
11
+ @snippet = snippet
12
+ end
13
+
14
+ def run_command
15
+ @run_command ||= begin
16
+ if @config['run_command']
17
+ @config['run_command'].gsub('{filename}', file_name)
18
+ end
19
+ end
20
+ end
21
+
22
+ def render
23
+ renderer.run_command(run_command, file_name, @config['code']['source']).to_s
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -5,183 +5,46 @@ module Nexmo
5
5
 
6
6
  def call(input)
7
7
  input.gsub(/```single_code_snippet(.+?)```/m) do |_s|
8
- config = YAML.safe_load($1)
8
+ @config = YAML.safe_load($1)
9
+ @binding = ::Nexmo::Markdown::Filters::CodeSnippet::Binding.new(@config)
9
10
 
10
- @renderer = get_renderer(config['language'])
11
+ return instructions if @config['code_only']
11
12
 
12
- lexer = Nexmo::Markdown::CodeLanguage.find(config['language']).lexer
13
- lang = config['title'].delete('.')
14
-
15
- application_html = generate_application_block(config['application'])
16
-
17
- # Read the client
18
- if config['client']
19
- highlighted_client_source = generate_code_block(config['language'], config['client'], config['unindent'])
20
- end
21
-
22
- # Read the code
23
- highlighted_code_source = generate_code_block(config['language'], config['code'], config['unindent'])
24
-
25
- dependency_html = ''
26
- if config['dependencies']
27
- dependency_html = generate_dependencies(lexer.tag, config['dependencies'])
28
- end
29
-
30
- source_url = generate_source_url(config['code'])
31
-
32
- client_html = ''
33
- if highlighted_client_source
34
- client_url = generate_source_url(config['client'])
35
- id = SecureRandom.hex
36
- create_instructions = @renderer.create_instructions(config['file_name']).render_markdown
37
- erb = File.read("#{GEM_ROOT}/lib/nexmo_markdown_renderer/views/code_snippets/_configure_client.html.erb")
38
- client_html = ERB.new(erb).result(binding)
39
- end
40
-
41
- add_instructions = @renderer.add_instructions(config['file_name']).render_markdown
42
- if config['code_only']
43
- erb = File.read("#{GEM_ROOT}/lib/nexmo_markdown_renderer/views/code_snippets/_code_only.html.erb")
44
- else
45
- erb = File.read("#{GEM_ROOT}/lib/nexmo_markdown_renderer/views/code_snippets/_write_code.html.erb")
46
- end
47
-
48
- code_html = ERB.new(erb).result(binding)
49
-
50
- return code_html if config['code_only']
51
-
52
- config['run_command'] = config['run_command'].gsub('{filename}', config['file_name']) if config['run_command']
53
- run_html = @renderer.run_command(config['run_command'], config['file_name'], config['code']['source']).to_s
13
+ "#{prerequisites}#{instructions}#{run}"
14
+ end
15
+ end
54
16
 
55
- prereqs = (application_html + dependency_html + client_html).strip
17
+ def prerequisites
18
+ @prerequisites ||= begin
19
+ prereqs = [application_html, install_dependencies, import_dependencies, initialize_dependencies].join.strip
56
20
  prereqs = "<h2>#{::I18n.t('.filters.prerequisites')}</h2>#{prereqs}" unless prereqs.empty?
57
- prereqs + code_html + run_html
21
+ prereqs
58
22
  end
59
23
  end
60
24
 
61
- private
62
-
63
- def highlight(source, lexer)
64
- formatter = Rouge::Formatters::HTML.new
65
- formatter.format(lexer.lex(source))
25
+ def application_html
26
+ @application_html ||= ::Nexmo::Markdown::Filters::CodeSnippet::CreateApplication.new(@config['application']).render
66
27
  end
67
28
 
68
- def generate_code_block(language, input, unindent)
69
- filename = "#{Nexmo::Markdown::Config.docs_base_path}/#{input['source']}"
70
- return '' unless input
71
- raise "CodeSnippetFilter - Could not load #{filename} for language #{language}" unless File.exist?(filename)
72
-
73
- code = File.read(filename)
74
- lexer = Nexmo::Markdown::CodeLanguage.find(language).lexer
75
-
76
- total_lines = code.lines.count
77
-
78
- # Minus one since lines are not zero-indexed
79
- from_line = (input['from_line'] || 1) - 1
80
- to_line = (input['to_line'] || total_lines) - 1
81
-
82
- code = code.lines[from_line..to_line].join
83
- code.unindent! if unindent
84
-
85
- highlight(code, lexer)
29
+ def install_dependencies
30
+ @install_dependencies ||= ::Nexmo::Markdown::Filters::CodeSnippet::InstallDependencies.new(@config['dependencies'], @binding).render
86
31
  end
87
32
 
88
- def get_renderer(language)
89
- language = 'dotnet' if language == 'csharp'
90
- case language
91
- when 'curl'
92
- Nexmo::Markdown::CodeSnippetRenderer::Curl
93
- when 'node'
94
- Nexmo::Markdown::CodeSnippetRenderer::Javascript
95
- when 'javascript'
96
- Nexmo::Markdown::CodeSnippetRenderer::Javascript
97
- when 'java'
98
- Nexmo::Markdown::CodeSnippetRenderer::Java
99
- when 'dotnet'
100
- Nexmo::Markdown::CodeSnippetRenderer::Dotnet
101
- when 'python'
102
- Nexmo::Markdown::CodeSnippetRenderer::Python
103
- when 'ruby'
104
- Nexmo::Markdown::CodeSnippetRenderer::Ruby
105
- when 'php'
106
- Nexmo::Markdown::CodeSnippetRenderer::Php
107
- when 'android'
108
- Nexmo::Markdown::CodeSnippetRenderer::Android
109
- when 'kotlin'
110
- Nexmo::Markdown::CodeSnippetRenderer::Kotlin
111
- when 'objective_c'
112
- Nexmo::Markdown::CodeSnippetRenderer::ObjectiveC
113
- when 'swift'
114
- Nexmo::Markdown::CodeSnippetRenderer::Swift
115
- else
116
- raise "Unknown language: #{language}"
117
- end
33
+ def import_dependencies
34
+ @import_dependencies ||= ::Nexmo::Markdown::Filters::CodeSnippet::ImportDependencies.new(@config['import_dependencies'], @binding).render
118
35
  end
119
36
 
120
- def generate_dependencies(language, dependencies)
121
- # The only valid dependency for curl examples is `JWT`
122
- if dependencies.map(&:upcase).include?('JWT')
123
- title = ::I18n.t('filters.generate_your_jwt')
124
- else
125
- title = ::I18n.t('filters.install_dependencies')
126
- end
127
- deps = @renderer.dependencies(dependencies)
128
- id = SecureRandom.hex
129
- erb = File.read("#{GEM_ROOT}/lib/nexmo_markdown_renderer/views/code_snippets/_dependencies.html.erb")
130
- ERB.new(erb).result(binding)
37
+ def initialize_dependencies
38
+ @initialize_dependencies ||= ::Nexmo::Markdown::Filters::CodeSnippet::InitializeDependencies.new(@config['client'], @binding).render
131
39
  end
132
40
 
133
- def generate_application_block(app)
134
- return '' unless app
135
-
136
- base_url = 'http://demo.ngrok.io'
137
- base_url = 'https://example.com' if app['disable_ngrok']
138
-
139
- app['name'] = 'ExampleProject' unless app['name']
140
-
141
- # We should remove this default once we're sure that all Code Snippets
142
- # have a type set e.g audit
143
- app['type'] ||= 'voice'
144
-
145
- if ['voice', 'rtc'].include? app['type']
146
- app['event_url'] = "#{base_url}/webhooks/events" unless app['event_url']
147
- app['answer_url'] = "#{base_url}/webhooks/answer" unless app['answer_url']
148
- erb = File.read("#{GEM_ROOT}/lib/nexmo_markdown_renderer/views/code_snippets/_application_#{app['type']}.html.erb")
149
- elsif ['messages', 'dispatch'].include? app['type']
150
- erb = File.read("#{GEM_ROOT}/lib/nexmo_markdown_renderer/views/code_snippets/_application_messages_dispatch.html.erb")
151
- else
152
- raise "Invalid application type when creating code snippet: '#{app['type']}'"
153
- end
154
-
155
- id = SecureRandom.hex
156
-
157
- ERB.new(erb).result(binding)
41
+ def instructions
42
+ @instructions ||= ::Nexmo::Markdown::Filters::CodeSnippet::Instructions.new(@config, @binding).render
158
43
  end
159
44
 
160
- def generate_source_url(code)
161
- # Source example: .repos/nexmo/nexmo-java-code-snippets/ExampleClass.java
162
- # Direct link on GitHub is in form https://github.com/nexmo/nexmo-java-code-snippets/blob/master/ExampleClass.java
163
- start_section = 'https://github.com'
164
-
165
- # Insert "blob/master" and strip ".repos"
166
- repo_path = '\\0blob/master/'
167
- file_section = code['source'].sub('.repos', '').sub(%r{(-quickstart|-code-snippets|-code-snippets)/}, repo_path)
168
-
169
- # Line highlighting
170
- line_section = ''
171
- if code['from_line']
172
- line_section += "#L#{code['from_line']}"
173
- if code['to_line']
174
- # If we've provided a to_line, use that
175
- line_section += "-L#{code['to_line']}" if code['to_line']
176
- else
177
- # By default we read to the end of the file
178
- line_section += "-L#{File.read(code['source']).lines.count}"
179
- end
180
- end
181
-
182
- start_section + file_section + line_section
45
+ def run
46
+ @run ||= ::Nexmo::Markdown::Filters::CodeSnippet::Run.new(@config, @binding).render
183
47
  end
184
48
  end
185
-
186
49
  end
187
50
  end
@@ -0,0 +1,22 @@
1
+ module Nexmo
2
+ module Markdown
3
+ module Concerns
4
+ module PrismCodeSnippet
5
+ def code_snippet_body(lexer, body)
6
+ <<~HEREDOC
7
+ <pre class="#{prism_css_classes(lexer)}"><code>#{body}</code></pre>
8
+ HEREDOC
9
+ end
10
+
11
+ def code_language_to_prism(code_language)
12
+ code_language == 'objective_c' && 'objectivec' || code_language
13
+ end
14
+
15
+ def prism_css_classes(lexer)
16
+ code_language = code_language_to_prism(lexer.tag)
17
+ "main-code Vlt-prism--dark language-#{code_language} Vlt-prism--copy-disabled"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,16 +1,17 @@
1
1
  module Nexmo
2
2
  module Markdown
3
3
  class MarkdownFilter < Banzai::Filter
4
+
4
5
  def call(input)
5
6
  markdown.render(input)
6
7
  end
7
-
8
+
8
9
  private
9
-
10
+
10
11
  def renderer
11
12
  @renderer ||= VoltaRender.new(options)
12
13
  end
13
-
14
+
14
15
  def markdown
15
16
  @markdown ||= Redcarpet::Markdown.new(renderer, {
16
17
  no_intra_emphasis: true,
@@ -27,17 +28,19 @@ module Nexmo
27
28
  end
28
29
 
29
30
  class VoltaRender < HTML
31
+ include Nexmo::Markdown::Concerns::PrismCodeSnippet
32
+
30
33
  def initialize(options)
31
34
  @options = options
32
35
  super(options)
33
36
  end
34
-
37
+
35
38
  def paragraph(text)
36
39
  return text if @options[:skip_paragraph_surround]
37
-
40
+
38
41
  "<p>#{text}</p>"
39
42
  end
40
-
43
+
41
44
  def table(header, body)
42
45
  '<div class="Vlt-table Vlt-table--bordered">' \
43
46
  '<table>' \
@@ -46,7 +49,7 @@ module Nexmo
46
49
  '</table>' \
47
50
  '</div>'
48
51
  end
49
-
52
+
50
53
  def block_quote(quote)
51
54
  '<div class="Vlt-callout Vlt-callout--tip">' \
52
55
  '<i></i>' \
@@ -55,7 +58,7 @@ module Nexmo
55
58
  '</div>' \
56
59
  '</div>'
57
60
  end
58
-
61
+
59
62
  def image(link, _title, _alt_text)
60
63
  '<figure>' \
61
64
  '<img src="'\
@@ -63,7 +66,7 @@ module Nexmo
63
66
  '" alt="#{alt_text}">' \
64
67
  '</figure>'
65
68
  end
66
-
69
+
67
70
  def list(contents, list_type)
68
71
  if "#{list_type}" == 'unordered'
69
72
  '<ul class="Vlt-list Vlt-list--simple">' \
@@ -86,7 +89,7 @@ module Nexmo
86
89
  code.gsub! /^ /, "\t"
87
90
  end
88
91
 
89
- formatter = ::Rouge::Formatters::HTMLLegacy.new(:css_class => "Vlt-prism--dark language-#{lexer.tag} Vlt-prism--copy-disabled")
92
+ formatter = ::Rouge::Formatters::HTMLLegacy.new(:css_class => prism_css_classes(lexer))
90
93
  formatter.format(lexer.lex(code))
91
94
  end
92
95
  end
@@ -5,7 +5,7 @@ module Nexmo
5
5
  input.gsub(/```partial(.+?)```/m) do |_s|
6
6
  config = YAML.safe_load($1)
7
7
  file_path = if config['source'].starts_with? 'app/views'
8
- config['source']
8
+ "#{Rails.root}/#{config['source']}"
9
9
  else
10
10
  "#{Nexmo::Markdown::Config.docs_base_path}/#{config['source']}"
11
11
  end
@@ -4,7 +4,7 @@ module Nexmo
4
4
  def call(input)
5
5
  input.gsub(/```screenshot(.+?)```/m) do |_s|
6
6
  config = YAML.safe_load($1)
7
- if config['image'] && File.file?(config['image'])
7
+ if config['image'] && File.file?("#{Nexmo::Markdown::Config.docs_base_path}/#{config['image']}")
8
8
  "![Screenshot](#{config['image'].gsub('public', '')})"
9
9
  else
10
10
  <<~HEREDOC
@@ -1,16 +1,18 @@
1
1
  module Nexmo
2
2
  module Markdown
3
3
  class TabFilter < Banzai::Filter
4
+ include Nexmo::Markdown::Concerns::PrismCodeSnippet
5
+
4
6
  def call(input)
5
7
  input.gsub(/^(\s*)```tabbed_(examples|content|folder)(.+?)```/m) do |_s|
6
8
  @indentation = $1
7
9
  @mode = $2
8
10
  @config = YAML.safe_load($3)
9
-
11
+
10
12
  if tabbed_folder?
11
- raise "#{@config['source']} is not a directory" unless File.directory? "#{Nexmo::Markdown::Config.docs_base_path}/#{@config['source']}"
12
-
13
- @tabbed_config = YAML.safe_load(File.read("#{Nexmo::Markdown::Config.docs_base_path}/#{@config['source']}/.config.yml"))
13
+ raise "#{@config['source']} is not a directory" unless File.directory? "#{@config['source']}"
14
+
15
+ @tabbed_config = YAML.safe_load(File.read("#{@config['source']}/.config.yml"))
14
16
  @path = @config['source']
15
17
  validate_folder_config
16
18
  else
@@ -19,28 +21,28 @@ module Nexmo
19
21
  html
20
22
  end
21
23
  end
22
-
24
+
23
25
  private
24
-
26
+
25
27
  def create_tabs(content)
26
28
  tab = Nokogiri::XML::Element.new 'div', @document
27
29
  tab['class'] = 'Vlt-tabs__link'
28
30
  tab['class'] += ' Vlt-tabs__link_active' if content[:active]
29
31
  tab['role'] = 'tab'
30
-
32
+
31
33
  if content[:language]
32
34
  tab['data-language'] = content[:language].key
33
35
  tab['data-language-type'] = content[:language].type
34
36
  tab['data-language-linkable'] = content[:language].linkable?
35
37
  end
36
-
38
+
37
39
  if content[:platform]
38
40
  tab['data-language'] = content[:platform].languages.map(&:key).join(',')
39
41
  tab['data-platform'] = content[:platform].key
40
42
  tab['data-platform-type'] = content[:platform].type
41
43
  tab['data-platform-linkable'] = content[:platform].linkable?
42
44
  end
43
-
45
+
44
46
  tab_link = Nokogiri::XML::Element.new 'span', @document
45
47
  if content[:language]
46
48
  # We don't currently have icons for JSON/XML
@@ -48,6 +50,8 @@ module Nexmo
48
50
  tab_link.content = content[:tab_title]
49
51
  elsif content[:language].key == 'objective_c' || content[:language].key == 'swift'
50
52
  tab_link.inner_html = "<svg><use xlink:href=\"/assets/images/brands/ios.svg#ios\" /></svg><span>" + content[:tab_title] + '</span>'
53
+ elsif content[:language].key == 'kotlin'
54
+ tab_link.inner_html = "<img class=\"Vlt-icon Vlt-icon--small\" src=\"/assets/images/brands/kotlin.svg#kotlin\" /><span>" + content[:tab_title] + '</span>'
51
55
  else
52
56
  tab_link.inner_html = "<svg><use xlink:href=\"/assets/images/brands/#{content[:language].key}.svg##{content[:language].key}\" /></svg><span>" + content[:tab_title] + '</span>'
53
57
  end
@@ -56,37 +60,37 @@ module Nexmo
56
60
  else
57
61
  tab_link.content = content[:tab_title]
58
62
  end
59
-
63
+
60
64
  tab.add_child(tab_link)
61
65
  @tabs.add_child(tab)
62
66
  end
63
-
67
+
64
68
  def create_content(content)
65
69
  tabs_panel = Nokogiri::XML::Element.new 'div', @document
66
70
  tabs_panel['class'] = 'Vlt-tabs__panel'
67
71
  tabs_panel['class'] += ' Vlt-tabs__panel_active' if content[:active]
68
-
72
+
69
73
  element = Nokogiri::XML::Element.new 'p', @document
70
74
  element['aria-labelledby'] = "\"#{content[:id]}\""
71
75
  element['aria-hidden'] = true
72
76
  element.inner_html = content[:body]
73
-
77
+
74
78
  tabs_panel.add_child(element)
75
79
  @tabs_content.add_child(tabs_panel)
76
80
  end
77
-
81
+
78
82
  def tabbed_code_examples?
79
83
  @mode == 'examples'
80
84
  end
81
-
85
+
82
86
  def tabbed_content?
83
87
  @mode == 'content'
84
88
  end
85
-
89
+
86
90
  def tabbed_folder?
87
91
  @mode == 'folder'
88
92
  end
89
-
93
+
90
94
  def html
91
95
  html = <<~HEREDOC
92
96
  <div class="Vlt-tabs">
@@ -95,97 +99,97 @@ module Nexmo
95
99
  </div>
96
100
  </div>
97
101
  HEREDOC
98
-
102
+
99
103
  @document = Nokogiri::HTML::DocumentFragment.parse(html)
100
104
  @tabs = @document.at_css('.Vlt-tabs__header')
101
105
  @tabs_content = @document.at_css('.Vlt-tabs__content')
102
-
106
+
103
107
  contents.each do |content|
104
108
  create_tabs(content)
105
109
  create_content(content)
106
110
  end
107
-
111
+
108
112
  source = @document.to_html
109
-
113
+
110
114
  "#{@indentation}FREEZESTART#{Base64.urlsafe_encode64(source)}FREEZEEND"
111
115
  end
112
-
116
+
113
117
  def contents
114
118
  list = content_from_folder if tabbed_folder?
115
119
  list ||= content_from_source if @config['source']
116
120
  list ||= content_from_tabs if @config['tabs']
117
-
121
+
118
122
  list ||= []
119
-
123
+
120
124
  return list unless list.any?
121
-
125
+
122
126
  list = resolve_language(list)
123
-
127
+
124
128
  if tabbed_code_examples?
125
129
  list = format_code(list)
126
130
  list = resolve_code(list)
127
131
  list = resolve_tab_title(list)
128
132
  end
129
-
133
+
130
134
  list = sort_contents(list)
131
135
  resolve_active_tab(list)
132
-
136
+
133
137
  list
134
138
  end
135
-
139
+
136
140
  def validate_config
137
141
  return if @config && (@config['source'] || @config['tabs'])
138
-
142
+
139
143
  raise 'Source or tabs must be present in this tabbed_example config'
140
144
  end
141
-
145
+
142
146
  def validate_folder_config
143
147
  return if @tabbed_config && @tabbed_config['tabbed'] == true
144
-
148
+
145
149
  raise 'Tabbed must be set to true in the folder config YAML file'
146
150
  end
147
-
151
+
148
152
  def content_from_source
149
153
  source_path = "#{Nexmo::Markdown::Config.docs_base_path}/#{@config['source']}"
150
154
  source_path += '/*' if tabbed_code_examples?
151
155
  source_path += '/*.md' if tabbed_content?
152
-
156
+
153
157
  files = Dir.glob(source_path)
154
158
  raise "Empty content_from_source file list in #{source_path}" if files.empty?
155
-
159
+
156
160
  files.map do |content_path|
157
161
  raise "Could not find content_from_source file: #{content_path}" unless File.exist? content_path
158
-
162
+
159
163
  source = File.read(content_path)
160
-
164
+
161
165
  next generate_tabbed_code_examples(source, content_path) if tabbed_code_examples?
162
-
166
+
163
167
  generate_tabbed_content(source) if tabbed_content?
164
168
  end
165
169
  end
166
-
170
+
167
171
  def content_from_folder
168
- source_path = "#{Nexmo::Markdown::Config.docs_base_path}/#{@config['source']}"
172
+ source_path = "#{@config['source']}"
169
173
  source_path += '/*.md'
170
-
174
+
171
175
  files = Dir.glob(source_path)
172
176
  raise "Empty content_from_source file list in #{source_path}" if files.empty?
173
-
177
+
174
178
  files.map do |content_path|
175
179
  raise "Could not find content_from_source file: #{content_path}" unless File.exist? content_path
176
-
180
+
177
181
  source = File.read(content_path)
178
-
182
+
179
183
  generate_tabbed_content(source)
180
184
  end
181
185
  end
182
-
186
+
183
187
  def content_from_tabs
184
188
  @config['tabs'].map do |title, config|
185
189
  raise "Could not find content_from_tabs file: #{Nexmo::Markdown::Config.docs_base_path}/#{@config['source']}" unless File.exist? "#{Nexmo::Markdown::Config.docs_base_path}/#{@config['source']}"
186
-
190
+
187
191
  source = File.read("#{Nexmo::Markdown::Config.docs_base_path}/#{@config['source']}")
188
-
192
+
189
193
  config.symbolize_keys.merge({
190
194
  id: SecureRandom.hex,
191
195
  source: source,
@@ -193,22 +197,22 @@ module Nexmo
193
197
  })
194
198
  end
195
199
  end
196
-
200
+
197
201
  def generate_tabbed_content(source)
198
202
  content = {
199
203
  id: SecureRandom.hex,
200
204
  source: source,
201
205
  }
202
-
206
+
203
207
  content[:frontmatter] = YAML.safe_load(source)
204
208
  content[:language_key] = content[:frontmatter]['language']
205
209
  content[:platform_key] = content[:frontmatter]['platform']
206
210
  content[:tab_title] = content[:frontmatter]['title']
207
211
  content[:body] = Nexmo::Markdown::Renderer.new(options).call(source)
208
-
212
+
209
213
  content
210
214
  end
211
-
215
+
212
216
  def generate_tabbed_code_examples(source, content_path)
213
217
  content = {
214
218
  id: SecureRandom.hex,
@@ -216,24 +220,24 @@ module Nexmo
216
220
  }
217
221
  language_key = File.basename(content_path, '.*').downcase
218
222
  content[:language_key] = language_key
219
-
223
+
220
224
  content
221
225
  end
222
-
226
+
223
227
  def resolve_language(contents)
224
228
  contents.map do |content|
225
229
  if content[:language_key]
226
230
  content[:language] = CodeLanguage.find(content[:language_key])
227
231
  end
228
-
232
+
229
233
  if content[:platform_key]
230
234
  content[:platform] = CodeLanguage.find(content[:platform_key])
231
235
  end
232
-
236
+
233
237
  content
234
238
  end
235
239
  end
236
-
240
+
237
241
  def format_code(contents)
238
242
  contents.each do |content|
239
243
  if content[:from_line] || content[:to_line]
@@ -243,43 +247,42 @@ module Nexmo
243
247
  to_line = (content[:to_line] || total_lines) - 1
244
248
  content[:source] = lines[from_line..to_line].join
245
249
  end
246
-
250
+
247
251
  content[:source].unindent! if content[:unindent]
248
252
  end
249
253
  end
250
-
254
+
251
255
  def resolve_code(contents)
252
256
  contents.map do |content|
253
257
  @formatter ||= Rouge::Formatters::HTML.new
254
258
  lexer = content[:language].lexer
255
259
  highlighted_source = @formatter.format(lexer.lex(content[:source]))
256
- body = <<~HEREDOC
257
- <pre class="Vlt-prism--dark language-#{lexer.tag} Vlt-prism--copy-disabled"><code>#{highlighted_source}</code></pre>
258
- HEREDOC
259
-
260
+
261
+ body = code_snippet_body(lexer, highlighted_source)
262
+
260
263
  content.merge!({ body: body })
261
264
  end
262
265
  end
263
-
266
+
264
267
  def resolve_tab_title(contents)
265
268
  contents.map do |content|
266
269
  content.merge!({ tab_title: content[:language].label })
267
270
  end
268
271
  end
269
-
272
+
270
273
  def sort_contents(contents)
271
274
  contents.sort_by do |content|
272
275
  next content[:language].weight if content[:language]
273
-
276
+
274
277
  next content[:frontmatter]['menu_weight'] || 999 if content[:frontmatter]
275
-
278
+
276
279
  999
277
280
  end
278
281
  end
279
-
282
+
280
283
  def resolve_active_tab(contents)
281
284
  active_index = nil
282
-
285
+
283
286
  if options[:code_language]
284
287
  contents.each_with_index do |content, index|
285
288
  %i[language_key platform_key].each do |key|
@@ -287,10 +290,10 @@ module Nexmo
287
290
  end
288
291
  end
289
292
  end
290
-
293
+
291
294
  @tabs['data-has-initial-tab'] = active_index.present?
292
295
  active_index ||= 0
293
-
296
+
294
297
  contents[active_index][:active] = true
295
298
  end
296
299
  end