hyla 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 (72) hide show
  1. data/.rakeTasks +7 -0
  2. data/.travis.yml +10 -0
  3. data/Gemfile +7 -0
  4. data/Gemfile.lock +49 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.adoc +136 -0
  7. data/Rakefile +61 -0
  8. data/archive/GruntFile.js +72 -0
  9. data/archive/watch_files.rb +70 -0
  10. data/bin/hyla +155 -0
  11. data/data/generated/A_Introduction_module/1_Chapter.adoc +42 -0
  12. data/data/generated/A_Introduction_module/2_Chapter.adoc +31 -0
  13. data/data/generated/A_Introduction_module/3_Chapter.adoc +23 -0
  14. data/data/generated/A_Introduction_module/A_Introduction_module_AllSlides.index +9 -0
  15. data/data/generated/B_Instruction_module/1_Chapter.adoc +27 -0
  16. data/data/generated/B_Instruction_module/B_Instruction_module_AllSlides.index +7 -0
  17. data/data/generated/C_Installation_module/1_Chapter.adoc +14 -0
  18. data/data/generated/C_Installation_module/2_Chapter.adoc +17 -0
  19. data/data/generated/C_Installation_module/C_Installation_module_AllSlides.index +8 -0
  20. data/data/generated/camel_AllSlides.index +9 -0
  21. data/data/js/livereload.js +1055 -0
  22. data/data/mime.types +85 -0
  23. data/data/toc.adoc +63 -0
  24. data/hyla.gemspec +37 -0
  25. data/hyla_frog.jpg +0 -0
  26. data/lib/hyla.rb +47 -0
  27. data/lib/hyla/command.rb +21 -0
  28. data/lib/hyla/commands/build.rb +40 -0
  29. data/lib/hyla/commands/create.rb +25 -0
  30. data/lib/hyla/commands/generate.rb +264 -0
  31. data/lib/hyla/commands/new.rb +82 -0
  32. data/lib/hyla/commands/publish.rb +8 -0
  33. data/lib/hyla/commands/reload.rb +109 -0
  34. data/lib/hyla/commands/serve.rb +59 -0
  35. data/lib/hyla/commands/watch.rb +172 -0
  36. data/lib/hyla/configuration.rb +47 -0
  37. data/lib/hyla/logger.rb +89 -0
  38. data/lib/hyla/project.rb +5 -0
  39. data/lib/hyla/training.rb +25 -0
  40. data/lib/hyla/websocket.rb +53 -0
  41. data/lib/templates/sample/asciidoc_article.adoc +64 -0
  42. data/lib/templates/sample/asciidoc_audio.adoc +4 -0
  43. data/lib/templates/sample/asciidoc_source_highlight.adoc +37 -0
  44. data/lib/templates/sample/asciidoc_video.adoc +4 -0
  45. data/lib/templates/sample/audio/ocean_waves.mp3 +0 -0
  46. data/lib/templates/sample/image/hyla_arborea.jpg +0 -0
  47. data/lib/templates/sample/slideshow_deckjs.adoc +186 -0
  48. data/lib/templates/sample/video/small.ogv +0 -0
  49. data/lib/templates/training-exercises/Gemfile +4 -0
  50. data/lib/templates/training-exercises/README.md +1 -0
  51. data/lib/templates/training-exercises/modules/introduction/docs/audio/ocean_waves.mp3 +0 -0
  52. data/lib/templates/training-exercises/modules/introduction/docs/video/small.ogv +0 -0
  53. data/lib/templates/training-exercises/modules/introduction/pom.xml +114 -0
  54. data/lib/templates/training-exercises/modules/introduction/src/main/java/HelloWorld.java +16 -0
  55. data/lib/templates/training-exercises/modules/introduction/src/test/java/HelloWorldTest.java +29 -0
  56. data/lib/templates/training-exercises/modules/pom.xml +61 -0
  57. data/lib/templates/training-exercises/modules/src/main/assembly/code.xml +31 -0
  58. data/lib/templates/training-exercises/modules/src/main/assembly/content.xml +16 -0
  59. data/lib/templates/training-exercises/pom.xml +157 -0
  60. data/lib/templates/training/GemFile +4 -0
  61. data/lib/templates/training/development/article.adoc +64 -0
  62. data/lib/templates/training/development/audio/ocean_waves.mp3 +0 -0
  63. data/lib/templates/training/development/image/hyla_frog.jpg +0 -0
  64. data/lib/templates/training/development/video/small.ogv +0 -0
  65. data/lib/templates/training/introduction/article.adoc +64 -0
  66. data/lib/templates/training/introduction/audio/ocean_waves.mp3 +0 -0
  67. data/lib/templates/training/introduction/image/hyla_frog.jpg +0 -0
  68. data/lib/templates/training/introduction/video/small.ogv +0 -0
  69. data/lib/templates/training/readme.adoc +1 -0
  70. data/scenario.adoc +59 -0
  71. data/test/my_test.rb +23 -0
  72. metadata +265 -0
