rsg_doc 0.0.2

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c09f5aafe9ecd80c48b7e2486e1d5e7a0a26322a
4
+ data.tar.gz: ab508931966bda51b4ab86d6a0c4d4c0febdf740
5
+ SHA512:
6
+ metadata.gz: 3da3339def91f42811c669a23b5142b08179f3e6288d66c6c9e6605f4ad40622d8971e81740c53c46e2ca3a9bd29670edfe24df1f8d4dc367d9b64857d1f6967
7
+ data.tar.gz: 9e62cdbda81736723f4e9dc44c6b15aa54b4c2eda3e87677b98a876b649dcfd989886c920874d7413a6ba0168400545f75032c1366b0ced466e44955841d155c
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ .byebug_history
data/LICENSE.txt ADDED
@@ -0,0 +1,14 @@
1
+ Copyright 2017 REDspace.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
14
+
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # Roku SceneGraph/BrightScript Documentation Generator
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rsg_doc.svg)](https://badge.fury.io/rb/rsg_doc)
4
+
5
+ A tool to generate documentation for Brightscript referenced in Scenegraph XML.
6
+
7
+ ## Installation
8
+
9
+ $ gem install rsg_doc
10
+
11
+ ## Usage
12
+
13
+ From within the root directory for a project:
14
+
15
+ $ rsg
16
+
17
+ ### Result
18
+
19
+ The generator targets Scenegraph xml files and parses Brightscript associated through the use of script tags.
20
+
21
+ <script type="text/brightscript" uri="pkg:/somebrightscript.brs"></script>'
22
+ A docs folder is created containing same directory structure as the project with .brs.html and .xml.html files located where the source would be.
23
+
24
+ For information on how the html files are generated check out the [Standard](#standard).
25
+
26
+ ## Contributing
27
+
28
+ 1. Fork it
29
+ 2. Create your feature branch (`git checkout -b feature/my-new-feature`)
30
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
31
+ 4. Push to the branch (`git push origin feature/my-new-feature`)
32
+ 5. Create a new Pull Request
33
+
34
+ ## Standard
35
+
36
+
37
+
38
+ ### Function Comment Structure
39
+
40
+ Comments on functions need to be in two blocks separated by an empty commented line:
41
+ * **Description block**<br>
42
+ A section for an explanation of the sub/function. Multiple lines will be stitched together to form a single description.
43
+ <br><br>
44
+ * **Tag block**<br>
45
+ A section where tags can be used to effect how content is rendered.
46
+
47
+ ### Available Tags
48
+
49
+ * **@deprecated** :_description_:<br>
50
+ * **@param** :_attribute_name_: :_description_:
51
+ * **@return** :_description_:
52
+ * **@since** :_version_:
53
+
54
+ Example:
55
+ ```BrightScript
56
+ ' Description block: any commented lines prior to an empty line
57
+ ' the is part of the description
58
+ ' this is also part of the description but the line below is not
59
+ '
60
+ ' @deprecated Removed in 0.0.2 in favor of new function
61
+ ' @param params contains information useful to this function
62
+ ' @param anotherArg a string used for something
63
+ ' @return 0 if successful, error code if not
64
+ ' @since version 0.0.1
65
+ function myFunction(params as Object, anotherArg as String) as Int
66
+ ...
67
+ end function
68
+ ```
data/bin/rsg ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ #********** Copyright 2017 REDspace. All Rights Reserved. **********
3
+
4
+ require "rsg_doc"
5
+ require "byebug"
6
+
7
+ Docgen.new(root_dir: Dir.pwd()).generate
data/lib/rsg_doc.rb ADDED
@@ -0,0 +1,11 @@
1
+ #********** Copyright 2017 REDspace. All Rights Reserved. **********
2
+
3
+ require 'fileutils'
4
+
5
+ # require the document generator
6
+ require 'rsg_doc/docgen.rb'
7
+
8
+ module RSGDoc
9
+ # Version for the roku scenegraph document generator
10
+ VERSION = "0.0.2"
11
+ end
@@ -0,0 +1,243 @@
1
+ #********** Copyright 2017 REDspace. All Rights Reserved. **********
2
+
3
+ require 'erb'
4
+
5
+ # Generate Brightscript documentation
6
+ class Docgen
7
+
8
+ # Set the root directory
9
+ def initialize(root_dir: nil)
10
+ @ROOT_DIR = root_dir
11
+ @BRS_DOC_REF = "https://sdkdocs.roku.com/display/sdkdoc/"
12
+ FileUtils.cd(@ROOT_DIR)
13
+ FileUtils.mkdir_p 'docs', :mode => 0755
14
+ # Grab the document root
15
+ @doc_dir = File.join(@ROOT_DIR, "docs")
16
+ end
17
+
18
+ # Generate html files for xml files and brs included via script tags
19
+ def generate
20
+ Dir.glob(File.join(@ROOT_DIR, "**", "*.xml")).each do |file|
21
+ FileUtils.mkdir_p File.join(@doc_dir, File.dirname(file).split(@ROOT_DIR)[1]), :mode => 0755
22
+ parsexml(file)
23
+ end
24
+ end
25
+
26
+ # Look through the xml file and generate an html file with appropriate information
27
+ def parsexml(filename)
28
+ scripts = Array.new
29
+ # Initialize the hash containing xml.html information
30
+ xml_html_content = Hash.new
31
+ xml_html_content[:fields] = Array.new
32
+ xml_html_content[:brsfiles] = Array.new
33
+ xml_html_content[:functionalfields] = Array.new
34
+
35
+ # Iterate through lines in the file
36
+ File.open(filename).each do |line|
37
+ # Look for component name and optionally the extended class
38
+ temp_component = /<component name="(?<name>[^"]*)" (extends="(?<extendedClass>[^"]*)")?.*>/.match(line)
39
+ if (temp_component)
40
+ xml_html_content[:componentName] = temp_component['name']
41
+ xml_html_content[:componentExtendedClass] = temp_component['extendedClass']
42
+ next
43
+ end
44
+ # Look for referenced brightscript files
45
+ tempScript = /<script.*uri="pkg:(?<uri>[^"]*)".*>/.match(line)
46
+ if (tempScript)
47
+ scripts.push( tempScript )
48
+ next
49
+ end
50
+ # Look for fields on the inferface
51
+ tempField = /<field (id="(?<id>[^"]*)") (type="(?<type>[^"]*)").*>/.match(line)
52
+ if (tempField)
53
+ xml_html_content[:fields].push({
54
+ :id => tempField['id'],
55
+ :type => tempField['type']
56
+ })
57
+ next
58
+ end
59
+ # Look for functional fields on the interface
60
+ tempFuncField = /<function (name="(?<name>[^"]*)").*>/.match(line)
61
+ if (tempFuncField)
62
+ xml_html_content[:functionalfields].push({
63
+ :name => tempFuncField['name']
64
+ })
65
+ end
66
+ # End looping through file
67
+ end
68
+
69
+ # Define the variable for the portion of the path after the root and before pkg:
70
+ # Needs to be changes in order to account for relative paths
71
+ packageDoc = nil
72
+
73
+ # Parse the brightscript
74
+ scripts.each do |script|
75
+
76
+ packageDoc = File.dirname(filename.split(@ROOT_DIR)[1]).split(File.dirname(script['uri']))[0]
77
+ xml_html_content[:brsfiles].push({
78
+ :path => File.join(@doc_dir, packageDoc, File.path(script['uri'])),
79
+ :name => File.basename(script['uri'])
80
+ })
81
+
82
+ brs_doc_contents = parsebrs( script['uri'], packageDoc, filename )
83
+ # Pair up the functional field with the corresponding script
84
+ xml_html_content[:functionalfields].each do |function|
85
+ if brs_doc_contents[:content][:functions].empty?
86
+ puts "Warn: Uncommented functional field located in #{brs_doc_contents[:ref]}"
87
+ else
88
+ brs_doc_contents[:content][:functions].each do |brsfunction|
89
+ if brsfunction[:functionname] == function[:name]
90
+ function.merge!(:file => brs_doc_contents[:file])
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ # Using the .xml.html.erb
98
+ template = ERB.new(File.read(File.join(File.dirname(__FILE__), "docgenTemplates", "docgen.xml.html.erb")))
99
+ # Document the xml file
100
+ xml_file = File.open(
101
+ File.join(
102
+ @doc_dir,
103
+ File.dirname(filename).split(@ROOT_DIR)[1],
104
+ File.basename(filename)
105
+ ) << ".html","w",0755)
106
+ xml_file.write( template.result(binding) )
107
+ xml_file.close
108
+ end
109
+
110
+ # Controls the parsing for the commands
111
+ def parsebrs( script, package, parentxmlfile)
112
+
113
+ # FUTURE: Account for the path being relative, versus using package root
114
+ @ref_brs_script = File.join(@ROOT_DIR, package, script)
115
+
116
+ # html to be written to the documentation
117
+ brs_doc_content = Hash.new
118
+ brs_doc_content[:functions] = Array.new
119
+ brs_doc_content[:name] = File.basename(@ref_brs_script)
120
+
121
+ begin
122
+ lines = IO.readlines(@ref_brs_script)
123
+ rescue Errno::ENOENT
124
+ puts "Warn: BrightScript file not found: #{@ref_brs_script} Referenced from: #{parentxmlfile}"
125
+ return
126
+ else
127
+ # look through the saved lines for comments to parse
128
+ counter = 0;
129
+ until counter > lines.length
130
+ if /^\s*(sub|function)/.match(lines[counter])
131
+ rev_counter = counter - 1
132
+ while rev_counter > 0
133
+ break unless /\s*('|(?i:rem))/.match(lines[rev_counter])
134
+ rev_counter -= 1
135
+ end
136
+ brs_doc_content[:functions].push(
137
+ parseComments(lines.slice(rev_counter+1, counter-rev_counter))
138
+ ) if counter-rev_counter > 1
139
+ end
140
+ counter += 1
141
+ # End of loop per file
142
+ end
143
+
144
+ # Using the .xml.html.erb
145
+ template = ERB.new(File.read(File.join(File.dirname(__FILE__), "docgenTemplates", "docgen.brs.html.erb")))
146
+ # Document brightscript file
147
+ brs_doc_loc = File.join(
148
+ @doc_dir,
149
+ File.dirname(@ref_brs_script).split(@ROOT_DIR)[1],
150
+ File.basename(@ref_brs_script)
151
+ ) << ".html"
152
+ brs_file = File.open(brs_doc_loc, "w", 0755)
153
+ brs_file.write( template.result(binding) )
154
+ brs_file.close
155
+ return {:content => brs_doc_content, :file => brs_doc_loc, :ref => @ref_brs_script }
156
+ end
157
+ end
158
+
159
+ # Find all the comment components when generating the brightscript file
160
+ def parseComments(comments)
161
+ # Last line of the comments will be the function name
162
+ brs_html_content = Hash.new
163
+ brs_html_content[:description] = Array.new
164
+ line_num = 0;
165
+
166
+ # Parse description block
167
+ while line_num < comments.length - 1
168
+ if /('|(?i:rem))\s*$/.match(comments[line_num])
169
+ line_num += 1
170
+ break
171
+ end
172
+ full_comment = /('|(?i:rem))\s*(?<comment>\w.*$)/.match(comments[line_num])
173
+ if not full_comment
174
+ puts "fatal! Bad comment in file #{@ref_brs_script}"
175
+ abort
176
+ else
177
+ brs_html_content[:description].push( parseDescription(full_comment['comment'] ))
178
+ end
179
+ line_num += 1
180
+ end
181
+ brs_html_content[:params] = Array.new
182
+ # Parse the block tags if present
183
+ while line_num < comments.length - 1
184
+ # Look for deprecated tag
185
+ dep_match = /'\s*@deprecated\s*(?<description>.*$)/.match(comments[line_num])
186
+ if dep_match
187
+ brs_html_content[:deprecated] = parseDescription(dep_match['description'])
188
+ line_num += 1
189
+ next
190
+ end
191
+ # Look for param tag
192
+ param_match = /'\s*@param\s*(?<name>\w*)\s*(?<description>\w.*)?/.match(comments[line_num])
193
+ if param_match
194
+ brs_html_content[:params].push({
195
+ :name => param_match['name'],
196
+ :description => parseDescription(param_match['description'])
197
+ })
198
+ line_num += 1
199
+ next
200
+ end
201
+ # Look for since tags
202
+ since_match = /'\s*@since\s*(?<description>\w.*)/.match(comments[line_num])
203
+ if since_match
204
+ brs_html_content[:since] = parseDescription(since_match['description'])
205
+ line_num += 1
206
+ next
207
+ end
208
+ # Look for return tags
209
+ return_match = /'\s*@return\s*(?<description>\w.*$)/.match(comments[line_num])
210
+ if return_match
211
+ brs_html_content[:return] = parseDescription(return_match['description'])
212
+ line_num += 1
213
+ next
214
+ end
215
+ line_num += 1
216
+ end
217
+ # Get the function details (name for now)
218
+ function_info = /^\s*(sub|function)\s(?<name>[^(]*)\((?<inputs>[^)]*)\)\s*(?<returntype>\w.*)?/.match(comments[comments.length-1])
219
+ if function_info
220
+ brs_html_content[:functionname] = function_info['name']
221
+ brs_html_content[:functioninputs] = function_info['inputs']
222
+ end
223
+ return brs_html_content
224
+ end
225
+
226
+ # Handle the description and the inline tags
227
+ def parseDescription(des)
228
+ return des unless inline_match = /^'(.*)(?<inline>{[^}]*})(.*)/.match(des)
229
+
230
+ link_string = ""
231
+ tag_match = /@(?<tag>\w*)\s+(?<component>\w*)\s+(?<link_text>[^}]*)/.match(inline_match['inline'])
232
+ if tag_match
233
+ case tag_match['tag']
234
+ when "link"
235
+ link_string = "<a href=\"#{ File.join(@BRS_DOC_REF,tag_match['component']) }\">#{tag_match['link_text']}</a>"
236
+ return des.split(inline_match['inline']).join(link_string)
237
+ end
238
+ return des
239
+ end
240
+ end
241
+
242
+ # End class
243
+ end
@@ -0,0 +1,32 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+
5
+ </head>
6
+ <body>
7
+ <h1> <%= brs_doc_content[:name] %> </h1>
8
+ <% if brs_doc_content[:functions].length > 0 %>
9
+ <h2> Functions: </h2>
10
+ <% brs_doc_content[:functions].each do |function| %>
11
+ <% if function[:deprecated] %>
12
+ <h3>Deprecated: <%= function[:deprecated] %></h3>
13
+ <% end %>
14
+ <h3> <%= function[:functionname] %> </h3>
15
+ <p> <%= function[:description].join(" ") %> </p>
16
+ <% if function[:params].length > 0 %>
17
+ <% function[:params].each do |param| %>
18
+ <h4> <%= param[:name] %> </h4>
19
+ <p> <%= param[:description] %></p>
20
+ <% end %>
21
+ <% end %>
22
+ <% if function[:return] %>
23
+ <h3>Returns: </h3>
24
+ <p> <%= function[:return] %> </p>
25
+ <% end %>
26
+ <% if function[:since] %>
27
+ <h4>Added in <%= function[:since] %></h4>
28
+ <% end %>
29
+ <% end %>
30
+ <% end %>
31
+ </body>
32
+ </html>
@@ -0,0 +1,37 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+
5
+ </head>
6
+ <body>
7
+ <h1><%= xml_html_content[:componentName] %></h1>
8
+ <h2>Extends: <%= xml_html_content[:componentExtendedClass] %></h2>
9
+
10
+ <% if xml_html_content[:brsfiles].length > 0 %>
11
+ <h2> Associated Brightscript: </h2>
12
+ <ul>
13
+ <% xml_html_content[:brsfiles].each do |brsfile| %>
14
+ <li><a href="<%= brsfile[:path] %>.html"><%= brsfile[:name] %></a></li>
15
+ <%end %>
16
+ </ul>
17
+ <% end %>
18
+
19
+ <% if xml_html_content[:fields].length > 0 %>
20
+ <h2> Fields: </h2>
21
+ <ul>
22
+ <% xml_html_content[:fields].each do |field| %>
23
+ <li><%= field[:id] %> : <%= field[:type] %></li>
24
+ <% end %>
25
+ </ul>
26
+ <% end %>
27
+
28
+ <% if xml_html_content[:functionalfields].length > 0 %>
29
+ <h2> Functional Fields: </h2>
30
+ <ul>
31
+ <% xml_html_content[:functionalfields].each do |functionalfield| %>
32
+ <li><a href="<%= functionalfield[:file] %>"></a><%= functionalfield[:name] %></li>
33
+ <% end %>
34
+ </ul>
35
+ <% end %>
36
+ </body>
37
+ </html>
data/rsg_doc.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ #********** Copyright 2017 REDspace. All Rights Reserved. **********
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rsg_doc'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'rsg_doc'
8
+ s.version = RSGDoc::VERSION
9
+ s.summary = "Generates documentation for Brightscript referenced in Scenegraph markup"
10
+ s.description = ""
11
+ s.authors = ["TyRud"]
12
+ s.email = 'tyler.rudolph@redspace.com'
13
+ s.files = `git ls-files -z`.split("\x0")
14
+ s.homepage = "https://rubygems.org/gems/example"
15
+ s.license = 'Apache-2.0'
16
+
17
+ s.bindir = ["bin"]
18
+ s.executables = ["rsg"]
19
+
20
+ s.required_ruby_version = "~> 2.3"
21
+
22
+ s.add_development_dependency "byebug", "~> 9.0"
23
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rsg_doc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - TyRud
8
+ autorequire:
9
+ bindir:
10
+ - bin
11
+ cert_chain: []
12
+ date: 2017-05-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: byebug
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '9.0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '9.0'
28
+ description: ''
29
+ email: tyler.rudolph@redspace.com
30
+ executables:
31
+ - rsg
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - LICENSE.txt
37
+ - README.md
38
+ - bin/rsg
39
+ - lib/rsg_doc.rb
40
+ - lib/rsg_doc/docgen.rb
41
+ - lib/rsg_doc/docgenTemplates/docgen.brs.html.erb
42
+ - lib/rsg_doc/docgenTemplates/docgen.xml.html.erb
43
+ - rsg_doc.gemspec
44
+ homepage: https://rubygems.org/gems/example
45
+ licenses:
46
+ - Apache-2.0
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '2.3'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 2.6.11
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: Generates documentation for Brightscript referenced in Scenegraph markup
68
+ test_files: []