easy_html_generator 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +44 -0
  3. data/LICENSE +22 -0
  4. data/README.md +332 -0
  5. data/bin/ehg +52 -0
  6. data/lib/easy_html_generator.rb +100 -0
  7. data/lib/easy_html_generator/checksum.rb +39 -0
  8. data/lib/easy_html_generator/config.rb +147 -0
  9. data/lib/easy_html_generator/generator.rb +25 -0
  10. data/lib/easy_html_generator/generator/base.rb +83 -0
  11. data/lib/easy_html_generator/generator/combine.rb +28 -0
  12. data/lib/easy_html_generator/generator/compile/coffee.rb +30 -0
  13. data/lib/easy_html_generator/generator/compile/haml.rb +70 -0
  14. data/lib/easy_html_generator/generator/compile/haml/context.rb +52 -0
  15. data/lib/easy_html_generator/generator/compile/haml/helper/activesupport_override.rb +48 -0
  16. data/lib/easy_html_generator/generator/compile/haml/helper/asset_helper.rb +78 -0
  17. data/lib/easy_html_generator/generator/compile/haml/layout.rb +35 -0
  18. data/lib/easy_html_generator/generator/compile/sass.rb +47 -0
  19. data/lib/easy_html_generator/generator/copy.rb +44 -0
  20. data/lib/easy_html_generator/generator/delete.rb +20 -0
  21. data/lib/easy_html_generator/generator/minimize/css.rb +28 -0
  22. data/lib/easy_html_generator/generator/minimize/html.rb +32 -0
  23. data/lib/easy_html_generator/generator/minimize/images.rb +33 -0
  24. data/lib/easy_html_generator/generator/minimize/js.rb +28 -0
  25. data/lib/easy_html_generator/generator/service/analytics.rb +34 -0
  26. data/lib/easy_html_generator/generator/service/bower.rb +34 -0
  27. data/lib/easy_html_generator/generator/service/grunt.rb +24 -0
  28. data/lib/easy_html_generator/generator/structure.rb +20 -0
  29. data/lib/easy_html_generator/generators.rb +53 -0
  30. data/lib/easy_html_generator/project.rb +77 -0
  31. data/lib/easy_html_generator/rackapp.rb +67 -0
  32. data/lib/easy_html_generator/workspace.rb +59 -0
  33. data/src/demo/assets/images/demo.png +0 -0
  34. data/src/demo/assets/public/robots.txt +0 -0
  35. data/src/demo/assets/scripts/demo.js.coffee +1 -0
  36. data/src/demo/assets/scripts/plain.js +0 -0
  37. data/src/demo/assets/styles/app.css.sass +2 -0
  38. data/src/demo/assets/styles/plain.css +0 -0
  39. data/src/demo/lib/generators/project_generator.rb +12 -0
  40. data/src/demo/lib/helper/projecthelper.rb +5 -0
  41. data/src/demo/views/index.html.haml +1 -0
  42. data/src/demo/views/index/_lore_ipsum.haml +1 -0
  43. data/src/demo/views/layout.haml +8 -0
  44. data/src/demo/views/plain.html +0 -0
  45. data/src/shared/assets/images/shared.png +0 -0
  46. data/src/shared/assets/scripts/shared.js.coffee +1 -0
  47. data/src/shared/assets/scripts/shared.plain.js +0 -0
  48. data/src/shared/assets/styles/mixins/_arrows.sass +32 -0
  49. data/src/shared/assets/styles/mixins/_bootstrap-fixes.sass +12 -0
  50. data/src/shared/assets/styles/mixins/_buttons.sass +32 -0
  51. data/src/shared/assets/styles/mixins/_css3.sass +266 -0
  52. data/src/shared/assets/styles/mixins/_headjs-bootstrap-mediaqueries.sass +42 -0
  53. data/src/shared/assets/styles/mixins/_helper.sass +70 -0
  54. data/src/shared/assets/styles/mixins/_normalize.sass +340 -0
  55. data/src/shared/assets/styles/mixins/_reset.sass +46 -0
  56. data/src/shared/lib/generators/shared_generator.rb +12 -0
  57. data/src/shared/lib/helper/shared_helper.rb +16 -0
  58. data/src/shared/project.yml +127 -0
  59. data/src/shared/views/404.yml +5 -0
  60. data/src/template/assets/public/robots.txt +0 -0
  61. data/src/template/assets/scripts/index.js.coffee +1 -0
  62. data/src/template/assets/styles/index.css.sass +2 -0
  63. data/src/template/lib/generators/project_generator.rb +12 -0
  64. data/src/template/lib/helper/project_helper.rb +5 -0
  65. data/src/template/project.yml +128 -0
  66. data/src/template/views/index.html.haml +4 -0
  67. data/src/template/views/index/_lore_ipsum.haml +2 -0
  68. data/src/template/views/layout.haml +9 -0
  69. metadata +402 -0
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ require 'piet'
3
+ require 'easy_html_generator/generator/base'
4
+
5
+ # this generator minifies image files from src folder and copies them
6
+ # to the dist folder
7
+ class EasyHtmlGenerator::Generator::Minimize::Images <
8
+ EasyHtmlGenerator::Generator::Base
9
+
10
+ def initialize(project, config)
11
+ super(project, config)
12
+
13
+ @config.src = project.config.paths.src.images
14
+ @config.dest = project.config.paths.dist.images
15
+ end
16
+
17
+ def do_file(src, target, *args)
18
+ return unless File.exist?(src) && File.file?(src)
19
+ log "-> do_file #{src}"
20
+
21
+ FileUtils.mkdir_p File.dirname(target)
22
+
23
+ args.push target
24
+
25
+ FileUtils.copy(src, target)
26
+
27
+ Piet.optimize(target, @config.options)
28
+
29
+ EasyHtmlGenerator::Checksum.store_file(src)
30
+ rescue StandardError
31
+ log '-> you have to install "optipng" and "jpegoptim"'.red
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ require 'uglifier'
3
+ require 'easy_html_generator/generator/base'
4
+
5
+ # this generator minifies js files from src folder and copies them
6
+ # to the dist folder
7
+ class EasyHtmlGenerator::Generator::Minimize::Js <
8
+ EasyHtmlGenerator::Generator::Base
9
+
10
+ def initialize(project, config)
11
+ super(project, config)
12
+
13
+ @config.src = project.config.paths.src.scripts
14
+ @config.dest = project.config.paths.dist.scripts
15
+ end
16
+
17
+ def do_input(input, *_args)
18
+ self.class.compress input
19
+ end
20
+
21
+ def input_to_output_file(i)
22
+ super(i).gsub('.js', "#{@config.prefix_extension}.js")
23
+ end
24
+
25
+ def self.compress(input)
26
+ Uglifier.compile input
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ require 'easy_html_generator/generator/base'
3
+
4
+ # this generator adds web tracking snippets to files in the dist folder
5
+ class EasyHtmlGenerator::Generator::Service::Analytics <
6
+ EasyHtmlGenerator::Generator::Base
7
+
8
+ def generate
9
+ return unless @config.enabled
10
+
11
+ log_running
12
+
13
+ selector = File.join(@project.dist_path_to(:views),
14
+ @config.append_to_files)
15
+ Dir[selector].each do |file|
16
+ do_google file
17
+ end
18
+ end
19
+
20
+ def do_google(file)
21
+ return unless @config.google.enabled
22
+
23
+ content = File.read(file)
24
+ return if file.include? '<!-- Google Analytics -->'
25
+
26
+ code = @config.google.code.sub('{GOOGLE_UA_ID}', @config.google.id)
27
+
28
+ code = "<!-- Google Analytics -->#{code}<!-- End Google Analytics -->"
29
+
30
+ content = content.sub('</head>', "#{code}</head>")
31
+
32
+ File.write(file, content)
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ require 'fileutils'
3
+ require 'easy_html_generator/generator/base'
4
+
5
+ # this generator resolves and runs a bower.json
6
+ class EasyHtmlGenerator::Generator::Service::Bower <
7
+ EasyHtmlGenerator::Generator::Base
8
+
9
+ def initialize(project, config)
10
+ super(project, config)
11
+
12
+ @config.src = ''
13
+ @config.dest = ''
14
+ end
15
+
16
+ def do_file(bower_file, *_args)
17
+ input_folder = File.dirname(bower_file)
18
+ output_folder = File.join(@project.dist_path_to(:scripts), @config.target)
19
+
20
+ cmd = "cd #{input_folder} && bower install"
21
+ cmd = "if which bower >/dev/null; then echo '\e[32mrunning bower\e[0m' \
22
+ && #{cmd}; else echo '\e[31mplease install bower \
23
+ \"npm install -g bower\" http://bower.io/ \e[0m'; fi"
24
+
25
+ log ` #{cmd} `
26
+
27
+ FileUtils.mkdir_p output_folder
28
+
29
+ EasyHtmlGenerator::Generator::Copy.copy_r(
30
+ "#{input_folder}/bower_components", output_folder, '**/*')
31
+
32
+ EasyHtmlGenerator::Checksum.store_file(bower_file)
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require 'easy_html_generator/generator/base'
3
+
4
+ # this generator resolves and runs a Gruntfile
5
+ class EasyHtmlGenerator::Generator::Service::Grunt <
6
+ EasyHtmlGenerator::Generator::Base
7
+
8
+ def initialize(project, config)
9
+ super(project, config)
10
+
11
+ @config.src = ''
12
+ @config.dest = ''
13
+ end
14
+
15
+ def do_file(grunt_file, *_args)
16
+ input_folder = File.dirname(grunt_file)
17
+
18
+ cmd = "cd #{input_folder} && npm install && grunt #{@config.task}"
19
+ cmd = "if which grunt >/dev/null; then echo '\e[32m | ->running grunt \
20
+ \e[0m' && #{cmd}; else echo '\e[31mplease install grunt \
21
+ \"npm install -g grunt\" http://gruntjs.com/ \e[0m'; fi"
22
+ log ` #{cmd} `
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ require 'find'
3
+ require 'fileutils'
4
+ require 'easy_html_generator/generator/base'
5
+
6
+ # this generator creates dist paths
7
+ class EasyHtmlGenerator::Generator::Structure <
8
+ EasyHtmlGenerator::Generator::Base
9
+
10
+ def generate
11
+ return unless @config.enabled
12
+
13
+ log_running
14
+
15
+ @project.config.paths.dist.each do |_index, dir|
16
+ next if dir.empty?
17
+ FileUtils.mkdir_p("#{@project.dist_path}/#{dir}")
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ # this class handles multiple generators for a project
4
+ class EasyHtmlGenerator::Generators
5
+ def initialize(project)
6
+ @project = project
7
+ @generators = load_generators
8
+ end
9
+
10
+ def generate
11
+ @generators.each do |_index, generator|
12
+ generator.generate
13
+ end
14
+ end
15
+
16
+ def generator_class_by_name(name)
17
+ name = name.split('_').map { |n| capitalize(n) }.join('::')
18
+ capitalize(name) # if there is no _
19
+
20
+ "EasyHtmlGenerator::Generator::#{name}"
21
+ end
22
+
23
+ private
24
+
25
+ def capitalize(input)
26
+ input.slice(0, 1).capitalize + input.slice(1..-1)
27
+ end
28
+
29
+ def load_generators
30
+ Dir[@project.src_path_to(:generators, '**/*.rb'),
31
+ EasyHtmlGenerator::SHARED_GENERATORS_PATH + '/**/*.rb']
32
+ .each { |file| load file }
33
+
34
+ result = {}
35
+ @project.config.generators.each.map do |generator|
36
+ name, config = generator.first
37
+ result[name] = generator_by_name(name.to_s, config)
38
+ end
39
+ result
40
+ end
41
+
42
+ def generator_by_name(name, config)
43
+ clazz = Object.const_get generator_class_by_name(name)
44
+
45
+ clazz.new(@project, config)
46
+ end
47
+
48
+ def method_missing(name, *args)
49
+ return super.method_missing name unless @generators.key? name
50
+
51
+ @generators[name]
52
+ end
53
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+
3
+ # this class represents a project and handles generators and ressources
4
+ class EasyHtmlGenerator::Project
5
+ attr_reader :src_path, :dist_path, :name, :generators, :config
6
+
7
+ def initialize(name, src_path, dist_path, config_file)
8
+ @name = name
9
+ @src_path = src_path
10
+ @dist_path = dist_path
11
+
12
+ @config_file = config_file
13
+ load_config config_file
14
+ load_generators
15
+ end
16
+
17
+ def src_path_to(type, relative_path = '')
18
+ File.join(@src_path, @config.paths.src[type.to_sym], relative_path)
19
+ end
20
+
21
+ def dist_path_to(type, relative_path = '')
22
+ File.join(@dist_path, @config.paths.dist[type.to_sym], relative_path)
23
+ end
24
+
25
+ def uri_path_to(type, relative_path = '')
26
+ File.join('/', @name, @config.paths.dist[type.to_sym], relative_path)
27
+ end
28
+
29
+ def generate
30
+ STDERR.puts ''
31
+ STDERR.puts ' -----------------------------'.green
32
+ STDERR.puts " | compiling project #{@name}".green
33
+ STDERR.puts ' -----------------------------'.green
34
+
35
+ reaload_if_config_changed
36
+
37
+ @generators.generate
38
+ end
39
+
40
+ def list_dir(_relative_path = '/')
41
+ dir_pattern = File.join(src_path_to(:views), '*.html*')
42
+
43
+ dirs = Dir[dir_pattern].map { |file| file.sub('.html.haml', '.html') }
44
+
45
+ dirs.map { |file| file.sub(src_path_to(:views), "#{name}/") }
46
+ end
47
+
48
+ def should_generate_for?(path)
49
+ return true unless path
50
+
51
+ @config.generate_on_request_path_match.each do |pattern|
52
+ return true if pattern.match path
53
+ end
54
+
55
+ false
56
+ end
57
+
58
+ private
59
+
60
+ def load_config(file)
61
+ @config = EasyHtmlGenerator::Config.from_file file
62
+ @config[:generate_on_request_path_match].map! { |p| Regexp.new(p) }
63
+ EasyHtmlGenerator::Checksum.store_file file
64
+ end
65
+
66
+ def load_generators
67
+ @generators = EasyHtmlGenerator::Generators.new self
68
+ end
69
+
70
+ def reaload_if_config_changed
71
+ return unless EasyHtmlGenerator::Checksum.file_changed? @config_file
72
+ STDERR.puts " | -> reloading config(#{@config_file.green})"
73
+
74
+ load_config @config_file
75
+ load_generators
76
+ end
77
+ end
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+ require 'rack'
3
+ require 'rack/abstract_format'
4
+ require 'rack/respond_to'
5
+
6
+ # this is the rack application for ehg
7
+ class EasyHtmlGenerator::Rackapp
8
+ include Rack::RespondTo
9
+
10
+ EHG_URL = 'https://github.com/creative-workflow/easy-html-generator'
11
+ LIST_BODY = "<!DOCTYPE html><html><head>
12
+ <style>*{ font-size: 20px;
13
+ font-family: Verdana, 'Lucida Sans Unicode', sans-serif;}
14
+ a,a:hover{text-decoration: none; color: #818181;}
15
+ </style></head>
16
+ <body>
17
+ {CONTENT}
18
+ <a target='_blank' href='#{EHG_URL}'>ehc on Github</a></body></html>"
19
+
20
+ def self.call(env)
21
+ Rack::RespondTo.env = env
22
+ request = Rack::Request.new(env)
23
+
24
+ case request.path_info
25
+ when '/'
26
+ list_dir
27
+ else
28
+ dispatch(request)
29
+ end
30
+ end
31
+
32
+ def self.respond(body, status_code = 200)
33
+ content_type = Rack::RespondTo.selected_media_type || 'text/html'
34
+
35
+ [status_code, { 'Content-Type' => "#{content_type}; charset=UTF-8" }, [body || '']]
36
+ end
37
+
38
+ def self.dispatch(request)
39
+ file = EasyHtmlGenerator.dispatch(request)
40
+
41
+ if File.exist? file
42
+ respond(File.read(file))
43
+ else
44
+ respond("404 not found #{file}", 404)
45
+ end
46
+ end
47
+
48
+ def self.list_dir
49
+ content = ''
50
+ EasyHtmlGenerator.projects.each do |_name, project|
51
+ content += "<h3>#{project.name}</h3>"
52
+ project.list_dir.each do |file|
53
+ content += build_list_dir_row(file)
54
+ end
55
+ end
56
+ content = LIST_BODY.sub('{CONTENT}', "<ul>#{content}</ul>")
57
+
58
+ respond(content)
59
+ end
60
+
61
+ def self.build_list_dir_row(file)
62
+ f = File.path(file)
63
+ f_name = File.basename(f)
64
+ f_path = File.dirname(f)
65
+ "<li><a href='#{f_path}/#{f_name}'><b>#{f_path}</b>/#{f_name}</a></li>"
66
+ end
67
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+ require 'fileutils'
3
+
4
+ # this class creates project instances
5
+ class EasyHtmlGenerator::Workspace
6
+ @project_instances = {}
7
+
8
+ def self.projects
9
+ if @project_instances.empty?
10
+ project_folders.each do |path|
11
+ next if path.include? 'shared'
12
+ p = project_instance_from_path path
13
+ @project_instances[p.name.to_sym] = p
14
+ end
15
+ end
16
+
17
+ @project_instances
18
+ end
19
+
20
+ def self.project_folders
21
+ Dir[File.join(EasyHtmlGenerator::SRC_PATH, '*')]
22
+ .reject { |o| !File.directory?(o) }
23
+ .map { |o| File.expand_path(o) }
24
+ end
25
+
26
+ def self.create_project(name)
27
+ FileUtils.cp_r(
28
+ File.join(EasyHtmlGenerator::EHC_SRC_PATH, 'template'),
29
+ File.join(EasyHtmlGenerator::SRC_PATH, name))
30
+ end
31
+
32
+ def self.init
33
+ EasyHtmlGenerator::CREATE_ON_INIT.each do |dir|
34
+ FileUtils.mkdir_p dir
35
+ end
36
+
37
+ EasyHtmlGenerator::COPY_ON_INIT.each do |src, target|
38
+ FileUtils.cp_r src, target
39
+ end
40
+ end
41
+
42
+ def self.project_instance_from_path(path)
43
+ name = path.split('/').last.sub('/', '')
44
+
45
+ config_file = "#{EasyHtmlGenerator::SHARED_PATH}/project.yml"
46
+ config_file = "#{path}/project.yml" if File.exist? "#{path}/project.yml"
47
+
48
+ EasyHtmlGenerator::Project.new(
49
+ name,
50
+ "#{EasyHtmlGenerator::SRC_PATH}/#{name}",
51
+ "#{EasyHtmlGenerator::DIST_PATH}/#{name}",
52
+ config_file
53
+ )
54
+ end
55
+
56
+ def self.project_by_name(name)
57
+ projects[name.to_sym]
58
+ end
59
+ end
Binary file