nexmo-oas-renderer 0.1.0

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 (158) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +1 -0
  3. data/.gitignore +5 -0
  4. data/CHANGELOG.md +2 -0
  5. data/CONTRIBUTING.md +46 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +183 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +73 -0
  10. data/Rakefile +2 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/exe/nexmo-oas-renderer +5 -0
  14. data/lib/nexmo/oas/engine.rb +9 -0
  15. data/lib/nexmo/oas/renderer.rb +13 -0
  16. data/lib/nexmo/oas/renderer/app.rb +116 -0
  17. data/lib/nexmo/oas/renderer/config.ru +7 -0
  18. data/lib/nexmo/oas/renderer/config/code_languages.yml +138 -0
  19. data/lib/nexmo/oas/renderer/config/dynamic_content.yml +1 -0
  20. data/lib/nexmo/oas/renderer/config/redirects.yml +8 -0
  21. data/lib/nexmo/oas/renderer/constraints/open_api.rb +76 -0
  22. data/lib/nexmo/oas/renderer/constraints/redirector.rb +17 -0
  23. data/lib/nexmo/oas/renderer/decorators/response_parser_decorator.rb +55 -0
  24. data/lib/nexmo/oas/renderer/filters/anchor.rb +17 -0
  25. data/lib/nexmo/oas/renderer/filters/audio.rb +21 -0
  26. data/lib/nexmo/oas/renderer/filters/block_escape.rb +24 -0
  27. data/lib/nexmo/oas/renderer/filters/break.rb +13 -0
  28. data/lib/nexmo/oas/renderer/filters/code.rb +64 -0
  29. data/lib/nexmo/oas/renderer/filters/code_snippet.rb +194 -0
  30. data/lib/nexmo/oas/renderer/filters/code_snippet_list.rb +33 -0
  31. data/lib/nexmo/oas/renderer/filters/code_snippets.rb +158 -0
  32. data/lib/nexmo/oas/renderer/filters/collapsible.rb +27 -0
  33. data/lib/nexmo/oas/renderer/filters/columns.rb +50 -0
  34. data/lib/nexmo/oas/renderer/filters/concept_list.rb +33 -0
  35. data/lib/nexmo/oas/renderer/filters/dynamic_content.rb +30 -0
  36. data/lib/nexmo/oas/renderer/filters/external_link.rb +32 -0
  37. data/lib/nexmo/oas/renderer/filters/frontmatter.rb +14 -0
  38. data/lib/nexmo/oas/renderer/filters/heading.rb +61 -0
  39. data/lib/nexmo/oas/renderer/filters/icon.rb +22 -0
  40. data/lib/nexmo/oas/renderer/filters/indent.rb +20 -0
  41. data/lib/nexmo/oas/renderer/filters/inline_escape.rb +17 -0
  42. data/lib/nexmo/oas/renderer/filters/js_sequence_diagram.rb +21 -0
  43. data/lib/nexmo/oas/renderer/filters/label.rb +32 -0
  44. data/lib/nexmo/oas/renderer/filters/language.rb +15 -0
  45. data/lib/nexmo/oas/renderer/filters/markdown.rb +85 -0
  46. data/lib/nexmo/oas/renderer/filters/modal.rb +41 -0
  47. data/lib/nexmo/oas/renderer/filters/partial.rb +28 -0
  48. data/lib/nexmo/oas/renderer/filters/php_inliner.rb +15 -0
  49. data/lib/nexmo/oas/renderer/filters/screenshot.rb +26 -0
  50. data/lib/nexmo/oas/renderer/filters/tab.rb +250 -0
  51. data/lib/nexmo/oas/renderer/filters/techio.rb +24 -0
  52. data/lib/nexmo/oas/renderer/filters/tooltip.rb +22 -0
  53. data/lib/nexmo/oas/renderer/filters/tutorial_link.rb +27 -0
  54. data/lib/nexmo/oas/renderer/filters/tutorials.rb +28 -0
  55. data/lib/nexmo/oas/renderer/filters/unfreeze.rb +20 -0
  56. data/lib/nexmo/oas/renderer/filters/user_personalization.rb +43 -0
  57. data/lib/nexmo/oas/renderer/helpers/navigation.rb +66 -0
  58. data/lib/nexmo/oas/renderer/helpers/render.rb +24 -0
  59. data/lib/nexmo/oas/renderer/helpers/summary.rb +30 -0
  60. data/lib/nexmo/oas/renderer/helpers/url.rb +17 -0
  61. data/lib/nexmo/oas/renderer/lib/core_ext/string.rb +14 -0
  62. data/lib/nexmo/oas/renderer/lib/redcarpet.rb +14 -0
  63. data/lib/nexmo/oas/renderer/models/code_snippet.rb +75 -0
  64. data/lib/nexmo/oas/renderer/models/tutorial.rb +83 -0
  65. data/lib/nexmo/oas/renderer/pipelines/markdown_pipeline.rb +52 -0
  66. data/lib/nexmo/oas/renderer/presenters/api_specification.rb +42 -0
  67. data/lib/nexmo/oas/renderer/presenters/groups.rb +35 -0
  68. data/lib/nexmo/oas/renderer/presenters/navigation.rb +24 -0
  69. data/lib/nexmo/oas/renderer/presenters/open_api_specification.rb +68 -0
  70. data/lib/nexmo/oas/renderer/presenters/versions.rb +40 -0
  71. data/lib/nexmo/oas/renderer/public/assets/fonts/Lato-Black.woff +0 -0
  72. data/lib/nexmo/oas/renderer/public/assets/fonts/Lato-Black.woff2 +0 -0
  73. data/lib/nexmo/oas/renderer/public/assets/fonts/Lato-Heavy.woff +0 -0
  74. data/lib/nexmo/oas/renderer/public/assets/fonts/Lato-Heavy.woff2 +0 -0
  75. data/lib/nexmo/oas/renderer/public/assets/fonts/Lato-Regular.woff +0 -0
  76. data/lib/nexmo/oas/renderer/public/assets/fonts/Lato-Regular.woff2 +0 -0
  77. data/lib/nexmo/oas/renderer/public/assets/fonts/Lato-Semibold.woff +0 -0
  78. data/lib/nexmo/oas/renderer/public/assets/fonts/Lato-Semibold.woff2 +0 -0
  79. data/lib/nexmo/oas/renderer/public/assets/images/brands/android.svg +1 -0
  80. data/lib/nexmo/oas/renderer/public/assets/images/brands/curl.svg +1 -0
  81. data/lib/nexmo/oas/renderer/public/assets/images/brands/dotnet.svg +1 -0
  82. data/lib/nexmo/oas/renderer/public/assets/images/brands/ios.svg +1 -0
  83. data/lib/nexmo/oas/renderer/public/assets/images/brands/java.svg +1 -0
  84. data/lib/nexmo/oas/renderer/public/assets/images/brands/javascript.svg +1 -0
  85. data/lib/nexmo/oas/renderer/public/assets/images/brands/node.svg +1 -0
  86. data/lib/nexmo/oas/renderer/public/assets/images/brands/php.svg +1 -0
  87. data/lib/nexmo/oas/renderer/public/assets/images/brands/python.svg +11 -0
  88. data/lib/nexmo/oas/renderer/public/assets/images/brands/ruby.svg +1 -0
  89. data/lib/nexmo/oas/renderer/public/assets/images/lost.svg +37 -0
  90. data/lib/nexmo/oas/renderer/public/assets/javascripts/components/format.js +42 -0
  91. data/lib/nexmo/oas/renderer/public/assets/javascripts/volta.accordion.js +249 -0
  92. data/lib/nexmo/oas/renderer/public/assets/javascripts/volta.core.js +230 -0
  93. data/lib/nexmo/oas/renderer/public/assets/javascripts/volta.modal.js +300 -0
  94. data/lib/nexmo/oas/renderer/public/assets/javascripts/volta.tabs.js +139 -0
  95. data/lib/nexmo/oas/renderer/public/assets/stylesheets/api.css +95 -0
  96. data/lib/nexmo/oas/renderer/public/assets/stylesheets/buttons.css +80 -0
  97. data/lib/nexmo/oas/renderer/public/assets/stylesheets/core.css +79 -0
  98. data/lib/nexmo/oas/renderer/public/assets/stylesheets/mediaqueries.css +2 -0
  99. data/lib/nexmo/oas/renderer/public/assets/stylesheets/mediaqueries.css.map +7 -0
  100. data/lib/nexmo/oas/renderer/public/assets/stylesheets/navigation.css +79 -0
  101. data/lib/nexmo/oas/renderer/public/assets/stylesheets/nexmo.css +68 -0
  102. data/lib/nexmo/oas/renderer/public/assets/stylesheets/sass/api.scss +147 -0
  103. data/lib/nexmo/oas/renderer/public/assets/stylesheets/sass/core.scss +133 -0
  104. data/lib/nexmo/oas/renderer/public/assets/stylesheets/sass/mediaqueries.scss +48 -0
  105. data/lib/nexmo/oas/renderer/public/assets/stylesheets/sass/navigation.scss +106 -0
  106. data/lib/nexmo/oas/renderer/public/assets/stylesheets/sass/nexmo.scss +61 -0
  107. data/lib/nexmo/oas/renderer/public/assets/stylesheets/sass/style.scss +10 -0
  108. data/lib/nexmo/oas/renderer/public/assets/stylesheets/sass/syntax.scss +63 -0
  109. data/lib/nexmo/oas/renderer/public/assets/stylesheets/sass/typography.scss +248 -0
  110. data/lib/nexmo/oas/renderer/public/assets/stylesheets/sass/variables.scss +91 -0
  111. data/lib/nexmo/oas/renderer/public/assets/stylesheets/sass/volta-templates.scss +119 -0
  112. data/lib/nexmo/oas/renderer/public/assets/stylesheets/style.css +2 -0
  113. data/lib/nexmo/oas/renderer/public/assets/stylesheets/style.css.map +7 -0
  114. data/lib/nexmo/oas/renderer/public/assets/stylesheets/syntax.css +79 -0
  115. data/lib/nexmo/oas/renderer/public/assets/stylesheets/typography.css +86 -0
  116. data/lib/nexmo/oas/renderer/public/assets/stylesheets/variables.css +2 -0
  117. data/lib/nexmo/oas/renderer/public/assets/stylesheets/variables.css.map +7 -0
  118. data/lib/nexmo/oas/renderer/public/assets/stylesheets/volta-templates.css +2 -0
  119. data/lib/nexmo/oas/renderer/public/assets/stylesheets/volta-templates.css.map +7 -0
  120. data/lib/nexmo/oas/renderer/public/assets/stylesheets/volta.min.css +1 -0
  121. data/lib/nexmo/oas/renderer/public/assets/symbol/volta-icons.svg +1 -0
  122. data/lib/nexmo/oas/renderer/public/favicon.ico +0 -0
  123. data/lib/nexmo/oas/renderer/services/code_language_api.rb +98 -0
  124. data/lib/nexmo/oas/renderer/services/oas_parser.rb +21 -0
  125. data/lib/nexmo/oas/renderer/services/open_api_definition_resolver.rb +33 -0
  126. data/lib/nexmo/oas/renderer/version.rb +7 -0
  127. data/lib/nexmo/oas/renderer/views/api/show.erb +1 -0
  128. data/lib/nexmo/oas/renderer/views/code_snippets/_application_messages_dispatch.html.erb +9 -0
  129. data/lib/nexmo/oas/renderer/views/code_snippets/_application_rtc.html.erb +41 -0
  130. data/lib/nexmo/oas/renderer/views/code_snippets/_application_voice.html.erb +24 -0
  131. data/lib/nexmo/oas/renderer/views/code_snippets/_code_only.html.erb +6 -0
  132. data/lib/nexmo/oas/renderer/views/code_snippets/_configure_client.html.erb +20 -0
  133. data/lib/nexmo/oas/renderer/views/code_snippets/_dependencies.html.erb +11 -0
  134. data/lib/nexmo/oas/renderer/views/code_snippets/_write_code.html.erb +13 -0
  135. data/lib/nexmo/oas/renderer/views/code_snippets/list/plain.html.erb +10 -0
  136. data/lib/nexmo/oas/renderer/views/concepts/list/plain.html.erb +5 -0
  137. data/lib/nexmo/oas/renderer/views/layouts/_head.erb +4 -0
  138. data/lib/nexmo/oas/renderer/views/layouts/_javascripts.erb +9 -0
  139. data/lib/nexmo/oas/renderer/views/layouts/api.erb +23 -0
  140. data/lib/nexmo/oas/renderer/views/layouts/open_api.erb +10 -0
  141. data/lib/nexmo/oas/renderer/views/open_api/_callback.erb +5 -0
  142. data/lib/nexmo/oas/renderer/views/open_api/_callback_endpoint.erb +48 -0
  143. data/lib/nexmo/oas/renderer/views/open_api/_code_examples.erb +16 -0
  144. data/lib/nexmo/oas/renderer/views/open_api/_endpoint.erb +156 -0
  145. data/lib/nexmo/oas/renderer/views/open_api/_model.erb +38 -0
  146. data/lib/nexmo/oas/renderer/views/open_api/_navigation.erb +80 -0
  147. data/lib/nexmo/oas/renderer/views/open_api/_parameter_groups.erb +50 -0
  148. data/lib/nexmo/oas/renderer/views/open_api/_parameters.erb +165 -0
  149. data/lib/nexmo/oas/renderer/views/open_api/_response_description_parameters.erb +61 -0
  150. data/lib/nexmo/oas/renderer/views/open_api/_response_descriptions.erb +41 -0
  151. data/lib/nexmo/oas/renderer/views/open_api/show.erb +104 -0
  152. data/lib/nexmo/oas/renderer/views/static/404.erb +6 -0
  153. data/lib/nexmo/oas/renderer/views/tutorials/_index.html.erb +32 -0
  154. data/lib/nexmo/oas/renderer/views/tutorials/index.html.erb +7 -0
  155. data/lib/nexmo/oas/renderer/views/tutorials/list/plain.html.erb +5 -0
  156. data/lib/nexmo/oas/renderer/views/tutorials/show.html.erb +8 -0
  157. data/nexmo-oas-renderer.gemspec +49 -0
  158. metadata +399 -0
