texas 0.1.6 → 0.1.7

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 +15 -0
  2. data/bin/texas +1 -1
  3. data/lib/texas.rb +13 -2
  4. data/lib/texas/build.rb +32 -0
  5. data/lib/texas/build/base.rb +47 -24
  6. data/lib/texas/build/config.rb +118 -0
  7. data/lib/texas/build/config_loader.rb +93 -0
  8. data/lib/texas/build/dry.rb +1 -1
  9. data/lib/texas/build/final.rb +2 -2
  10. data/lib/texas/build/task/add_default_templates_to_build_path.rb +4 -0
  11. data/lib/texas/build/task/base.rb +2 -0
  12. data/lib/texas/build/task/copy_contents_to_build_path.rb +3 -0
  13. data/lib/texas/build/task/execute_after_scripts.rb +18 -0
  14. data/lib/texas/build/task/execute_before_scripts.rb +18 -0
  15. data/lib/texas/build/task/open_pdf.rb +7 -21
  16. data/lib/texas/build/task/publish_pdf.rb +35 -27
  17. data/lib/texas/build/task/run_master_template.rb +2 -0
  18. data/lib/texas/build/task/script.rb +28 -0
  19. data/lib/texas/core_ext.rb +2 -1
  20. data/lib/texas/core_ext/hash.rb +34 -0
  21. data/lib/texas/core_ext/string.rb +1 -128
  22. data/lib/texas/option_parser.rb +153 -124
  23. data/lib/texas/output_helper.rb +58 -0
  24. data/lib/texas/runner.rb +32 -51
  25. data/lib/texas/task/base.rb +1 -0
  26. data/lib/texas/task/new_project.rb +1 -1
  27. data/lib/texas/task/watch.rb +29 -18
  28. data/lib/texas/template.rb +6 -2
  29. data/lib/texas/template/helper/base.rb +60 -9
  30. data/lib/texas/template/helper/tex.rb +2 -4
  31. data/lib/texas/template/runner.rb +2 -5
  32. data/lib/texas/template/runner/base.rb +59 -11
  33. data/lib/texas/template/runner/md.rb +2 -2
  34. data/lib/texas/template/runner/tex.rb +2 -2
  35. data/lib/texas/template/template_error.rb +19 -5
  36. data/lib/texas/version.rb +1 -1
  37. data/spec/fixtures/basic-tex/contents/{unused_template.tex.erb → sub_dir/unused_template.tex.erb} +0 -0
  38. data/spec/fixtures/new-project/lib/init.rb +1 -1
  39. data/spec/fixtures/pdflatex-error/contents/contents.tex.erb +1 -0
  40. data/spec/spec_helper.rb +16 -7
  41. data/spec/texas/build/base_spec.rb +53 -9
  42. data/spec/texas/build/config_spec.rb +73 -0
  43. data/spec/texas/build/task/base_spec.rb +21 -0
  44. data/spec/texas/option_parser_spec.rb +53 -0
  45. data/spec/texas/task/base_spec.rb +49 -0
  46. data/spec/texas_spec.rb +49 -3
  47. metadata +76 -73
  48. data/lib/texas/build/task/run_before_scripts.rb +0 -22
@@ -0,0 +1,58 @@
1
+ module Texas
2
+ # The OutputHelper module provides helper methods to output information
3
+ # to STDOUT.
4
+ module OutputHelper
5
+
6
+ # Puts the given arguments
7
+ #
8
+ def trace(*args)
9
+ puts *args
10
+ end
11
+
12
+ # Traces the result of the given block if Texas is running in verbose mode
13
+ #
14
+ # Example:
15
+ # verbose { "Debug information: " + some_expensive_lookup.to_s }
16
+ #
17
+ def verbose(&block)
18
+ if Texas.verbose
19
+ trace block.()
20
+ end
21
+ end
22
+
23
+ # Traces the result of the given block if warnings are enabled
24
+ #
25
+ # Example:
26
+ # warning { "This might cause problems: " + something.to_s }
27
+ #
28
+ def warning(&block)
29
+ if Texas.warnings
30
+ trace TraceInfo.new("WARNING", block.().to_s, :yellow)
31
+ end
32
+ end
33
+
34
+ class TraceInfo
35
+ COL_LENGTH = 20
36
+
37
+ def initialize(left, right, color = nil)
38
+ @left, @right, @color = left, right, color
39
+ end
40
+
41
+ def left
42
+ l = (@left.to_s + " ").rjust(COL_LENGTH)
43
+ l = l.__send__(@color) if @color
44
+ l.bold
45
+ end
46
+
47
+ def right
48
+ r = @right.to_s
49
+ r = r.__send__(@color) if @color
50
+ r
51
+ end
52
+
53
+ def to_s
54
+ left + right
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,76 +1,57 @@
1
- def verbose(&block)
2
- if Texas.verbose
3
- value = block.()
4
- if value.is_a?(String)
5
- puts value
6
- else
7
- pp value
8
- end
9
- end
10
- end
11
-
12
- def warning(&block)
13
- if Texas.warnings
14
- value = block.()
15
- if value.is_a?(String)
16
- puts "[WARNING]".yellow + " #{value}"
17
- else
18
- pp value
19
- end
20
- end
21
- end
22
-
23
1
  module Texas
