hyla 1.0.1 → 1.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.
Files changed (48) hide show
  1. checksums.yaml +8 -8
  2. data/README.adoc +44 -84
  3. data/bin/hyla +23 -7
  4. data/data/chm-status-weeks-0601-1001.html +913 -0
  5. data/documentation/image/access_local_file.png +0 -0
  6. data/documentation/image/email_send.png +0 -0
  7. data/{hyla_frog.jpg → documentation/image/hyla_frog.jpg} +0 -0
  8. data/documentation/introduction.adoc +433 -0
  9. data/hyla.gemspec +7 -5
  10. data/lib/hyla.rb +4 -2
  11. data/lib/hyla/commands/generate.rb +102 -76
  12. data/lib/hyla/commands/sendmail.rb +97 -0
  13. data/lib/hyla/commands/watch.rb +6 -4
  14. data/lib/hyla/configuration.rb +49 -26
  15. data/lib/hyla/project.rb +1 -1
  16. data/lib/resources/backends/slim/revealjs/document.html.slim +1 -1
  17. data/lib/resources/backends/slim/revealjs/section.html.slim +3 -3
  18. data/lib/resources/revealjs/plugin/notes/notes.html +252 -248
  19. data/lib/resources/styles/asciidoctor.css +1 -1
  20. data/lib/resources/styles/colony.css +1 -1
  21. data/lib/resources/styles/foundation-lime.css +1 -1
  22. data/lib/resources/styles/foundation-potion.css +1 -1
  23. data/lib/resources/styles/foundation.css +1 -1
  24. data/lib/resources/styles/github.css +3 -3
  25. data/lib/resources/styles/golo.css +3 -3
  26. data/lib/resources/styles/iconic.css +1 -1
  27. data/lib/resources/styles/maker.css +2 -2
  28. data/lib/resources/styles/readthedocs.css +1 -1
  29. data/lib/resources/styles/redhat.css +1 -654
  30. data/lib/resources/styles/riak.css +1 -1
  31. data/lib/resources/styles/rocket-panda.css +1 -1
  32. data/lib/resources/styles/rubygems.css +1 -1
  33. data/lib/templates/_config.yml +2 -2
  34. data/lib/templates/sample/slideshow_revealjs.adoc +240 -6
  35. metadata +79 -18
  36. data/Gemfile.lock +0 -77
  37. data/data/generated/A_Introduction_module/1_Chapter.adoc +0 -42
  38. data/data/generated/A_Introduction_module/2_Chapter.adoc +0 -31
  39. data/data/generated/A_Introduction_module/3_Chapter.adoc +0 -23
  40. data/data/generated/A_Introduction_module/A_Introduction_module_AllSlides.index +0 -9
  41. data/data/generated/B_Instruction_module/1_Chapter.adoc +0 -27
  42. data/data/generated/B_Instruction_module/B_Instruction_module_AllSlides.index +0 -7
  43. data/data/generated/C_Installation_module/1_Chapter.adoc +0 -14
  44. data/data/generated/C_Installation_module/2_Chapter.adoc +0 -17
  45. data/data/generated/C_Installation_module/C_Installation_module_AllSlides.index +0 -8
  46. data/data/generated/camel_AllSlides.index +0 -9
  47. data/lib/templates/book/GemFile +0 -5
  48. data/scenario.adoc +0 -152
data/lib/hyla.rb CHANGED
@@ -22,7 +22,6 @@ require 'guard'
22
22
  require 'safe_yaml'
23
23
  require 'asciidoctor'
24
24
  require 'asciidoctor/backends/html5'
25
-
26
25
  # require 'asciidoctor/backends/_stylesheets'
27
26
  require 'eventmachine'
28
27
  require 'em-websocket'
@@ -30,13 +29,16 @@ require 'http/parser'
30
29
  require 'multi_json'
31
30
  require 'webrick'
32
31
  require 'find'
32
+ require 'mail'
33
+ require 'mime/types'
34
+ require 'pdfkit'
33
35
 
34
36
  # internal requires
35
37
  require 'hyla/logger'
36
38
  require 'hyla/core_ext'
37
39
  require 'hyla/command'
38
40
  require 'hyla/configuration'
39
- require 'Hyla/WebSocket'
41
+ require 'hyla/websocket'
40
42
  require 'hyla/logger'
