nexmo_markdown_renderer 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61beb60888700c64e9a5840c98ebc4d7ce06de47e5f1d8385c6a85f675d2d5f6
4
- data.tar.gz: bc5037d6894fb0b33c8aa56d0a4325d954757d925775133bab16dde6ac0f044f
3
+ metadata.gz: fe1875b3974959e1290b19d8e480b455fa5259b78567b607a4b66b86634ccfad
4
+ data.tar.gz: 9e33c425c055ef2b52ac3e9abf70c596bcf86ad92f0f8ea4f69ea7732f3001ed
5
5
  SHA512:
6
- metadata.gz: 43a9a7d862fe6d7bb7aef8c2b2b77c863f5bfd985f8c8ab80954a12c7cfcb8a490dccc69baecfd55593c7ca80887f2a5d345482e29edc0067192b8b55c6243b9
7
- data.tar.gz: 3b8e9f3becb2f3ffe7d54a48f7400df6f48efd85a1da6578d130051de18962b3a4aba3d3f0210f9fc693e9970adf298461a72e69e5eecac7748e752634bb72e8
6
+ metadata.gz: 25002e68f5f4db9e9de3d9360a82b3d93c4de70e56a00bdffa6e09ed89a0967a115c50f5b13cd875cfc386c66bbc359b15d5d191619be4f0f3420d250c04786c
7
+ data.tar.gz: c2b6fc824c865d72f523e50a56b74647393bb8fb98fe9e63f96d48435867511eeb141f6d856ac47c6eae2d8661fdbbeb5d53d557dab5307c5a5525da775291b2
@@ -0,0 +1,32 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class Tutorial::FileLoader
4
+ attr_reader :root, :code_language, :doc_name, :format
5
+
6
+ def initialize(root:, code_language:, doc_name:, format: 'yml')
7
+ @root = root
8
+ @code_language = code_language
9
+ @doc_name = doc_name
10
+ @format = format
11
+ end
12
+
13
+ def path
14
+ @path ||= Nexmo::Markdown::DocFinder.find(
15
+ root: root,
16
+ document: doc_name,
17
+ language: ::I18n.locale,
18
+ code_language: code_language,
19
+ format: format
20
+ ).path
21
+ end
22
+
23
+ def content
24
+ @content ||= File.read(path)
25
+ end
26
+
27
+ def yaml
28
+ @yaml ||= YAML.safe_load(content)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,57 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class Tutorial::Metadata
4
+ attr_reader :name, :file_loader
5
+ delegate :path, :yaml, to: :file_loader
6
+
7
+ def initialize(name:)
8
+ @name = name
9
+ @file_loader = load_file!
10
+ end
11
+
12
+ def products
13
+ @products ||= yaml['products'] || []
14
+ end
15
+
16
+ def title
17
+ @title ||= yaml['title']
18
+ end
19
+
20
+ def description
21
+ @description ||= yaml['description']
22
+ end
23
+
24
+ def external_link
25
+ @external_link ||= yaml['external_link']
26
+ end
27
+
28
+ def available_code_languages
29
+ @available_code_languages ||= begin
30
+ DocFinder
31
+ .code_languages_for_tutorial(path: path.sub('.yml', '/'))
32
+ .map { |file_path| File.basename(Pathname.new(file_path).basename, '.yml') }
33
+ .sort_by { |l| CodeLanguage.find(l).weight }
34
+ end
35
+ end
36
+
37
+ def code_language
38
+ @code_language ||= begin
39
+ available_code_languages
40
+ .min_by { |k| CodeLanguage.languages.map(&:key).index(k) }
41
+ end
42
+ end
43
+
44
+ def default_product
45
+ @default_product ||= products.first
46
+ end
47
+
48
+ def load_file!
49
+ Tutorial::FileLoader.new(
50
+ root: Tutorial.tutorials_path,
51
+ code_language: nil,
52
+ doc_name: @name
53
+ )
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,35 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class Tutorial::Prerequisite
4
+ delegate :content, :yaml, to: :@file_loader
5
+
6
+ def initialize(current_step:, code_language:, name:)
7
+ @current_step = current_step
8
+ @code_language = code_language
9
+ @name = name
10
+ @file_loader = load_file!
11
+ end
12
+
13
+ def title
14
+ @title ||= yaml['title']
15
+ end
16
+
17
+ def description
18
+ @description ||= yaml['description']
19
+ end
20
+
21
+ def active?
22
+ @name == @current_step
23
+ end
24
+
25
+ def load_file!
26
+ Tutorial::FileLoader.new(
27
+ root: Tutorial.task_content_path,
28
+ code_language: nil,
29
+ doc_name: @name,
30
+ format: 'md'
31
+ )
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,49 @@
1
+ module Nexmo
2
+ module Markdown
3
+ class Tutorial::Task
4
+ attr_reader :name, :title, :description, :current_step
5
+
6
+ def initialize(name:, title:, description:, current_step:)
7
+ @name = name
8
+ @title = title
9
+ @description = description
10
+ @current_step = current_step
11
+ end
12
+
13
+ def active?
14
+ @name == @current_step
15
+ end
16
+
17
+ def self.make_from(name:, code_language:, current_step:)
18
+ file_loader = Tutorial::FileLoader.new(
19
+ root: Tutorial.task_content_path,
20
+ doc_name: name,
21
+ code_language: code_language,
22
+ format: 'md'
23
+ )
24
+
25
+ new(
26
+ name: name,
27
+ title: file_loader.yaml['title'],
28
+ description: file_loader.yaml['description'],
29
+ current_step: current_step
30
+ )
31
+ end
32
+
33
+ def ==(other)
34
+ name == other.name &&
35
+ title == other.title &&
36
+ description == other.description &&
37
+ current_step == other.current_step
38
+ end
39
+
40
+ def eql?(other)
41
+ self == other
42
+ end
43
+
44
+ def hash
45
+ name.hash ^ title.hash ^ description.hash ^ current_step.hash
46
+ end
47
+ end
48
+ end
49
+ end
@@ -2,68 +2,109 @@ module Nexmo
2
2
  module Markdown