2
+ # An instance of Texas::Runner is used to run a build process.
3
+ #
24
4
  class Runner
5
+ include Texas::OutputHelper
6
+
7
+ # Returns the instance of the performed task.
8
+ # Normally a Texas::Build::Base derived object.
9
+ #
25
10
  attr_reader :task_instance
26
11
 
27
- def initialize(force_options = nil)
28
- @options = if force_options.nil?
29
- Texas::OptionParser.new(ARGV).parse
30
- else
31
- opts = Texas::OptionParser.new([]).parse
32
- force_options.each { |k, v| opts.send("#{k}=", v) }
33
- opts
34
- end
12
+ # Initializes the Runner with an array or hash of options.
13
+ #
14
+ # Example:
15
+ # Texas::Runner.new(%w(-w --no-color))
16
+ # Texas::Runner.new(:warnings => true, :colors => false)
17
+ #
18
+ def initialize(args = nil)
19
+ @options = options_from_args args
35
20
  extend_string_class
36
21
  Texas.verbose = @options.verbose
37
22
  Texas.warnings = @options.warnings
38
23
  load_local_libs if @options.load_local_libs
24
+ verbose { TraceInfo.new(:starting, task_class, :magenta) }
39
25
  @task_instance = task_class.new(@options)
40
26
  run
41
27
  end
42
-
43
- # Display the error message that caused the exception.
44
- #
45
- def display_error_message(ex)
46
- puts "#{@options.task} aborted!"
47
- puts ex.message
48
- if @options.backtrace
49
- puts ex.backtrace
50
- else
51
- puts "(See full trace with --backtrace)"
52
- end
53
- end
54
28
 
55
- # Extends String with Term::ANSIColor if options demand it.
29
+ # Extends String with Term::ANSIColor.
56
30
  #
57
31
  def extend_string_class
58
- mod = @options.colors ? Term::ANSIColor : Term::NoColor
59
- String.send :include, mod
32
+ String.send(:include, Term::ANSIColor)
33
+ Term::ANSIColor::coloring = @options.colors
60
34
  end
61
35
 
62
36
  # Load lib/init.rb if present in current project.
63
37
  #
64
38
  def load_local_libs
65
39
  init_file = File.join(@options.work_dir, "lib", "init.rb")
66
- require init_file if File.exist?(init_file)
40
+ load init_file if File.exist?(init_file)
41
+ end
42
+
43
+ def options_from_args(args)
44
+ if args.is_a?(Hash)
45
+ opts = Texas::OptionParser.new([]).parse
46
+ args.each { |k, v| opts.send("#{k}=", v) }
47
+ opts
48
+ else
49
+ Texas::OptionParser.new(args).parse
50
+ end
67
51
  end
68
52
 
69
53
  def run
70
- @task_instance.run
71
- rescue Exception => ex
72
- display_error_message ex
73
- exit 1
54
+ Build.run_with_nice_errors(@task_instance) { exit 1 }
74
55
  end
75
56
 
76
57
  # Returns the class for the given task.
@@ -88,7 +69,7 @@ module Texas
88
69
  begin
89
70
  eval("::Texas::Task::#{class_name}")
90
71
  rescue
91
- puts "Failed to fallback for Texas::Task::#{class_name}"
72
+ trace "Failed to fallback for Texas::Task::#{class_name}"
92
73
  exit
93
74
  end
94
75
  end
@@ -1,6 +1,7 @@
1
1
  module Texas
2
2
  module Task