@@ -0,0 +1,82 @@
1
+ module Hyla
2
+ module Commands
3
+ class New < Command
4
+
5
+ def self.process(args, options = {})
6
+ raise ArgumentError.new('You must specify a destination.') if args.empty?
7
+
8
+ @config = Hyla::Configuration.new
9
+
10
+ #
11
+ # Create Directory for the Project
12
+ #
13
+ new_project_path = File.expand_path(args.join(" "), Dir.pwd)
14
+
15
+ if Dir.exist? new_project_path
16
+
17
+ Hyla.logger.debug("Dir exists: #{new_project_path}")
18
+
19
+ # If force is selected, then we delete & recreate it to clen content
20
+ if options[:force]
21
+ Hyla.logger.debug("Force option selected")
22
+ # DOES NOT WORK ON Mac OS X
23
+ # FileUtils.rmdir(new_project_path)
24
+ FileUtils.rm_rf new_project_path
25
+ # Create Directory
26
+ FileUtils.mkdir_p new_project_path
27
+ Hyla.logger.debug("Dir recreated it")
28
+ end
29
+
30
+ # Preserve content if it exists
31
+ if preserve_content?(new_project_path)
32
+ Hyla.logger.error "Conflict: ", "#{new_project_path} exists and is not empty."
33
+ exit(1)
34
+ end
35
+
36
+ else
37
+ # Create Directory
38
+ FileUtils.mkdir_p new_project_path
39
+ end
40
+
41
+ #
42
+ # Create blank project
43
+ # or copy sample project from template directory
44
+ #
45
+ if options[:blank]
46
+ create_blank_project new_project_path
47
+ else
48
+ raise ArgumentError.new('You must specifiy a template type.') if options[:template_type].nil?
49
+ create_sample_project(new_project_path, options[:template_type])
50
+ end
51
+
52
+ end
53
+
54
+ #
55
+ # Create Blank Project
56
+ # with just a readme.adoc file
57
+ def self.create_blank_project(path)
58
+ Dir.chdir(path) do
59
+ f = File.open('sample.adoc', 'w')
60
+ f.puts "= Sample Asciidoctor Project"
61
+ f.puts "This is an empty AsciidocTor file."
62
+ f.puts "To create **asciidoc(tor)** content, more info are available http://asciidoctor.org/docs/user-manual[here]"
63
+ end
64
+ end
65
+
66
+ # Create a Sample Project
67
+ # from a Template
68
+ def self.create_sample_project(path, type)
69
+ # TODO Test with ['',''] * '/'
70
+ source = @config.templates + '/' + type + '/.'
71
+ FileUtils.cp_r source, path
72
+ end
73
+
74
+ #
75
+ # Preserve source location is folder is not empty
76
+ def self.preserve_content?(path)
77
+ !Dir["#{path}/**/*"].empty?
78
+ end
79
+
80
+ end # class
81
+ end # module Commands
82
+ end # module Hyla
@@ -0,0 +1,8 @@
1
+ module Hyla
2
+ module Commands
3
+ class Publish < Command
4
+
5
+
6
+ end # class
7
+ end # module Commands
8
+ end # module Hyla
@@ -0,0 +1,109 @@
1
+ module Hyla
2
+ module Commands
3
+ class Reload < Command
4
+
5
+ attr_reader :web_sockets, :thread, :options
6
+
7
+ DEFAULT_OPTIONS = {
8
+ host: '0.0.0.0',
9
+ port: '35729',
10
+ apply_css_live: true,
11
+ override_url: false,
12
+ grace_period: 0
13
+ }
14
+
15
+ @@web_sockets = []
16
+
17
+ def initialize()
18
+ end
19
+
20
+ def process(options)
21
+ @options = DEFAULT_OPTIONS.clone.merge(options)
22
+ @Websocket ||= Hyla::WebSocket
23
+ _start
24
+ end
25
+
26
+ def reload_browser(paths = [])
27
+ Hyla.logger.info "Reloading browser: #{paths.join(' ')}"
28
+ paths.each do |path|
29
+ Hyla.logger.info(path)
30
+ data = _data(path)
31
+ Hyla.logger.info(">> Data received : #{data}")
32
+ @@web_sockets.each { |ws| ws.send(MultiJson.encode(data)) }
33
+ end
34
+ end
35
+
36
+ def reload_browser2(paths = [])
37
+ Hyla.logger.info "Reloading browser: #{paths.join(' ')}"
38
+ paths.each do |path|
39
+ Hyla.logger.info(path)
40
+ data = 'hyla/development/'
41
+ Hyla.logger.info(">> Data received : #{data}")
42
+ @@web_sockets.each { |ws| ws.send(MultiJson.encode(data)) }
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def _start
49
+ _start_reactor
50
+ end
51
+
52
+ def _stop
53
+ thread.kill
54
+ end
55
+
56
+ def _data(path)
57
+
58
+ # TODO Improve that
59
+ # path: "#{Dir.pwd}/#{path}",
60
+
61
+ data = {
62
+ command: 'reload',
63
+ path: "#{path}",
64
+ liveCSS: @options[:apply_css_live]
65
+ }
66
+ if options[:override_url] && File.exist?(path)
67
+ data[:overrideURL] = '/' + path
68
+ end
69
+ data
70
+ end
71
+
72
+ def _start_reactor
73
+ Hyla.logger.info "LiveReload is waiting for a browser to connect."
74
+ EventMachine.epoll
75
+ EventMachine.run do
76
+ EventMachine.start_server(@options[:host], @options[:port], @Websocket, {}) do |ws|
77
+ ws.onopen { _connect(ws) }
78
+ ws.onclose { _disconnect(ws) }
79
+ ws.onmessage { |msg| _print_message(msg) }
80
+ end
81
+ end
82
+ end
83
+
84
+ def _connect(ws)
85
+ Hyla.logger.info "Browser connected."
86
+ ws.send MultiJson.encode(
87
+ command: 'hello',
88
+ protocols: ['http://livereload.com/protocols/official-7'],
89
+ serverName: 'guard-livereload'
90
+ )
91
+ @@web_sockets << ws
92
+ rescue
93
+ Hyla.logger.error $!
94
+ Hyla.logger.error $!.backtrace
95
+ end
96
+
97
+ def _disconnect(ws)
98
+ Hyla.logger.info "Browser disconnected."
99
+ @@web_sockets.delete(ws)
100
+ end
101
+
102
+ def _print_message(message)
103
+ message = MultiJson.decode(message)
104
+ Hyla.logger.info "Browser URL: #{message['url']}" if message['command'] == 'url'
105
+ end
106
+
107
+ end # class
108
+ end # module Commands
109
+ end # module Hyla
@@ -0,0 +1,59 @@
1
+ module Hyla
2
+ module Commands
3
+ class Serve < Command
4
+
5
+ def self.process(args, options)
6
+ include WEBrick
7
+
8
+ my_opts = options
9
+
10
+ destination = options[:out_dir]
11
+
12
+ my_opts[:Port] = options[:port]
13
+ my_opts[:BindAddress] = options[:host]
14
+ my_opts[:MimeTypes] = self.mime_types
15
+ my_opts[:DoNotReverseLookupmy_opts] = true
16
+ my_opts[:StartCallback] = start_callback(options[:detach])
17
+ my_opts[:AccessLog] = []
18
+ my_opts[:Logger] = Log::new([], Log::WARN)
19
+ my_opts[:baseurl] = options[:baseurl]
20
+
21
+ # recreate NondisclosureName under utf-8 circumstance
22
+ fh_option = WEBrick::Config::FileHandler
23
+ fh_option[:NondisclosureName] = ['.ht*','~*']
24
+ # Option added to allow to navigate into the directories
25
+ fh_option[:FancyIndexing] = true
26
+
27
+ #s = HTTPServer.new(webrick_options(my_opts))
28
+ s = HTTPServer.new(my_opts)
29
+
30
+ s.mount(my_opts[:baseurl],HTTPServlet::FileHandler, destination, fh_option)
31
+
32
+ Hyla.logger.info "Server address:", "http://#{s.config[:BindAddress]}:#{s.config[:Port]}"
33
+
34
+ if options[:detach] # detach the server
35
+ pid = Process.fork { s.start }
36
+ Process.detach(pid)
37
+ Hyla.logger.info "Server detatched with pid '#{pid}'.", "Run `kill -9 #{pid}' to stop the server."
38
+ else # create a new server thread, then join it with current terminal
39
+ t = Thread.new { s.start }
40
+ trap("INT") { s.shutdown }
41
+ t.join()
42
+ end
43
+ end
44
+
45
+
46
+ def self.start_callback(detached)
47
+ unless detached
48
+ Proc.new { Hyla.logger.info "Server running...", "press ctrl-c to stop." }
49
+ end
50
+ end
51
+
52
+ def self.mime_types
53
+ mime_types_file = File.expand_path('../../../data/mime.types', File.dirname(__FILE__))
54
+ WEBrick::HTTPUtils::load_mime_types(mime_types_file)
55
+ end
56
+
57
+ end # class
58
+ end # module Commands
59
+ end # module Hyla
@@ -0,0 +1,172 @@
1
+ module Hyla
2
+ module Commands
3
+ class Watch < Command
4
+
5
+ DEFAULT_OPTIONS = {
6
+ :watch_dir => '.',
7
+ :watch_ext => %w(ad adoc asc asciidoc txt index),
8
+ :run_on_start => false,
9
+ :backend => 'html5',
10
+ :eruby => 'erb',
11
+ :doctype => 'article',
12
+ :compact => false,
13
+ :attributes => {},
14
+ :always_build_all => false,
15
+ :to_dir => '.',
16
+ :to_file => '',
17
+ :safe => :unsafe,
18
+ :header_footer => true
19
+ }
20
+
21
+ WS_OPTIONS = {
22
+ :base_url => '/modules'
23
+ }
24
+
25
+ def initialize
26
+ end
27
+
28
+ def init(watchers = [], options = {})
29
+ watchers = [] if !watchers
30
+ merged_opts = DEFAULT_OPTIONS.clone
31
+
32
+ if options.has_key? :watch_dir
33
+ merged_opts[:watch_dir] = options.delete :watch_dir
34
+ # set output to input if input is specified, but not output
35
+ unless options.has_key? :to_dir
36
+ merged_opts[:to_dir] = merged_opts[:watch_dir]
37
+ end
38
+ end
39
+
40
+ merged_opts.merge! options
41
+
42
+ # house cleaning
43
+ merged_opts[:watch_dir] = '.' if merged_opts[:watch_dir].to_s.empty?
44
+ merged_opts.delete(:to_dir) if (merged_opts[:to_dir] == '.' || merged_opts[:to_dir].to_s.empty?)
45
+
46
+ if merged_opts[:watch_dir] == '.'
47
+ input_re = ''
48
+ else
49
+ merged_opts[:watch_dir].chomp!('/') while merged_opts[:watch_dir].end_with?('/')
50
+ merged_opts[:watch_dir] << '/'
51
+ input_re = Regexp.escape merged_opts[:watch_dir]
52
+ end
53
+
54
+ watch_re = %r{^#{input_re}.+\.(?:#{merged_opts[:watch_ext] * '|'})$}
55
+ watchers << ::Guard::Watcher.new(watch_re)
56
+ merged_opts[:attributes] = {} unless merged_opts[:attributes]
57
+ # set a flag to indicate running environment
58
+ merged_opts[:attributes]['guard'] = ''
59
+ end
60
+
61
+ def self.start_livereload
62
+ @reload = Hyla::Commands::Reload.new
63
+ Thread.new { @reload.process(WS_OPTIONS) }
64
+ end
65
+
66
+ def self.process(args, options = {})
67
+
68
+ # Start LiveReload
69
+ self.start_livereload
70
+
71
+ @opts = DEFAULT_OPTIONS.clone
72
+
73
+ if options.has_key? :destination
74
+ @opts[:to_dir] = File.expand_path options[:destination]
75
+ end
76
+
77
+ if options.has_key? :source
78
+ @opts[:watch_dir] = File.expand_path options[:source]
79
+ end
80
+
81
+ @received_opts = options
82
+
83
+ #
84
+ # Guard Listen Callback
85
+ # Detect files modified, deleted or added
86
+ #
87
+ callback = Proc.new do |modified, added, removed|
88
+ Hyla.logger.info "modified absolute path: #{modified}"
89
+ Hyla.logger.info "added absolute path: #{added}"
90
+ Hyla.logger.info "removed absolute path: #{removed}"
91
+
92
+ if !modified.nil? or !added.nil?
93
+ modified.each do |modify|
94
+ Hyla.logger.info "File modified : #{modify}"
95
+ call_asciidoctor(modify)
96
+ end
97
+ added.each do |add|
98
+ Hyla.logger.info "File added : #{add}"
99
+ call_asciidoctor(add)
100
+ end
101
+ end
102
+ end # callback
103
+
104
+ Hyla.logger.info ">> ... Starting"
105
+ Hyla.logger.info ">> Hyla has started to watch files in this output dir : #{@opts[:watch_dir]}"
106
+ Hyla.logger.info ">> Results of Asciidoctor generation will be available here : #{@opts[:to_dir]}"
107
+
108
+ # TODO : Investigate issue with Thread pool is not running (Celluloid::Error)
109
+ # when using a more recent version of guard listen
110
+ listener = Listen.to!(@opts[:watch_dir], &callback)
111
+
112
+ trap(:INT) {
113
+ Hyla.logger.info "Interrupt intercepted"
114
+ Thread.kill
115
+ }
116
+ end
117
+
118
+ # listen
119
+
120
+ def self.call_asciidoctor(f)
121
+ dir_file = File.dirname(f)
122
+ file_to_process = Pathname.new(f).basename
123
+ @ext_name = File.extname(file_to_process)
124
+ Hyla.logger.info ">> Directory of the file to be processed : #{dir_file}"
125
+ Hyla.logger.info ">> File to be processed : #{file_to_process}"
126
+ Hyla.logger.info ">> Extension of the file : #{@ext_name}"
127
+
128
+ if @ext_name != '.html'
129
+ to_file = file_to_process.to_s.gsub('adoc', 'html')
130
+ @opts[:to_file] = to_file
131
+
132
+ # TODO Check why asciidoctor populates new attributes and remove to_dir
133
+ # TODO when it is called a second time
134
+ # Workaround - reset list, add again :out_dir
135
+ @opts[:attributes] = {}
136
+ @opts[:to_dir] = @received_opts[:destination]
137
+
138
+ # Calculate Asciidoc to_dir relative to the dir of the file to be processed
139
+ # and create dir in watched dir
140
+ rel_dir = substract_watch_dir(dir_file, @opts[:watch_dir])
141
+ if !rel_dir.empty?
142
+ calc_dir = File.expand_path @opts[:to_dir] + rel_dir
143
+ FileUtils.makedirs calc_dir
144
+ else
145
+ calc_dir = File.expand_path @opts[:to_dir]
146
+ end
147
+
148
+ @opts[:to_dir] = calc_dir
149
+
150
+ Hyla.logger.info ">> Directory of the file to be generated : #{calc_dir}"
151
+ Hyla.logger.debug ">> Asciidoctor options : #{@opts}"
152
+
153
+ # Render Asciidoc document
154
+ Asciidoctor.render_file(f, @opts)
155
+
156
+ # Refresh browser connected using LiveReload
157
+ path = []
158
+ path.push(calc_dir)
159
+ # TODO
160
+ @reload.reload_browser(path)
161
+ end
162
+ end
163
+
164
+ def self.substract_watch_dir(file_dir, watched_dir)
165
+ s = file_dir.sub(watched_dir, '')
166
+ Hyla.logger.info ">> Relative directory : #{s}"
167
+ s
168
+ end
169
+
170
+ end # class
171
+ end # module Commands
172
+ end # module Hyla
@@ -0,0 +1,47 @@
1
+ module Hyla
2
+ class Configuration
3
+
4
+ attr_reader :HEADER, :INDEX_SUFFIX, :HEADER_INDEX, :INCLUDE_PREFIX, :INCLUDE_SUFFIX, :LEVEL_1, :LEVEL_2, :SKIP_CHARACTERS,
5
+ :ADOC_EXT, :PREFIX_ARTEFACT, :TEMPLATES
6
+
7
+ def initialize()
8
+
9
+ @INCLUDE_PREFIX = 'include::'
10
+ @INCLUDE_SUFFIX = '[]'
11
+
12
+ @INDEX_SUFFIX = '_AllSlides.index'
13
+
14
+ @HEADER = ":data-uri:\n" +
15
+ ":icons: font\n" +
16
+ ":last-update-label!:\n" +
17
+ ":source-highlighter: coderay\n" +
18
+ ":toc: left\n" +
19
+ "\n"
20
+
21
+ @HEADER_INDEX = ":data-uri:\n" +
22
+ ":navigation:\n" +
23
+ ":menu:\n" +
24
+ ":status:\n" +
25
+ "\n"
26
+
27
+ @LEVEL_1 = '= '
28
+
29
+ @LEVEL_2 = '== '
30
+
31
+ @SKIP_CHARACTERS = '>>'
32
+
33
+ @ADOC_EXT = '.adoc'
34
+
35
+ @PREFIX_ARTEFACT = 'asciidoc_'
36
+
37
+ @TEMPLATES = '../../lib/templates'
38
+
39
+ end
40
+
41
+ # Templates Location
42
+ def templates
43
+ File.expand_path(@TEMPLATES, File.dirname(__FILE__))
44
+ end
45
+
46
+ end # Class Artefact
47
+ end # module Hyla