3
3
  class Tutorial
4
4
  include ActiveModel::Model
5
- attr_accessor :raw, :name, :current_step, :current_product, :title, :description, :products, :subtasks, :prerequisites
5
+
6
+ attr_reader :name, :current_step
7
+ delegate :path, :yaml, to: :@file_loader
8
+ delegate :available_code_languages, to: :metadata
9
+
10
+ def initialize(name:, current_step:, current_product: nil, code_language: nil)
11
+ @name = name
12
+ @current_step = current_step
13
+ @product = current_product
14
+ @language = code_language
15
+ @file_loader = load_file!
16
+ end
17
+
18
+ def metadata
19
+ @metadata ||= Metadata.new(name: name)
20
+ end
21
+
22
+ def current_product
23
+ @current_product ||= @product || metadata.default_product
24
+ end
25
+
26
+ def code_language
27
+ @code_language ||= @language || metadata.code_language
28
+ end
29
+
30
+ def title
31
+ @title ||= yaml['title'] || metadata.title
32
+ end
33
+
34
+ def description
35
+ @description ||= yaml['description'] || metadata.description
36
+ end
37
+
38
+ def products
39
+ @products ||= yaml['products'] || metadata.products
40
+ end
41
+
42
+ def prerequisites
43
+ @prerequisites ||= (yaml['prerequisites'] || []).map do |prereq|
44
+ Prerequisite.new(name: prereq, code_language: code_language, current_step: current_step)
45
+ end
46
+ end
6
47
 
7
48
  def content_for(step_name)
8
49
  if ['introduction', 'conclusion'].include? step_name
9
- raise "Invalid step: #{step_name}" unless raw[step_name]
50
+ raise "Invalid step: #{step_name}" unless yaml[step_name]
10
51
 
11
- return raw[step_name]['content']
52
+ return yaml[step_name]['content']
12
53
  end
13
54
 