3
3
  class Base
4
+ include Texas::OutputHelper
4
5
  attr_accessor :options
5
6
 
6
7
  def initialize(_options, _build = nil)
@@ -18,7 +18,7 @@ module Texas
18
18
  if Dir[File.join(dest_dir, "*")].empty?
19
19
  FileUtils.rm_r dest_dir
20
20
  else
21
- warn "texas: directory is not empty: #{dest_dir}"
21
+ trace "texas: directory is not empty: #{dest_dir}"
22
22
  exit 1
23
23
  end
24
24
  end
@@ -8,32 +8,43 @@ module Texas
8
8
  end
9
9
 
10
10
  def run
11
- self.class.run_options = options
11
+ self.class.run_options = options.to_h.merge(:task => :build)
12
12
  dirs = Task::Watch.directories_to_watch
13
13
  Listen.to(*dirs) do |modified, added, removed|
14
14
  Task::Watch.rebuild
15
15
  end
16
16
  end
17
17
 
18
- def self.directories_to_watch
19
- arr = []
20
- arr << "tex" if Dir.exists?("tex")
21
- arr << "contents" if Dir.exists?("contents")
22
- arr << "figures" if Dir.exists?("figures")
23
- arr << Texas.texas_dir
24
- arr
25
- end
18
+ class << self
19
+ include Texas::OutputHelper
26
20
 
27
- def self.rebuild
28
- started_at = Time.now.to_i
29
- Build::Final.new(run_options).run
30
- finished_at = Time.now.to_i
31
- puts (finished_at - started_at).to_s + " seconds to rebuild"
32
- rescue Exception => e
33
- puts @build.current_template.filename
34
- puts "[ERROR] while building \n#{e}"
35
- end
21
+ # Returns the directories watched by default.
22
+ #
23
+ def default_directories
24
+ [Texas.contents_subdir_name, "lib/", Texas.texas_dir]
25
+ end
36
26
 
27
+ # Returns the directories watched, which can be extended.
28
+ #
29
+ # Example:
30
+ # Texas::Task::Watch.directories << "images/"
31
+ #
32
+ def directories
33
+ @@directories ||= default_directories
34
+ end
35
+
36
+ def directories_to_watch
37
+ directories.uniq
38
+ end
39
+
40
+ def rebuild
41
+ started_at = Time.now.to_i
42
+ Texas::Runner.new(run_options)
43
+ finished_at = Time.now.to_i
44
+ time = finished_at - started_at
45
+ trace TraceInfo.new(:rebuild, "in #{time} seconds", :green)
46
+ end
47
+ end
37
48
  end
38
49
  end
39
50
  end
@@ -1,7 +1,11 @@
1
1
  module Texas
2
2
  module Template
3
3
  class << self
4
- attr_accessor :handlers, :known_extensions
4
+ # Returns a map of file extensions to handlers
5
+ attr_accessor :handlers
6
+
7
+ # Returns all known template extensions
8
+ attr_accessor :known_extensions
5
9
 
6
10
  # Returns a template handler for the given filename
7
11
  #
@@ -49,7 +53,7 @@ module Texas
49
53
  #
50
54
  # Example:
51
55
  # Template.create("some_file.tex.erb", build)
52
- # # => #<Template::Runner::TeX ...>
56
+ # # => #<Texas::Template::Runner::TeX ...>
53
57
  #
54
58
  def create(filename, build)
55
59
  handler(filename).new(filename, build)
@@ -19,10 +19,26 @@ module Texas
19
19
  # Returns a subdir with the current template's basename
20
20
  #
21
21
  # Example:
22
- # In /example/introduction.tex.erb this method
23
- # returns "/example/introduction" if that directory exists
24
- # and nil if it doesn't.
22
+ # # Given the following contents directory:
23
+ # #
24
+ # # contents/
25
+ # # section-1/
26
+ # # subsection-1-1.tex.erb
27
+ # # contents.tex.erb
28
+ # # section-1.tex-erb
29
+ # # section-2.tex-erb
30
+ # #
25
31
  #
32
+ # # section-1.tex.erb
33
+ #
34
+ # <%= path_with_templates_basename %>
35
+ # # => "section-1"
36
+ #
37
+ # # section-2.tex.erb
38
+ #
39
+ # <%= path_with_templates_basename %>
40
+ # # => nil
41
+ #
26
42
  def path_with_templates_basename
