hyla 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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