texas 0.1.6 → 0.1.7

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 +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) }