27
43
  subdir = Template.basename @output_filename
28
44
  File.directory?(subdir) ? subdir : nil
@@ -42,11 +58,8 @@ module Texas
42
58
  #
43
59
  def find_template_file(parts, possible_exts = [], possible_paths = default_search_paths)
44
60
  possible_paths.each do |base|
45
- ([""] + possible_exts).each do |ext|
46
- path = parts.clone.map(&:to_s).map(&:dup)
47
- path.unshift base.to_s
48
- path.last << ".#{ext}" unless ext.empty?
49
- filename = File.join(*path)
61
+ (possible_exts + [""]).each do |ext|
62
+ filename = filename_for_find(parts, base, ext)
50
63
  return filename if File.exist?(filename) && !File.directory?(filename)
51
64
  end
52
65
  end
@@ -63,14 +76,35 @@ module Texas
63
76
  end
64
77
  end
65
78
 
79
+ def filename_for_find(parts, base, ext = nil)
80
+ path = [parts].flatten.map(&:to_s).map(&:dup)
81
+ path.unshift base.to_s
82
+ path.last << ".#{ext}" unless ext.empty?
83
+ File.join(*path)
84
+ end
85
+
66
86
  # Renders a partial with the given locals.
67
87
  #
88
+ # Example:
89
+ # <%= partial :some_partial, :some_value => 42 %>
90
+ #
68
91
  def partial(name, locals = {})
69
92
  render("_#{name}", locals)
70
93
  end
71
94
 
72
95
  # Renders one or more templates with the given locals.
73
96
  #
97
+ # Example:
98
+ # <%= render :template => "some_template" %>
99
+ #
100
+ # # or by shorthand:
101
+ #
102
+ # <%= render :some_template %>
103
+ #
104
+ # # or render multiple templates with a single call:
105
+ #
106
+ # <%= render %w(some_template some_other_template) %>
107
+ #
74
108
  def render(options, locals = {})
75
109
  if [String, Symbol].include?(options.class)
76
110
  options = {:templates => [options]}
@@ -94,12 +128,30 @@ module Texas
94
128
 
95
129
  # Returns all extensions the Template::Runner can handle.
96
130
  #
131
+ # Example:
132
+ # template_extensions
133
+ # # => ["tex", "tex.erb", "md", "md.erb"]
134
+ #
97
135
  def template_extensions
98
136
  Texas::Template.known_extensions
99
137
  end
100
138
 
101
139
  # Returns all templates in the current template's path matching the given glob
102
140
  #
141
+ # Example:
142
+ # # Given the following contents directory:
143
+ # #
144
+ # # contents/
145
+ # # _some_partial.tex.erb
146
+ # # contents.tex.erb
147
+ # # other_latex.tex
148
+ # # other_markdown.md.erb
149
+ # # some_template.tex.erb
150
+ # #
151
+ #
152
+ # templates_by_glob("*.tex.erb")
153
+ # # => ["_some_partial", "contents", "other_markdown", "some_template"]
154
+ #
103
155
  def templates_by_glob(glob = "*")
104
156
  files = Dir[File.join(__path__, glob)]
105
157
  templates = files.map do |f|
@@ -107,7 +159,6 @@ module Texas
107
159
  end
108
160
  templates.uniq.sort
109
161
  end
110
-
111
162
  end
112
163
  end
113
164
  end
@@ -50,12 +50,10 @@ module Texas
50
50
  template.write
51
51
  end
52
52
 
53
- private
54
-
55
53
  # Returns a path relative to the build_path
56
54
  #
57
55
  # Example:
58
- # input_path("/home/rene/github/sample_project/tmp/build/contents.tex.erb")
56
+ # relative_template_filename("/home/rene/github/sample_project/tmp/build/contents.tex.erb")
59
57
  # # => "contents.tex.erb"
60
58
  #
61
59
  def relative_template_filename(path, possible_exts = Template.known_extensions)
@@ -66,7 +64,7 @@ module Texas
66
64
  # Returns a path relative to the build_path and strips the template extension
67
65
  #
68
66
  # Example:
69
- # input_path("/home/rene/github/sample_project/tmp/build/contents.tex.erb")
67
+ # relative_template_basename("/home/rene/github/sample_project/tmp/build/contents.tex.erb")
70
68
  # # => "contents"
71
69
  #
72
70
  def relative_template_basename(path)