14
55
  path = Nexmo::Markdown::DocFinder.find(
15
56
  root: self.class.task_content_path,
16
57
  document: step_name,
17
- language: ::I18n.locale
58
+ language: ::I18n.locale,
59
+ code_language: code_language
18
60
  ).path
19
61
 
20
62
  File.read(path)
21
63
  end
22
64
 
23
65
  def first_step
24
- subtasks.first['path']
66
+ subtasks.first.name
25
67
  end
26
68
 
27
69
  def prerequisite?
28
- prerequisites.pluck('path').include?(@current_step)
70
+ prerequisites.map(&:name).include?(@current_step)
29
71
  end
30
72
 
31
73
  def next_step
32
- current_task_index = subtasks.pluck('path').index(@current_step)
74
+ current_task_index = subtasks.map(&:name).index(@current_step)
33
75
  return nil unless current_task_index
34
76
 
35
77
  subtasks[current_task_index + 1]
36
78
  end
37
79
 
38
80
  def previous_step
39
- current_task_index = subtasks.pluck('path').index(@current_step)
81
+ current_task_index = subtasks.map(&:name).index(@current_step)
40
82
  return nil unless current_task_index
41
83
  return nil if current_task_index <= 0
42
84
 
43
85
  subtasks[current_task_index - 1]
44
86
  end
45
87
 
46
- def self.load(name, current_step, current_product = nil)
47
- document_path = Nexmo::Markdown::DocFinder.find(
48
- root: 'config/tutorials',
49
- document: name,
50
- language: ::I18n.default_locale,
51
- format: 'yml'
52
- ).path
53
- config = YAML.safe_load(File.read(document_path))
54
- current_product ||= config['products'].first
55
-
56
- new({
57
- raw: config,
58
- name: name,
59
- current_step: current_step,
60
- current_product: current_product,
61
- title: config['title'],
62
- description: config['description'],
63
- products: config['products'],
64
- prerequisites: load_prerequisites(config['prerequisites'], current_step),
65
- subtasks: load_subtasks(config['introduction'], config['prerequisites'], config['tasks'], config['conclusion'], current_step),
66
- })
88
+ def subtasks
89
+ @subtasks ||= begin
90
+ tasks = []
91
+
92
+ (yaml['tasks'] || []).map do |t|
93
+ tasks.push(
94
+ Task.make_from(
95
+ name: t,
96
+ code_language: code_language,
97
+ current_step: current_step
98
+ )
99
+ )
100
+ end
101
+
102
+ tasks.unshift(prerequisite_task)
103
+ tasks.unshift(introduction_task)
104
+ tasks.push(conclusion_task)
105
+
106
+ tasks.compact
107
+ end
67
108
  end
68
109
 
69
110
  def self.load_prerequisites(prerequisites, current_step)
@@ -89,60 +130,63 @@ module Nexmo
89
130
  end
90
131
  end
91
132
 
92
- def self.load_subtasks(introduction, prerequisites, tasks, conclusion, current_step)
93
- tasks ||= []
133
+ def prerequisite_task
134
+ return if prerequisites.empty?
94
135
 
95
- tasks = tasks.map do |t|
96
- t_path = Nexmo::Markdown::DocFinder.find(
97
- root: task_content_path,
98
- document: t,
99
- language: ::I18n.locale
100
- ).path
101
- raise "Subtask not found: #{t}" unless File.exist? t_path
136
+ Task.new(
137
+ name: 'prerequisites',
138
+ title: 'Prerequisites',
139
+ description: 'Everything you need to complete this task',
140
+ current_step: current_step
141
+ )
142
+ end
102
143
 
103
- subtask_config = YAML.safe_load(File.read(t_path))
104
- {
105
- 'path' => t,
106
- 'title' => subtask_config['title'],
107
- 'description' => subtask_config['description'],
108
- 'is_active' => t == current_step,
109
- }
110
- end
144
+ def introduction_task
145
+ return unless yaml['introduction']
111
146
 