41
43
 
42
44
  # extensions
@@ -2,35 +2,22 @@ module Hyla
2
2
  module Commands
3
3
  class Generate < Command
4
4
 
5
- DEFAULT_OPTIONS = {
6
-
7
- :source => Dir.pwd,
8
- :destination => File.join(Dir.pwd, 'generated_content'),
9
-
10
- :watch_dir => '.',
11
- :watch_ext => %w(ad adoc asciidoc txt index),
12
- :run_on_start => false,
13
- :backend => 'html5',
14
- :eruby => 'erb',
15
- :doctype => 'article',
16
- :compact => false,
17
- :attributes => {
18
- 'source-highlighter' => 'coderay',
19
- 'linkcss!' => 'true',
20
- 'data-uri' => 'true',
21
- 'stylesheet' => 'asciidoctor.css',
22
- 'stylesdir' => Configuration::styles
23
- },
24
- :always_build_all => false,
25
- :safe => 'unsafe',
26
- :header_footer => true
27
- }
28
-
29
5
  def self.process(args, options = {})
30
6
 
31
7
  rendering = options[:rendering] if self.check_mandatory_option?('--r / --rendering', options[:rendering])
32
8
 
33
9
  case rendering
10
+
11
+ when 'html2pdf'
12
+
13
+ Hyla.logger.info "Rendering : Generate PDF from HTML file"
14
+
15
+ source_dir = options[:source] if self.check_mandatory_option?('-s / --source', options[:source])
16
+ out_dir = options[:destination] if self.check_mandatory_option?('-d / --destination', options[:destination])
17
+ file_name = options[:file] if self.check_mandatory_option?('-f / --file', options[:file])
18
+
19
+ self.html_to_pdf(source_dir, out_dir, file_name)
20
+
34
21
  when 'toc2adoc'
35
22
 
36
23
  Hyla.logger.info "Rendering : Table of Content to Asciidoc"
@@ -46,61 +33,70 @@ module Hyla
46
33
  Hyla.logger.info "Rendering : Asciidoc to HTML"
47
34
  self.check_mandatory_option?('--s / --source', options[:source])
48
35
  self.check_mandatory_option?('--d / --destination', options[:destination])
36
+
49
37
  @destination = options[:destination]
50
38
  @source = options[:source]
51
39
 
52
- extensions = 'adoc|ad|txt'
40
+ # Check Style to be used
41
+ new_asciidoctor_option = {
42
+ :attributes => {
43
+ 'stylesheet' => self.check_style(options[:style])
44
+ }
45
+ }
53
46
 
54
- self.asciidoc_to_html(@source, @destination, extensions, options)
47
+ merged_options = Configuration[options].deep_merge(new_asciidoctor_option)
55
48
 
56
- when 'adoc2slide'
57
- Hyla.logger.info "Rendering : Asciidoc to SlideShow"
49
+ extensions = 'adoc|ad|asciidoc'
50
+
51
+ self.asciidoc_to_html(@source, @destination, extensions, merged_options)
52
+
53
+ when 'index2slide'
54
+ Hyla.logger.info "Rendering : Asciidoctor Indexed Files to SlideShow"
58
55
  self.check_mandatory_option?('--s / --source', options[:source])
59
56
  self.check_mandatory_option?('--d / --destination', options[:destination])
60
57
 
61
- # Assign by default backend as HTML5 if not provided by command line
62
- backend = options[:backend]? options[:backend] : 'html5'
58
+ @destination = options[:destination]
59
+ @source = options[:source]
60
+
61
+ new_asciidoctor_option = {
62
+ :template_dirs => [self.backend_dir(options[:backend])],
63
+ :attributes => {
64
+ 'stylesheet' => self.check_style(options[:style])
65
+ }
66
+ }
63
67
 