@@ -0,0 +1,66 @@
1
+ module Nexmo
2
+ module OAS
3
+ module Renderer
4
+ module Helpers
5
+ module Navigation
6
+
7
+ HEADING_TAG_DEPTHS = {
8
+ 'h0' => 0,
9
+ 'h1' => 1,
10
+ 'h2' => 2,
11
+ 'h3' => 3,
12
+ 'h4' => 4,
13
+ 'h5' => 5,
14
+ 'h6' => 6,
15
+ }.freeze
16
+
17
+ def navigation_from_content(content:, title: nil)
18
+ content = "<h0 class='injected'>#{title}</h0>\n" + content if title
19
+ document = build_document(content)
20
+
21
+ nodes = ['<ul class="Vlt-sidemenu Vlt-sidemenu--rounded Vlt-sidemenu--flat navigation js-navigation">']
22
+ last_node = nil
23
+
24
+ document.css('.reveal').remove
25
+
26
+ document.css('h0,h2,h3,h4,h5,h6').each do |heading|
27
+ # If it's a header within tabbed content (including Code Snippets) we don't want to treat
28
+ # the header as a navigation item in the sidebar
29
+ next unless heading.ancestors('.Vlt-tabs').empty?
30
+
31
+ # Same with callouts
32
+ next unless heading.ancestors('.Vlt-callout').empty?
33
+
34
+ if last_node.nil? || heading.name == last_node.name
35
+ # Do nothing (cleaner than adding wrapping further conditions)
36
+ elsif heading.name >= last_node.name # e.g. h2 -> h3
37
+ nodes << '<ul>'
38
+ else # e.g. h4 -> h2
39
+ (HEADING_TAG_DEPTHS[last_node.name] - HEADING_TAG_DEPTHS[heading.name]).times do
40
+ nodes << '</li></ul>'
41
+ end
42
+ end
43
+
44
+ nodes << <<~HEREDOC
45
+ <li>
46
+ <a class="Vlt-sidemenu__link" href="##{heading.attributes['id']}" data-scrollspy-id="#{heading['data-id']}">
47
+ #{heading.text}
48
+ </a>
49
+ HEREDOC
50
+ last_node = heading
51
+ end
52
+ nodes << '</li></ul>'
53
+ nodes.join("\n").html_safe
54
+ end
55
+
56
+ private
57
+
58
+ def build_document(content)
59
+ Nokogiri::HTML::DocumentFragment.parse(content)
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,24 @@
1
+ module Nexmo
2
+ module OAS
3
+ module Renderer
4
+ module Helpers
5
+ module Render
6
+
7
+ def find_template(views, name, engine, &block)
8
+ Array(views).each do |v|
9
+ super(v, name, engine, &block)
10
+ end
11
+ end
12
+
13
+ def render(*args)
14
+ if args.length > 2
15
+ super
16
+ else
17
+ ApplicationController.renderer.render(*args)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ module Nexmo
2
+ module OAS
3
+ module Renderer
4
+ module Helpers
5
+ module Summary
6
+ def normalize_summary_title(summary, operation_id)
7
+ # return summary early if provided
8
+ return summary unless summary.nil?
9
+
10
+ # If the operation ID is camelCase,
11
+ if operation_id.match?(/^[a-zA-Z]\w+(?:[A-Z]\w+){1,}/x)
12
+ # Use the rails `.underscore` method to convert someString to some_string
13
+ operation_id = operation_id.underscore
14
+ end
15
+
16
+ # Replace snake_case and kebab-case with spaces and titelize the string
17
+ operation_id = operation_id.gsub(/(_|-)/, ' ').titleize
18
+
19
+ # Some terms need to be capitalised all the time
20
+ uppercase_array = ['SMS', 'DTMF']
21
+ operation_id.split(' ').map do |c|
22
+ next c.upcase if uppercase_array.include?(c.upcase)
23
+ c
24
+ end.join(' ')
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ module Nexmo
2
+ module OAS
3
+ module Renderer
4
+ module Helpers
5
+ module URL
6
+ def parameter_values(enum)
7
+ enum.map { |value| "<code>#{value}</code>" }.to_sentence(last_word_connector: ' or ', two_words_connector: ' or ')
8
+ end
9
+
10
+ def canonical_path
11
+ request.path.chomp("/#{params[:code_language]}")
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ class String
2
+ def render_markdown(options = {})
3
+ Nexmo::OAS::Renderer::MarkdownPipeline.new(options).call(self).html_safe
4
+ end
5
+
6
+ def unindent
7
+ indent = squeeze("\n").lines.map { |line| line.index(/[^\s]/) }.compact.min || 0
8
+ gsub(/^[[:blank:]]{#{indent}}/, '')
9
+ end
10
+
11
+ def unindent!
12
+ replace(unindent)
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'redcarpet'
2
+ require 'rouge'
3
+ require 'rouge/plugins/redcarpet'
4
+
5
+
6
+ module Nexmo
7
+ module OAS
8
+ module Renderer
9
+ class HTML < Redcarpet::Render::HTML
10
+ include Rouge::Plugins::Redcarpet
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,75 @@
1
+ module Nexmo
2
+ module OAS
3
+ module Renderer
4
+ module Models
5
+ class CodeSnippet
6
+ include ActiveModel::Model
7
+ attr_accessor :title, :product, :category, :navigation_weight, :document_path, :url
8
+
9
+ def self.by_product(product)
10
+ all.select do |block|
11
+ block.product == product
12
+ end
13
+ end
14
+
15
+ def self.all
16
+ blocks = files.map do |document_path|
17
+ document = File.read(document_path)
18
+ product = extract_product(document_path)
19
+
20
+ frontmatter = YAML.safe_load(document)
21
+
22
+ new({
23
+ title: frontmatter['title'],
24
+ navigation_weight: frontmatter['navigation_weight'] || 999,
25
+ product: product,
26
+ document_path: document_path,
27
+ category: extract_category(document_path),
28
+ url: generate_url(document_path),
29
+ })
30
+ end
31
+
32
+ blocks.sort_by(&:navigation_weight)
33
+ end
34
+
35
+ def self.generate_url(path)
36
+ '/' + path.gsub("#{origin}/", '').gsub('.md', '')
37
+ end
38
+
39
+ def self.extract_product(path)
40
+ # Remove the prefix
41
+ path = path.gsub!("#{origin}/", '')
42
+
43
+ # Each file is in the form code-snippets/<title>.md, so let's remove everything after code-snippets
44
+ path = path.gsub(%r{/code-snippets/.*}, '')
45
+
46
+ path
47
+ end
48
+
49
+ def self.extract_category(path)
50
+ # Remove the prefix
51
+ path = path.gsub("#{origin}/", '')
52
+
53
+ # Each file is in the form code-snippets/<title>.md, so let's capture everything after code-snippets
54
+ path = path.gsub(%r{.*/code-snippets/(.*)$}, '\1')
55
+
56
+ parts = path.split('/')
57
+ parts = parts[0...-1]
58
+
59
+ return nil if parts.empty?
60
+
61
+ parts.join('/').tr('-', ' ').humanize
62
+ end
63
+
64
+ def self.files
65
+ Dir.glob("#{origin}/**/code-snippets/**/*.md")
66
+ end
67
+
68
+ def self.origin
69
+ "_documentation"
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,83 @@
1
+ module Nexmo
2
+ module OAS
3
+ module Renderer
4
+ module Models
5
+ class Tutorial
6
+
7
+ include ActiveModel::Model
8
+ attr_accessor :title, :description, :external_link, :products, :document_path, :languages
9
+
10
+ def body
11
+ File.read(document_path)
12
+ end
13
+
14
+ def path
15
+ return external_link if external_link
16
+ "/tutorials/#{document_path.relative_path_from(self.class.origin)}".gsub('.md', '')
17
+ end
18
+
19
+ def subtitle
20
+ normalized_products = products.map do |product|
21
+ normalise_product_title(product)
22
+ end
23
+
24
+ normalized_products.sort.to_sentence
25
+ end
26
+
27
+ def normalise_product_title(product)
28
+ return 'SMS' if product == 'messaging/sms'
29
+ return 'Voice' if product == 'voice/voice-api'
30
+ return 'Number Insight' if product == 'number-insight'
31
+ return 'Messages' if product == 'messages'
32
+ return 'Dispatch' if product == 'dispatch'
33
+ return 'Client SDK' if product == 'client-sdk'
34
+ product.camelcase
35
+ end
36
+
37
+ def self.by_product(product, tutorials = [])
38
+ tutorials = all if tutorials.empty?
39
+ tutorials.select do |tutorial|
40
+ tutorial.products.include? product
41
+ end
42
+ end
43
+
44
+ def self.by_language(language, tutorials = [])
45
+ language = language.downcase
46
+ tutorials = all if tutorials.empty?
47
+
48
+ tutorials.select do |tutorial|
49
+ tutorial.languages.map(&:downcase).include? language
50
+ end
51
+ end
52
+
53
+ def self.origin
54
+ Pathname.new("_tutorials")
55
+ end
56
+
57
+ def self.all
58
+ files.map do |document_path|
59
+ document_path = Pathname.new(document_path)
60
+ document = File.read(document_path)
61
+ frontmatter = YAML.safe_load(document)
62
+
63
+ new({
64
+ title: frontmatter['title'],
65
+ description: frontmatter['description'],
66
+ external_link: frontmatter['external_link'],
67
+ products: frontmatter['products'].split(',').map(&:strip),
68
+ languages: frontmatter['languages'] || [],
69
+ document_path: document_path,
70
+ })
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ private_class_method def self.files
77
+ Dir.glob("#{origin}/**/*.md")
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,52 @@
1
+ require 'banzai'
2
+
3
+ Dir[File.join(__dir__, '../filters', '*.rb')].each { |f| require_relative f }
4
+
5
+ module Nexmo
6
+ module OAS
7
+ module Renderer
8
+ class MarkdownPipeline < Banzai::Pipeline
9
+ def initialize(options = {})
10
+ super(
11
+ # As Markdown
12
+ Filters::Frontmatter,
13
+ Filters::PHPInliner,
14
+ Filters::InlineEscape,
15
+ Filters::BlockEscape,
16
+ Filters::Screenshot,
17
+ Filters::Anchor,
18
+ Filters::Audio,
19
+ Filters::DynamicContent,
20
+ Filters::Tooltip,
21
+ Filters::Collapsible,
22
+ Filters::Tab.new(options),
23
+ Filters::CodeSnippets.new(options),
24
+ Filters::CodeSnippet.new(options),
25
+ Filters::Code,
26
+ Filters::Indent,
27
+ Filters::Modal,
28
+ Filters::JsSequenceDiagram,
29
+ Filters::Partial.new(options),
30
+ Filters::Techio,
31
+ Filters::Tutorials,
32
+ Filters::CodeSnippetList,
33
+ Filters::ConceptList,
34
+ Filters::Language,
35
+ Filters::Columns,
36
+ Filters::Markdown.new(options),
37
+
38
+ # As HTML
39
+ Filters::UserPersonalization.new(options),
40
+ Filters::Heading,
41
+ Filters::Label.new(options),
42
+ Filters::Break,
43
+ Filters::Unfreeze,
44
+ Filters::Icon,
45
+ Filters::ExternalLink,
46
+ Filters::TutorialLink
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,42 @@
1
+ module Nexmo
2
+ module OAS
3
+ module Renderer
4
+ module Presenters
5
+ class ApiSpecification
6
+
7
+ def initialize(document_name:)
8
+ @document_name = document_name
9
+ end
10
+
11
+ def side_navigation
12
+ "api/#{@document_name}"
13
+ end
14
+
15
+ def document_path
16
+ "_api/#{@document_name}.md"
17
+ end
18
+
19
+ def document
20
+ @document ||= File.read(document_path)
21
+ end
22
+
23
+ def frontmatter
24
+ @frontmatter ||= YAML.safe_load(document)
25
+ end
26
+
27
+ def side_navigation_title
28
+ @side_navigation_title ||= frontmatter.fetch('api')
29
+ end
30
+
31
+ def document_title
32
+ @document_title ||= "#{side_navigation_title} > #{frontmatter.fetch('title')}"
33
+ end
34
+
35
+ def content
36
+ @content ||= MarkdownPipeline.new.call(document)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,35 @@
1
+ module Nexmo
2
+ module OAS
3
+ module Renderer
4
+ module Presenters
5
+ class Groups
6
+ def initialize(definition)
7
+ @definition = definition
8
+ end
9
+
10
+ def groups
11
+ tags = @definition.raw['tags']
12
+ # For now we only use the first tag in the list as an equivalent for the old x-group functionality
13
+ @groups = @definition.endpoints.group_by do |endpoint|
14
+ next nil unless tags
15
+ endpoint.raw['tags']&.first
16
+ end
17
+
18
+ # We want to use the order in which the tags are defined in the definition, so iterate over the tags
19
+ # and store the index against the tag name. We'll use this later for sorting
20
+ ordering = {}
21
+ tags&.each_with_index do |tag, index|
22
+ ordering[tag['name'].capitalize] = index
23
+ end
24
+
25
+ # Sort by the order in which they're defined in the definition
26
+ @groups = @groups.sort_by do |name, _|
27
+ next -1 if name.nil?
28
+ ordering[name.capitalize] || 999
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end