112
- if prerequisites
113
- tasks.unshift({
114
- 'path' => 'prerequisites',
115
- 'title' => 'Prerequisites',
116
- 'description' => 'Everything you need to complete this task',
117
- 'is_active' => current_step == 'prerequisites',
118
- })
119
- end
147
+ Task.new(
148
+ name: 'introduction',
149
+ title: yaml['introduction']['title'],
150
+ description: yaml['introduction']['description'],
151
+ current_step: current_step
152
+ )
153
+ end
120
154
 
121
- if introduction
122
- tasks.unshift({
123
- 'path' => 'introduction',
124
- 'title' => introduction['title'],
125
- 'description' => introduction['description'],
126
- 'is_active' => current_step == 'introduction',
127
- })
128
- end
155
+ def conclusion_task
156
+ return unless yaml['conclusion']
129
157
 
130
- if conclusion
131
- tasks.push({
132
- 'path' => 'conclusion',
133
- 'title' => conclusion['title'],
134
- 'description' => conclusion['description'],
135
- 'is_active' => current_step == 'conclusion',
136
- })
137
- end
158
+ Task.new(
159
+ name: 'conclusion',
160
+ title: yaml['conclusion']['title'],
161
+ description: yaml['conclusion']['description'],
162
+ current_step: current_step
163
+ )
164
+ end
165
+
166
+ def self.load(name, current_step, current_product = nil, code_language = nil)
167
+ new(
168
+ name: name,
169
+ current_step: current_step,
170
+ current_product: current_product,
171
+ code_language: code_language
172
+ )
173
+ end
138
174
 
139
- tasks
175
+ def load_file!
176
+ Tutorial::FileLoader.new(
177
+ root: self.class.tutorials_path,
178
+ code_language: code_language,
179
+ doc_name: name
180
+ )
140
181
  end
141
182
 
142
183
  def self.task_content_path
143
184
  "#{Nexmo::Markdown::Config.docs_base_path}/_tutorials"
144
185
  end
145
- end
146
186
 
187
+ def self.tutorials_path
188
+ 'config/tutorials'
189
+ end
190
+ end
147
191
  end
148
192
  end
@@ -20,23 +20,12 @@ module Nexmo
20
20
 
21
21
  def subtitle
22
22
  normalized_products = products.map do |product|
23
- normalise_product_title(product)
23
+ Product.normalize_title(product)
24
24
  end
25
25
 
26
26
  normalized_products.sort.to_sentence
27
27
  end
28
28
 
29
- def normalise_product_title(product)
30
- return 'SMS' if product == 'messaging/sms'
31
- return 'Voice' if product == 'voice/voice-api'
32
- return 'Number Insight' if product == 'number-insight'
33
- return 'Messages' if product == 'messages'
34
- return 'Dispatch' if product == 'dispatch'
35
- return 'Client SDK' if product == 'client-sdk'
36
- return 'Subaccounts' if product == 'account/subaccounts'
37
- product.camelcase
38
- end
39
-
40
29
  def self.by_product(product, use_cases = [])
41
30
  use_cases = all if use_cases.empty?
42
31
  use_cases.select do |use_case|
@@ -63,7 +52,7 @@ module Nexmo
63
52
  document = File.read(document_path)
64
53
  frontmatter = YAML.safe_load(document)
65
54
 
