nexmo_markdown_renderer 0.2.1 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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