@@ -6,8 +6,5 @@ module Texas
6
6
  end
7
7
 
8
8
  require_relative 'runner/base'
9
-
10
- all_rbs = Dir[ File.join( File.dirname(__FILE__), "runner", "*.rb" ) ]
11
- all_rbs.each do |t|
12
- require t
13
- end
9
+ require_relative 'runner/tex'
10
+ require_relative 'runner/md'
@@ -1,13 +1,23 @@
1
- require 'texas/template/helper/base'
2
- require 'texas/template/helper/info'
1
+ require_relative '../helper/base'
2
+ require_relative '../helper/info'
3
3
  require 'erb'
4
4
 
5
5
  module Texas
6
+ # Runs and renders a template.
7
+ #
6
8
  class Template::Runner::Base
9
+ include Texas::OutputHelper
7
10
  include Texas::Template::Helper::Base
8
11
  include Texas::Template::Helper::Info
9
12
 
10
- attr_accessor :build, :content, :filename
13
+ # Returns the build object
14
+ attr_accessor :build
15
+
16
+ # Returns the original content of the template
17
+ attr_accessor :content
18
+
19
+ # Returns the location of the template (in the build directory)
20
+ attr_accessor :filename
11
21
 
12
22
  def initialize(_filename, _build)
13
23
  self.filename = _filename
@@ -16,25 +26,48 @@ module Texas
16
26
  @output_filename = filename.gsub(/(\.erb)$/, '')
17
27
  end
18
28
 
19
- # TODO: Use Forwardable
20
- def root; build.root; end
21
-
29
+ # Shorthand to the build's __path__.
30
+ #
22
31
  def build_path
23
32
  build.__path__
24
33
  end
25
34
 
35
+ # Returns this template's path.
36
+ #
26
37
  def __path__
27
38
  File.dirname filename
28
39
  end
29
40
 
41
+ # Shorthand to the build's config's document object.
42
+ # Can be used inside templates to display config information.
43
+ #
44
+ # Example:
45
+ # <%= document.title %>
46
+ #
30
47
  def document
31
- build.document_struct
48
+ build.config.document
32
49
  end
33
50
 
51
+ # Shorthand to the build's store object.
52
+ # Can be used inside templates to store information.
53
+ #
34
54
  def store
35
55
  build.store
36
56
  end
37
57
 
58
+ # Shorthand to the template's locals object.
59
+ # Can be used inside templates.
60
+ #
61
+ # Example:
62
+ # # some_template.tex.erb
63
+ #
64
+ # Value: <%= o.some_value %>
65
+ #
66
+ # # contents.tex.erb
67
+ #
68
+ # <%= render :some_template, :some_value => 42
69
+ #
70
+ # # => "Value: 42"
38
71
  def o
39
72
  @locals
40
73
  end
@@ -43,17 +76,21 @@ module Texas
43
76
  @erbout << str
44
77
  end
45
78
 
79
+ # Renders the template into a String.
80
+ #
46
81
  def __render__(locals = {})
47
82
  @locals = OpenStruct.new(locals)
48
83
  ERB.new(@content, nil, nil, "@erbout").result(binding)
49
84
  rescue TemplateError => ex
50
85
  raise ex
51
- rescue Exception => ex
86
+ rescue StandardError => ex
52
87
  raise TemplateError.new(self, ex.message, ex)
53
88
  end
54
89
 
90
+ # Runs the template with the given local variables.
91
+ #
55
92
  def __run__(locals = {})
56
- verbose { "[T] #{filename.gsub(build_path, '')}".dark }
93
+ verbose { TraceInfo.new(:template, filename.gsub(build_path, ''), :dark) }
57
94
 
58
95
  old_current_template = build.current_template
59
96
  build.current_template = self
@@ -62,9 +99,20 @@ module Texas
62
99
  @output
63
100
  end
64
101
 
65
- def after_write; end
66
- def after_render(str); str; end
102
+ # Called after write.
103
+ #
104
+ def after_write
105
+ end
106
+
107
+ # Called after __render__.
108
+ # Can be overriden to modify the rendered contents of the template.
109
+ #
110
+ def after_render(str)
111
+ str
112
+ end
67
113
 
114
+ # Runs the template and writes it to disk afterwards.
115
+ #
68
116
  def write
69
117
  __run__
70
118
  File.open(@output_filename, 'w') {|f| f.write(@output) }