66
- Nexmo::Markdown::UseCase.new({
55
+ new({
67
56
  title: frontmatter['title'],
68
57
  description: frontmatter['description'],
69
58
  external_link: frontmatter['external_link'],
@@ -75,8 +64,6 @@ module Nexmo
75
64
  end
76
65
  end
77
66
 
78
- private
79
-
80
67
  private_class_method def self.files
81
68
  Dir.glob("#{origin}/**/*.md")
82
69
  end
@@ -120,6 +120,11 @@ module Nexmo
120
120
  def self.strip_root_and_language(root:, language:, document:)
121
121
  document.sub(%r{#{root}\/}, '').sub(%r{#{language}\/}, '')
122
122
  end
123
+
124
+ def self.code_languages_for_tutorial(path:)
125
+ key = strip_root_and_language(root: '/', document: path, language: ::I18n.default_locale)
126
+ dictionary.keys.select { |k| k.include?(key) }
127
+ end
123
128
  end
124
129
  end
125
130
  end
@@ -6,10 +6,12 @@ require 'nokogiri'
6
6
  require 'open-uri'
7
7
  require 'active_model'
8
8
  require 'i18n'
9
+
9
10
  require_relative 'nexmo_markdown_renderer/config/load_config'
10
11
  require_relative 'nexmo_markdown_renderer/initializers/redcarpet'
11
12
  require_relative 'nexmo_markdown_renderer/initializers/i18n'
12
13
  require_relative 'nexmo_markdown_renderer/core_ext/string'
14
+
13
15
  require_relative 'nexmo_markdown_renderer/services/code_snippet_renderer/base'
14
16
  require_relative 'nexmo_markdown_renderer/services/code_snippet_renderer/android'
15
17
  require_relative 'nexmo_markdown_renderer/services/code_snippet_renderer/curl'
@@ -22,9 +24,20 @@ require_relative 'nexmo_markdown_renderer/services/code_snippet_renderer/php'
22
24
  require_relative 'nexmo_markdown_renderer/services/code_snippet_renderer/python'
23
25
  require_relative 'nexmo_markdown_renderer/services/code_snippet_renderer/ruby'
24
26
  require_relative 'nexmo_markdown_renderer/services/code_snippet_renderer/swift'
27
+
25
28
  require_relative 'nexmo_markdown_renderer/services/doc_finder'
26
29
  require_relative 'nexmo_markdown_renderer/services/doc_finder/doc'
27
- Dir[File.join(__dir__, 'nexmo_markdown_renderer/models', '*.rb')].each { |file| require_relative file }
30
+
31
+ require_relative 'nexmo_markdown_renderer/models/code_language'
32
+ require_relative 'nexmo_markdown_renderer/models/code_snippet'
33
+ require_relative 'nexmo_markdown_renderer/models/concept'
34
+ require_relative 'nexmo_markdown_renderer/models/tutorial'
35
+ require_relative 'nexmo_markdown_renderer/models/tutorial/file_loader'
36
+ require_relative 'nexmo_markdown_renderer/models/tutorial/metadata'
37
+ require_relative 'nexmo_markdown_renderer/models/tutorial/prerequisite'
38
+ require_relative 'nexmo_markdown_renderer/models/tutorial/task'
39
+ require_relative 'nexmo_markdown_renderer/models/use_case'
40
+
28
41
  Dir[File.join(__dir__, 'nexmo_markdown_renderer/filters', '*.rb')].each { |file| require_relative file }
29
42
  Dir[File.join(__dir__, 'nexmo_markdown_renderer/filters/i18n', '*.rb')].each { |file| require_relative file }
30
43
  require_relative 'nexmo_markdown_renderer/markdown_renderer'
data/lib/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # :nocov:
2
2
  module Nexmo
3
3
  module Markdown
4
- VERSION = '0.2.2'
4
+ VERSION = '0.3.0'
5
5
  end
6
6
  end
7
7
  # :nocov:
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexmo_markdown_renderer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nexmo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-06 00:00:00.000000000 Z
11
+ date: 2020-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: banzai
@@ -278,6 +278,10 @@ files:
278
278
  - lib/nexmo_markdown_renderer/models/code_snippet.rb
279
279
  - lib/nexmo_markdown_renderer/models/concept.rb
280
280
  - lib/nexmo_markdown_renderer/models/tutorial.rb
281
+ - lib/nexmo_markdown_renderer/models/tutorial/file_loader.rb
282
+ - lib/nexmo_markdown_renderer/models/tutorial/metadata.rb
283
+ - lib/nexmo_markdown_renderer/models/tutorial/prerequisite.rb
284
+ - lib/nexmo_markdown_renderer/models/tutorial/task.rb
281
285
  - lib/nexmo_markdown_renderer/models/use_case.rb
282
286
  - lib/nexmo_markdown_renderer/services/code_snippet_renderer/android.rb
283
287
  - lib/nexmo_markdown_renderer/services/code_snippet_renderer/base.rb