64
- #
65
- # Retrieve asciidoctor attributes
66
- # Could be an Arrays of Strings key=value,key=value
67
- # or
68
- # Could be a Hash (DEFAULTS, CONFIG_File)
69
- attributes = options[:attributes]
70
- override_attrs = case attributes
71
- when Hash then attributes
72
- when String then
73
- result = attributes.split(',')
74
- attributes = Hash.new
75
- result.each do |entry|
76
- words = entry.split('=')
77
- attributes[words[0]] = words[1]
78
- end
79
- attributes
80
- else {}
81
- end
68
+ merged_options = Configuration[options].deep_merge(new_asciidoctor_option)
69
+
70
+ # Extension(s) of the files containing include directives
71
+ extensions = 'txt'
72
+
73
+ self.asciidoc_to_html(@source, @destination, extensions, merged_options)
74
+
75
+ when 'adoc2slide'
76
+ Hyla.logger.info "Rendering : Asciidoc to SlideShow"
77
+ self.check_mandatory_option?('--s / --source', options[:source])
78
+ self.check_mandatory_option?('--d / --destination', options[:destination])
82
79
 
83
80
  @destination = options[:destination]
84
81
  @source = options[:source]
85
- options = {
86
- :backend => backend,
87
- :template_dirs => [
88
- self.backend_dir(options[:backend])
89
- ],
90
- :watch_ext => %w(index),
91
- :attributes => override_attrs
82
+
83
+ new_asciidoctor_option = {
84
+ :template_dirs => [self.backend_dir(options[:backend])],
85
+ :attributes => {
86
+ 'stylesheet' => self.check_style(options[:style])
87
+ }
92
88
  }
93
89
 
94
- extensions = 'index|adoc|ad|asciidoc'
90
+ merged_options = Configuration[options].deep_merge(new_asciidoctor_option)
95
91
 
96
- self.asciidoc_to_html(@source, @destination, extensions, options)
92
+ # Extension(s) of the files to be parsed
93
+ extensions = 'adoc|ad|asciidoc'
94
+
95
+ self.asciidoc_to_html(@source, @destination, extensions, merged_options)
97
96
  else
98
97
  Hyla.logger.error ">> Unknow rendering"
99
98
  exit(1)
100
99
  end
101
-
102
- # From Table of Content File to Asciidoc directories and Files
103
- # self.table_of_content_to_asciidoc(@toc_file, @out_dir, @project_name)
104
100
  end
105
101
 
106
102
  # Return backend directory
@@ -116,17 +112,6 @@ module Hyla
116
112
 
117
113
  def self.asciidoc_to_html(source, destination, extensions, options)
118
114
 
119
- # CSS Style to be applied
120
- css_style = self.check_style(options[:style])
121
-
122
- override = {
123
- :attributes => {
124
- 'stylesheet' => css_style
125
- }
126
- }
127
-
128
- @options = Configuration[options].deep_merge(override)
129
-
130
115
  # Move to Source directory & Retrieve Asciidoctor files to be processed
131
116
  source = File.expand_path source
132
117
  @destination = File.expand_path destination
@@ -173,8 +158,8 @@ module Hyla
173
158
 
174
159
  # Render asciidoc to HTML
175
160
  Hyla.logger.info ">> File to be rendered : #{path}"
176
- @options[:to_dir] = html_dir
177
- Asciidoctor.render_file(path, @options)
161
+ options[:to_dir] = html_dir
162
+ Asciidoctor.render_file(path, options)
178
163
 
179
164
  end
180
165
  end
@@ -269,8 +254,8 @@ module Hyla
269
254
  FileUtils.mkdir_p new_dir
270
255
  Dir.chdir(new_dir)
271
256
 
272
- # Add image directory
273
- Dir.mkdir('image')
257
+ # Add image, audio, video directory
258
+ self.create_asset_directory(['image', 'audio', 'video'])
274
259
 
275
260
  #
276
261
  # Create an index file
@@ -281,6 +266,7 @@ module Hyla
281
266
 
282
267
  # Include index file created to parent index file
283
268
  @project_index_file.puts Configuration::INCLUDE_PREFIX + dir_name + '/' + dir_name + Configuration::INDEX_SUFFIX + Configuration::INCLUDE_SUFFIX
269
+ @project_index_file.puts "\n"
284
270
 
285
271
  # Move to next line record
286
272
  next
@@ -304,11 +290,13 @@ module Hyla
304
290
  f_name += '.adoc'
305
291
  @new_f = File.new(f_name, 'w')
306
292
  @new_f.puts Configuration::HEADER
293
+ @new_f.puts "\n"
307
294
 
308
295
  @previous_f = @new_f
309
296
 
310
297
  # Include file to index
311
298
  @index_file.puts Configuration::INCLUDE_PREFIX + f_name + Configuration::INCLUDE_SUFFIX
299
+ @index_file.puts "\n"
312
300
  end
313
301
 
314
302
  #
@@ -322,6 +310,38 @@ module Hyla
322
310
 
323
311
  end
324
312
 
313
+ #
314
+ # Generate PDF
315
+ #
316
+ def self.html_to_pdf(source, destination, html_file_name)
317
+ file_path = [source, html_file_name] * '/'
318
+ html_file = File.new(file_path)
319
+ kit = PDFKit.new(html_file,
320
+ :page_size => 'A4',
321
+ :toc => true,
322
+ :page_offset => 1,
323
+ :footer_center => 'Page [page]')
324
+
325
+ # Create destination directory if it does not exist
326
+ unless File.directory?(destination)
327
+ FileUtils.mkdir_p(destination)
328
+ end
329
+
330
+ # Save PDF to a file
331
+ pdf_file_name = [destination, html_file_name.sub(/html|htm/,'pdf')] * '/'
332
+ kit.to_file(pdf_file_name)
333
+ Hyla.logger.info ">> PDF file generated and saved : #{pdf_file_name} "
334
+ end
335
+
336
+ #
337
+ # Create Asset Directory
338
+ #
339
+ def self.create_asset_directory(assets = [])
340
+ assets.each do |asset|
341
+ Dir.mkdir(asset) if !Dir.exist? asset
342
+ end
343
+ end
344
+
325
345
  #
326
346
  # Remove space, dot from a String
327
347
  #
@@ -350,8 +370,14 @@ module Hyla
350
370
  def self.create_index_file(file_name, level)
351
371
  n_file_name = file_name + Configuration::INDEX_SUFFIX
352
372
  index_file = File.new(n_file_name, 'w')
353
- index_file.puts level + file_name
373
+
354
374
  index_file.puts Configuration::HEADER_INDEX
375
+ index_file.puts "\n"
376
+ # TODO - until now we cannot use level 0 for parent/children files
377
+ # even if doctype: book
378
+ # This is why the level for each index file title is '=='
379
+ index_file.puts '==' + file_name
380
+ index_file.puts "\n"
355
381
 
356
382
  index_file
357
383
  end
@@ -0,0 +1,97 @@
1
+ module Hyla
2
+ module Commands
3
+ class Sendmail < Command
4
+
5
+ def self.process(args, options)
6
+
7
+ location = options[:location] if check_mandatory_option?('-s / --location', options[:location])
8
+ file_name = options[:file] if check_mandatory_option?('-f / --file', options[:file])
9
+ email_attributes = options[:email_attributes] if check_mandatory_option?('-e / --email_attributes', options[:email_attributes])
10
+
11
+ sender = email_attributes[:from]
12
+ recipients = email_attributes[:to]
13
+ subject = email_attributes[:subject]
14
+ file_path = [location, file_name] * '/'
15
+
16
+ # Parameters used to connect to the SMTP Server
17
+ @smtp_server = email_attributes[:smtp_server] if check_mandatory_option?(':smtp_server not defined in _config.yaml file', email_attributes[:smtp_server])
18
+ @port_number = email_attributes[:port] if check_mandatory_option?(':port not defined in _config.yaml file', email_attributes[:port])
19
+ @user = email_attributes[:user]
20
+ @password = email_attributes[:password]
21
+ @authentication = email_attributes[:authentication]
22
+ @enable_starttls = email_attributes[:enable_starttls] if check_mandatory_option?(':enable_start_tls not defined in _config.yaml file', email_attributes[:enable_starttls])
23
+
24
+ body = <<-EOS
25
+ <html>
26
+ <head>
27
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
28
+ <title>REPORT</title>
29
+ <link type="text/css" rel="stylesheet" href="http://cdn.jsdelivr.net/foundation/5.0.3/css/foundation.min.css" />
30
+ <link type="text/css" rel="stylesheet" href="http://cdn.jsdelivr.net/normalize/2.1.3/normalize.min.css" />
31
+ </head>
32
+ <body>
33
+ <div class="row">
34
+ <!-- Main Content -->
35
+ <div class="large-9 columns" role="content">
36
+ <article>
37
+ <h4>#{subject}</h4>
38
+ <p>Attached as <a href=\'#{file_name}'>HTML file to this email</a></p>
39
+ <p>Generated by Hyla Tool</p>
40
+ </p>
41
+ <p>Remark : html Link works with Thunderbird, Gmail clients but not using Zimbra Web Client</p>
42
+ </article>
43
+ </div>
44
+ </div>
45
+ </body>
46
+ </html>
47
+ EOS
48
+
49
+ mail = Mail.new do
50
+ to recipients
51
+ from sender
52
+ subject subject
53
+ content_type 'multipart/related'
54
+ end
55
+
56
+ attachment = File.read(file_path)
57
+ mail.attachments[file_name] = {
58
+ :mime_type => 'application/x-html',
59
+ :content => attachment}
60
+
61
+ inline_html = inline_body_with_attachments(body, mail.attachments)
62
+
63
+ html_part = Mail::Part.new do
64
+ content_type 'text/html; charset=UTF-8'
65
+ body inline_html
66
+ end
67
+
68
+ mail.html_part = html_part
69
+
70
+ mail.delivery_method :smtp, parameters()
71
+ mail.deliver!
72
+ Hyla.logger.info "Email send to SMTP server from #{sender} with this subject : #{subject}"
73
+ end
74
+
75
+ def self.parameters()
76
+ parameters = {}
77
+ parameters[:address] = @smtp_server unless @smtp_server.nil?
78
+ parameters[:port] = @port_number unless @port_number.nil?
79
+ parameters[:enable_starttls] = @enable_starttls unless @enable_starttls.nil?
80
+ parameters[:user_name] = @user unless @user.nil?
81
+ parameters[:password] = @password unless @password.nil?
82
+ parameters[:authentication] = @authentication unless @authentication.nil?
83
+ return parameters
84
+ end
85
+
86
+ def self.inline_body_with_attachments(html, attachments)
87
+ attachments.each do |attachment|
88
+ if (html =~ /#{attachment.filename}/)
89
+ html = html.sub(attachment.filename, "cid:#{attachment.cid}")
90
+ end
91
+ end
92
+ return html
93
+ end
94
+
95
+ end # class
96
+ end # module Commands
97
+ end # module Hyla
@@ -123,11 +123,13 @@ module Hyla
123
123
  dir_file = File.dirname(f)
124
124
  file_to_process = Pathname.new(f).basename
125
125
  @ext_name = File.extname(file_to_process)
126
- Hyla.logger.info ">> Directory of the file to be processed : #{dir_file}"
127
- Hyla.logger.info ">> File to be processed : #{file_to_process}"
128
- Hyla.logger.info ">> Extension of the file : #{@ext_name}"
129
126
 
130
- if @ext_name != '.html'
127
+ if [".adoc",".ad",".asciidoc",".txt",".index"].include? @ext_name
128
+
129
+ Hyla.logger.info ">> Directory containing file(s) to be processed : #{dir_file}"
130
+ Hyla.logger.info ">> File to be processed : #{file_to_process}"
131
+ Hyla.logger.info ">> Extension of the file : #{@ext_name}"
132
+
131
133
  # Generate File name
132
134
  # Rename xxx.adoc, xxx.asciidoc, xxx.ad, xxx.index to xxx.html
133
135
  to_file = file_to_process.to_s.gsub(/.adoc|.ad|.asciidoc|.index/, '.html')
@@ -6,26 +6,22 @@ module Hyla
6
6
  :templates, :samples, :resources, :styles, :backends
7
7
 
8
8
  DEFAULTS = {
9
- 'source' => Dir.pwd,
10
- 'destination' => File.join(Dir.pwd, 'generated_content'),
9
+ 'source' => Dir.pwd,
10
+ 'destination' => File.join(Dir.pwd, 'generated_content'),
11
11
 
12
12
  # Asciidoctor
13
- 'watch_dir' => '.',
14
- 'watch_ext' => %w(ad adoc asciidoc txt index),
15
- 'run_on_start' => false,
16
- 'backend' => 'html5',
17
- 'eruby' => 'erb',
18
- 'doctype' => 'article',
19
- 'compact' => false,
20
- 'attributes' => {
13
+ 'backend' => 'html5',
14
+ 'eruby' => 'erb',
15
+ 'doctype' => 'article',
16
+ 'compact' => false,
17
+ 'attributes' => {
21
18
  'source-highlighter' => 'coderay',
22
- 'linkcss!' => 'true',
23
- 'data-uri' => 'true',
24
- 'stylesheet' => 'asciidoctor.css',
25
- 'stylesdir' => 'styles'
19
+ 'linkcss!' => 'true',
20
+ 'data-uri' => 'true',
21
+ 'stylesheet' => 'asciidoctor.css',
22
+ 'stylesdir' => 'styles'
26
23
  },
27
- 'always_build_all' => false,
28
- 'safe' => 'unsafe',
24
+ 'safe' => 'unsafe',
29
25
  'header_footer' => true
30
26
 
31
27
  }
@@ -34,22 +30,19 @@ module Hyla
34
30
 
35
31
  INCLUDE_SUFFIX = '[]'
36
32
 
37
- INDEX_SUFFIX = '_AllSlides.index'
33
+ INDEX_SUFFIX = '_AllSlides.txt'
38
34
 
39
35
  HEADER = ":data-uri:\n" +
40
36
  ":icons: font\n" +
41
37
  ":last-update-label!:\n" +
42
- ":source-highlighter: coderay\n" +
43
- ":toc: left\n" +
44
- ":notitle: true\n" +
45
- "\n"
38
+ ":source-highlighter: coderay\n"
46
39
 
47
40
  HEADER_INDEX = ":data-uri:\n" +
48
41
  ":navigation:\n" +
49
42
  ":menu:\n" +
50
43
  ":status:\n" +
51
-
52
- "\n"
44
+ ":goto:\n" +
45
+ ":notitle:\n"
53
46
 
54
47
  LEVEL_1 = '= '
55
48
 
@@ -117,12 +110,27 @@ module Hyla
117
110
  #
118
111
  # Returns the final configuration Hash.
119
112
  def self.parse(override)
120
- config = DEFAULTS
121
- Hyla::logger.debug("DEFAULTS Keys: #{config.inspect}")
113
+
114
+
115
+ # Extract Asciidoctor attributes received from hyla command line '--a key=value,key=value'
116
+ # Convert them to a Hash of attributes 'attributes' => { 'backend' => html5 ... }
117
+ # Assign hash to override[:attributes]
118
+ extracted_attributes = self.extract_attributes(override[:attributes]) if override[:attributes]
119
+ override[:attributes] = extracted_attributes if extracted_attributes
120
+
121
+ extracted_email_attributes = self.extract_attributes(override[:email_attributes]) if override[:email_attributes]
122
+ override[:email_attributes] = extracted_email_attributes if extracted_email_attributes
123
+
124
+ # Stringify keys of the hash what we receive from Hyla as override
122
125
  override = Configuration[override].stringify_keys
123
126
  Hyla::logger.debug("OVERRIDE Keys: #{override.inspect}")
124
127
 
125
- # Read config file if it exists and merge content with DEFAULT config
128
+ # Clone DEFAULTS
129
+ config = DEFAULTS
130
+ Hyla::logger.debug("DEFAULTS Keys: #{config.inspect}")
131
+
132
+ # Read YAML config file IF it exists and
133
+ # Merge content with DEFAULT config
126
134
  new_config = read_config_file(YAML_CONFIG_FILE_NAME)
127
135
  Hyla::logger.debug("OVERRIDE Keys: #{new_config.inspect}") if !new_config.nil?
128
136
  config = config.deep_merge(new_config) if !new_config.nil?
@@ -185,5 +193,20 @@ module Hyla
185
193
  }
186
194
  end
187
195
 
196
+ #
197
+ # Retrieve asciidoctor attributes
198
+ # Could be an Arrays of Strings key=value,key=value
199
+ # or
200
+ # Could be a Hash (DEFAULTS, CONFIG_File)
201
+ def self.extract_attributes(attributes)
202
+ result = attributes.split(',')
203
+ attributes = Hash.new
204
+ result.each do |entry|
205
+ words = entry.split('=')
206
+ attributes[words[0]] = words[1]
207
+ end
208
+ return attributes
209
+ end
210
+
188
211
  end # Class Configuration
189
212
  end # module Hyla