erbtex 0.4.3 → 0.5.0

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.
data/bin/erbtex CHANGED
@@ -1,8 +1,29 @@
1
1
  #! /usr/bin/env ruby
2
+ #
3
+ # frozen_string_literal: true
2
4
 
3
5
  require 'erbtex'
4
6
 
7
+ # Name space module for erbtex's ruby pre-processing of TeX and LaTeX files by
8
+ # ruby.
5
9
  module ErbTeX
6
- cl = CommandLine.new(ARGV)
7
- exit ErbTeX.run(cl).exitstatus
10
+ if ARGV.empty?
11
+ warn 'usage: erbtex [LaTex_filename]'
12
+ exit(1)
13
+ end
14
+
15
+ begin
16
+ cl = CommandLine.new(ARGV)
17
+ status = ErbTeX.run(cl)
18
+ rescue OutputExists => e
19
+ warn "Warning: #{e}"
20
+ status = 1
21
+ rescue SystemCallError, ArgumentError, NoInputFile => e
22
+ warn "Error: #{e}"
23
+ status = 1
24
+ rescue ScriptError => e
25
+ warn "Erubis pre-processing failed: #{e}"
26
+ status = 1
27
+ end
28
+ exit status
8
29
  end
data/erbtex.gemspec CHANGED
@@ -1,33 +1,32 @@
1
- # -*- encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
- require "./lib/erbtex/version.rb"
3
+ require './lib/erbtex/version'
4
4
 
5
5
  Gem::Specification.new do |gem|
6
- gem.name = %q{erbtex}
6
+ gem.name = 'erbtex'
7
+ gem.license = 'MIT'
7
8
  gem.version = ErbTeX::VERSION
8
9
  gem.platform = Gem::Platform::RUBY
9
- gem.date = %q{2012-05-13}
10
10
  gem.homepage = 'https://github.com/ddoherty03/erbtex'
11
11
  gem.authors = ['Daniel E. Doherty']
12
- gem.email = %q{ded@ddoherty.net}
13
- gem.summary = %q{Preprocesses TeX and LaTeX files with erubis for ruby.}
14
- gem.description = %q{erbtex will act just like pdflatex except that it will
12
+ gem.email = 'ded@ddoherty.net'
13
+ gem.summary = 'Preprocesses TeX and LaTeX files with erubis for ruby.'
14
+ gem.description = 'erbtex will act just like pdflatex except that it will
15
15
  process ruby fragments between {: and :} markers,
16
16
  greatly expanding the ability to generate
17
- automated TeX and LaTeX documents.}
18
- gem.files = `git ls-files`.split("\n")
17
+ automated TeX and LaTeX documents.'
18
+ gem.files = %x(git ls-files).split("\n")
19
19
  gem.files.delete_if { |f| f =~ /\.(log|etc|aux|etx|pdf|gem|tmp)$/ }
20
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ gem.executables = %x(git ls-files -- bin/*).split("\n").map { |f| File.basename(f) }
22
21
  gem.require_paths = ['lib']
23
22
 
24
23
  gem.add_dependency 'erubis'
25
24
  gem.add_dependency 'fat_core'
26
- gem.add_development_dependency 'rake'
27
25
  gem.add_development_dependency 'bundler'
28
- gem.add_development_dependency 'rspec'
29
26
  gem.add_development_dependency 'minitest'
30
27
  gem.add_development_dependency 'pry'
31
- gem.add_development_dependency 'pry-doc'
32
28
  gem.add_development_dependency 'pry-byebug'
29
+ gem.add_development_dependency 'pry-doc'
30
+ gem.add_development_dependency 'rake'
31
+ gem.add_development_dependency 'rspec'
33
32
  end
@@ -55,7 +55,7 @@
55
55
  ## increments of step.
56
56
 
57
57
  require 'bigdecimal'
58
- require 'dms'
58
+ require_relative 'dms'
59
59
  DMS.precision = 0
60
60
  step = DMS.new(0, 0, 30)
61
61
  one = BigDecimal("1.0")
@@ -130,4 +130,4 @@
130
130
  \end{longtable}
131
131
  \end{document}
132
132
 
133
- % Take /that/ Charles Babbage!
133
+ % Take /that/ Charles Babbage!
data/examples/dms.rb CHANGED
@@ -1,27 +1,30 @@
1
- #! /usr/bin/ruby
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # frozen_string_literal: true
4
+
5
+ require_relative "int_ext"
2
6
 
3
7
  # A class for maipulating angles expressed as degreed, minutes,
4
8
  # and seconds.
5
9
  class DMS
6
10
  include Comparable
7
11
 
8
- attr_reader :degrees, :minutes, :seconds
9
-
10
- @@precision = 4
12
+ attr_accessor :degrees, :minutes, :seconds, :precision
11
13
 
12
- def initialize(deg, min = 0, sec = 0.0)
14
+ def initialize(deg, min = 0, sec = 0.0, precision: 4)
13
15
  @degrees = deg.to_i
14
16
  @minutes = min.to_i
15
17
  @seconds = sec.to_f
18
+ @precision = precision
16
19
  normalize
17
20
  end
18
21
 
19
22
  def self.from_radians(rad)
20
- if rad < 0
23
+ if rad.negative?
21
24
  rad = -rad
22
- sign = -1
25
+ -1
23
26
  else
24
- sign = 1
27
+ 1
25
28
  end
26
29
  deg = rad * (360.0 / (2.0 * Math::PI))
27
30
  degrees = deg.floor
@@ -31,16 +34,12 @@ class DMS
31
34
  DMS.new(degrees, minutes, seconds)
32
35
  end
33
36
 
34
- def self.precision=(p)
35
- @@precision = p
36
- end
37
-
38
37
  def to_s
39
- "#{@degrees}* #{@minutes}' %0.*f''" % [@@precision, @seconds]
38
+ format("#{degrees}* #{minutes}' %0.*f''", precision, seconds)
40
39
  end
41
40
 
42
41
  def to_f
43
- @degrees.to_f + (@minutes / 60.0) + (@seconds / 3600.0)
42
+ degrees.to_f + (minutes / 60.0) + (seconds / 3600.0)
44
43
  end
45
44
 
46
45
  def to_radians
@@ -50,13 +49,11 @@ class DMS
50
49
  # If degrees are at well-known values, eppress as radians
51
50
  # symbolically, using TeX notation
52
51
  def to_radians_tex
53
- unless @seconds == 0.0 and @minutes == 0
54
- return '$%0.*f$' % [@@precision, to_radians]
55
- end
52
+ return format('$%0.*f$', precision, to_radians) unless (@seconds == 0.0) && @minutes.zero?
56
53
 
57
54
  # This gets deg to 0 <= x <= 360, even for negative
58
55
  # values of @degrees
59
- deg = @degrees.divmod(360)[1]
56
+ deg = degrees.divmod(360)[1]
60
57
  case deg
61
58
  when 0
62
59
  '$0$'
@@ -85,20 +82,20 @@ class DMS
85
82
  when 360
86
83
  '$2\\pi$'
87
84
  else
88
- '$%0.*f$' % [@@precision, to_radians]
85
+ format('$%0.*f$', precision, to_radians)
89
86
  end
90
87
  end
91
88
 
92
89
  def to_tex
93
- "$%02d^\\circ~%02d'~%02.*f''$" % [@degrees, @minutes, @@precision, @seconds] #"
90
+ format("$%02d^\\circ~%02d'~%02.*f''$", degrees, minutes, precision, seconds) # "
94
91
  end
95
92
 
96
93
  def -@
97
- DMS.new(-@degrees, @minutes, @seconds)
94
+ DMS.new(-degrees, minutes, seconds)
98
95
  end
99
96
 
100
97
  def +@
101
- DMS.new(@degrees, @minutes, @seconds)
98
+ DMS.new(degrees, minutes, seconds)
102
99
  end
103
100
 
104
101
  def <=>(other)
@@ -106,23 +103,23 @@ class DMS
106
103
  end
107
104
 
108
105
  def +(other)
109
- seconds = @seconds + other.seconds
110
- minutes = @minutes + other.minutes
111
- degrees = @degrees + other.degrees
106
+ seconds += other.seconds
107
+ minutes += other.minutes
108
+ degrees += other.degrees
112
109
  DMS.new(degrees, minutes, seconds)
113
110
  end
114
111
 
115
112
  def -(other)
116
- r = (self + (-other))
117
- DMS.new(r.degrees, r.minutes, r.seconds)
113
+ diff = (self + -other)
114
+ DMS.new(diff.degrees, diff.minutes, diff.seconds)
118
115
  end
119
116
 
120
- def *(scalar)
121
- DMS.new(scalar*@degrees, scalar*@minutes, scalar*@seconds)
117
+ def *(other)
118
+ DMS.new(other * degrees, other * minutes, other * seconds)
122
119
  end
123
120
 
124
- def /(scalar)
125
- DMS.new(@degrees / scalar, @minutes / scalar, @seconds / scalar)
121
+ def /(other)
122
+ DMS.new(@degrees / other, @minutes / other, @seconds / other)
126
123
  end
127
124
 
128
125
  def sin
@@ -153,28 +150,16 @@ class DMS
153
150
  # After normalization, only degrees can be negative,
154
151
  # which will represent a negative quantity
155
152
  def normalize
156
- q, r = @seconds.divmod(60.0)
157
- @seconds = r
158
- @minutes += q
159
- q, r = @minutes.divmod(60)
160
- @minutes = r
161
- @degrees += q
162
- end
163
- end
164
-
165
- class Integer
166
- alias times *
167
- def *(other)
168
- case other
169
- when DMS
170
- other * self
171
- else
172
- times(other)
173
- end
153
+ q, r = seconds.divmod(60.0)
154
+ self.seconds = r
155
+ self.minutes += q
156
+ q, r = minutes.divmod(60)
157
+ self.minutes = r
158
+ self.degrees += q
174
159
  end
175
160
  end
176
161
 
177
- if __FILE__ == $0
162
+ if __FILE__ == $PROGRAM_NAME
178
163
  print "Fifty seconds in radians: #{DMS.new(0, 0, 50).to_radians}\n"
179
164
  print "One minute in radians: #{DMS.new(0, 1, 0).to_radians}\n"
180
165
  print "Fifty seconds in degrees: #{DMS.new(0, 0, 50).to_f}\n"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Integer
4
+ alias_method :times, :*
5
+ def *(other)
6
+ case other
7
+ when DMS
8
+ other * self
9
+ else
10
+ times(other)
11
+ end
12
+ end
13
+ end
data/examples/testbind.rb CHANGED
@@ -1,3 +1,4 @@
1
- x = 1957
1
+ # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable-next Style/GlobalVars
3
4
  $x = 1957
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  # Name space for erbtex command.
4
4
  module ErbTeX
@@ -6,61 +6,46 @@ module ErbTeX
6
6
 
7
7
  # Class to record and manipulate the command line typed by the user.
8
8
  class CommandLine
9
- attr_reader :erbtex_name, :tex_program, :tex_args, :tex_commands
10
- attr_reader :input_file, :print_version, :print_help
9
+ attr_reader :erbtex_name, :tex_program, :tex_args, :tex_commands, :input_file, :print_version, :print_help
10
+ attr_reader :preprocess_only, :no_clobber
11
11
 
12
12
  def initialize(argv)
13
- # Note: argv will be the command line arguments after processing by the
14
- # shell, so if we see things such as '&', '~', '\' in the args, these
15
- # were quoted by the user on the command-line and need no special
16
- # treatment here. For example, '~/junk' on the commandline will show up
17
- # here as '/home/ded/junk'. If we see '~/junk', that means the user has
18
- # quoted the ~ on the command line with something like '\~junk', so we
19
- # should assume that the user wants to keep it that way. Likewise, an
20
- # arg with spaces in it will have been quoted by the user to be seen as
21
- # a single argument. When we output these for use by the shell in the
22
- # system command, we should apply shellquote to everything so that the
23
- # receiving shell sees the args in the same way.
13
+ # Arguments have already been split by the shell. Preserve each string
14
+ # unchanged and pass it directly to the TeX process.
24
15
 
25
16
  @erbtex_name = File.basename($PROGRAM_NAME)
26
17
 
27
18
  # Find the tex_commands
28
19
  @tex_commands = []
29
- if argv.any? { |a| a =~ /\A\\/ }
20
+ if argv.any? { |a| a.start_with?('\\') }
30
21
  # All args after first starting with '\' should be interpreted as TeX
31
22
  # commands, even if they don't start with '\'
32
23
  @tex_commands = argv.drop_while { |a| a !~ /\A\\/ }
33
24
  first_tex_command_k = argv.size - @tex_commands.size
34
- argv = argv[0..first_tex_command_k - 1]
25
+ argv = argv.take(first_tex_command_k)
35
26
  end
36
27
 
37
- # Look for our --invoke=tex_command option
38
- @tex_program = 'pdflatex'
39
- if argv.any? { |a| a =~ /\A--invoke=(\w+)/ }
40
- @tex_program = $1
41
- argv.reject! { |a| a =~ /\A--invoke=(\w+)/ }
28
+ # Keep the complete executable name, including paths and punctuation.
29
+ invoke_options = argv.select { |argument| argument.start_with?('--invoke=') }
30
+ if invoke_options.include?('--invoke=')
31
+ raise ArgumentError, '--invoke requires a nonempty executable name'
42
32
  end
43
33
 
44
- # Look for our --version
45
- @print_version = false
46
- if argv.any? { |a| a =~ /\A--version/ }
47
- @print_version = true
48
- argv.reject! { |a| a =~ /\A--version/ }
49
- end
34
+ @tex_program = invoke_options.first&.delete_prefix('--invoke=') || 'pdflatex'
35
+ argv = argv.reject { |argument| argument.start_with?('--invoke=') }
50
36
 
51
- # Look for our --help
52
- @print_help = false
53
- if argv.any? { |a| a =~ /\A--help/ }
54
- @print_help = true
55
- argv.reject! { |a| a =~ /\A--help/ }
56
- end
37
+ @print_version = argv.include?('--version')
38
+ @print_help = argv.include?('--help')
39
+ @preprocess_only = argv.include?('--preprocess-only')
40
+ @no_clobber = argv.include?('--no-clobber')
41
+ argv = argv.reject { |argument| argument == '--version' || argument == '--help' }
42
+ argv = argv.reject { |argument| argument == '--preprocess-only' }
43
+ argv = argv.reject { |argument| argument == '--no-clobber' }
57
44
 
58
45
  # The last argument, assuming it does not start with a '-' or '&', is
59
46
  # assumed to be the name of the input_file.
60
47
  @input_file = nil
61
- if !argv.empty? && argv[-1] !~ /\A[-&]/
62
- @input_file = ErbTeX.expand_input_file(argv.pop)
63
- end
48
+ @input_file = ErbTeX.expand_input_file(argv.pop) if !argv.empty? && argv[-1] !~ /\A[-&]/
64
49
 
65
50
  # What remains in argv should be the tex program's '-options', which
66
51
  # should be passed through untouched. So, can form the full command line
@@ -69,11 +54,7 @@ module ErbTeX
69
54
  end
70
55
 
71
56
  def tex_command(tex_file = input_file)
72
- "#{tex_program} " \
73
- "#{tex_args.shelljoin} " \
74
- "#{tex_commands.shelljoin} " \
75
- "#{tex_file}"
76
- .strip.squeeze(' ')
57
+ [tex_program, *tex_args, tex_file, *tex_commands].compact
77
58
  end
78
59
  end
79
60
  end
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Name space module for ErbTeX.
1
4
  module ErbTeX
2
5
  # Given an arbitrary file name, parse it into its components in one go. It
3
6
  # separates three parts of a filename: (1) the directory, if any, (2) the
@@ -5,7 +8,7 @@ module ErbTeX
5
8
  # name rather than an extension, and (3) any extension, including a compound
6
9
  # extension such as .tex.erb
7
10
  def self.parse_file_name(path)
8
- fn_re = %r{\A(?<dir>([^\/]*\/)*) (?<base>.?[^\/.]*) (?<ext>\.[\w.]+)?}x
11
+ fn_re = %r{\A(?<dir>([^/]*/)*) (?<base>.?[^/.]*) (?<ext>\.[\w.]+)?}x
9
12
  md = fn_re.match(path)
10
13
  { dir: md[:dir], base: md[:base], ext: md[:ext] }
11
14
  end
data/lib/erbtex/runner.rb CHANGED
@@ -1,17 +1,33 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tempfile'
2
4
  require 'pathname'
3
5
  require 'English'
4
6
 
5
7
  # Name space module for erbtex program.
6
8
  module ErbTeX
9
+ GENERATED_MARKER = '% Generated by erbtex. Changes may be overwritten.'
10
+
11
+ class OutputExists < StandardError; end
12
+
7
13
  # Perform the erubis pre-processing and the TeX processing on the input
8
- # file.
14
+ # file. Return an exit status; preprocessing errors propagate to the caller.
9
15
  def self.run(cmd_line)
10
- report_version && exit(0) if cmd_line.print_version
11
- report_help && exit(0) if cmd_line.print_help
16
+ return report_version if cmd_line.print_version
17
+
18
+ if cmd_line.print_help
19
+ report_help
20
+ return 0
21
+ end
22
+
23
+ if cmd_line.preprocess_only && !cmd_line.input_file
24
+ raise NoInputFile, '--preprocess-only requires an input file'
25
+ end
26
+
27
+ in_dir = parse_file_name(cmd_line.input_file)[:dir] if cmd_line.input_file
28
+ tex_file = erb_to_tex(cmd_line.input_file, in_dir, no_clobber: cmd_line.no_clobber) if cmd_line.input_file
29
+ return 0 if cmd_line.preprocess_only
12
30
 
13
- in_dir = parse_file_name(cmd_line.input_file)[:dir]
14
- tex_file = erb_to_tex(cmd_line.input_file, in_dir) if cmd_line.input_file
15
31
  run_tex(cmd_line.tex_command(tex_file), in_dir)
16
32
  end
17
33
 
@@ -19,13 +35,13 @@ module ErbTeX
19
35
  puts "erbtex version: #{ErbTeX::VERSION}"
20
36
  puts "Ruby version: #{RUBY_VERSION}"
21
37
  begin
22
- erubis_version = `erubis -v`
38
+ erubis_version = %x(erubis -v)
23
39
  rescue Errno::ENOENT
24
40
  warn 'Warning: erubis does not appear to be installed!'
25
- exit(1)
41
+ return 1
26
42
  end
27
43
  puts "erubis version: #{erubis_version}"
28
- true
44
+ 0
29
45
  end
30
46
 
31
47
  # Display the help for erbtex.
@@ -36,6 +52,9 @@ module ErbTeX
36
52
  erbtex_options are:
37
53
  --version - print the version of the erbtex gem, ruby and erubis
38
54
  --help - print this help message
55
+ --no-clobber - refuse to overwrite any existing preprocessed file
56
+ --preprocess-only - generate the preprocessed file without invoking TeX
57
+ (requires an input file)
39
58
  --invoke=<tex_prog> - after pre-processing, invoke <tex_prog> on the
40
59
  resulting file, tex_prog is pdflatex by default
41
60
 
@@ -49,7 +68,6 @@ module ErbTeX
49
68
  as an argument to the tex-prog.
50
69
 
51
70
  HELP
52
- true
53
71
  end
54
72
 
55
73
  # Run the TeX program on the erubis-processed output file, which is the
@@ -57,7 +75,9 @@ module ErbTeX
57
75
  def self.run_tex(cmd, in_dir = nil)
58
76
  # If the input file is located in another directory (in_dir), add that
59
77
  # directory to TEXINPUTS if its not already there so that the input file
60
- # can \include or \input files using relative file names.
78
+ # can \include or \input files using relative file names. Place it after
79
+ # the current directory '.' so that an plain file name is still
80
+ # interpreted relative to the current working directory.
61
81
  new_env = {}
62
82
  if in_dir
63
83
  in_dir = File.absolute_path(File.expand_path(in_dir))
@@ -65,32 +85,39 @@ module ErbTeX
65
85
  unless ENV['TEXINPUTS'].split(File::PATH_SEPARATOR)
66
86
  .reject { |p| p.strip.empty? }
67
87
  .any? { |p| in_dir == File.absolute_path(File.expand_path(p)) }
68
- new_env['TEXINPUTS'] = "#{in_dir}:#{ENV['TEXINPUTS']}"
88
+ new_env['TEXINPUTS'] = ".:#{in_dir}:#{ENV['TEXINPUTS']}"
69
89
  end
70
90
  end
71
91
  # Call cmd with the environment augmented by possibly expanded TEXINPUTS
72
92
  # environment variable.
73
- unless system(new_env, cmd)
74
- warn "Call to '#{cmd}' failed."
75
- exit $CHILD_STATUS
93
+ warn "TEXINPUTS set to: #{new_env['TEXINPUTS']}"
94
+ unless system(new_env, [cmd.first, cmd.first], *cmd.drop(1))
95
+ warn "Call to '#{cmd.shelljoin}' failed."
96
+ return $CHILD_STATUS.exitstatus || 128 + $CHILD_STATUS.termsig
76
97
  end
77
98
  # Run a second time unless its latexmk
78
- unless cmd =~ /\A *latexmk/
79
- unless system(new_env, cmd)
80
- warn "Call to '#{cmd}' failed."
81
- exit $CHILD_STATUS
99
+ unless File.basename(cmd.first) == 'latexmk'
100
+ warn "TEXINPUTS set to: #{new_env['TEXINPUTS']}"
101
+ unless system(new_env, [cmd.first, cmd.first], *cmd.drop(1))
102
+ warn "Call to '#{cmd.shelljoin}' failed."
103
+ return $CHILD_STATUS.exitstatus || 128 + $CHILD_STATUS.termsig
82
104
  end
83
105
  end
84
- $CHILD_STATUS
106
+ $CHILD_STATUS.exitstatus
85
107
  end
86
108
 
87
109
  # Pre-process the input file with erubis, adding the in_dir to the front of
88
110
  # the ruby load path if its not already in the load path so that requires in
89
111
  # the input file can be found if they are in the in_dir. Return the name of
90
112
  # the output file.
91
- def self.erb_to_tex(in_file, in_dir = nil)
113
+ def self.erb_to_tex(in_file, in_dir = nil, no_clobber: false)
114
+ out_file = ErbTeX.out_file_name(in_file)
115
+ check_output_file(out_file, no_clobber: no_clobber)
116
+
117
+ warn '================================================================'
118
+ warn 'Erubis phase of processing ...'
92
119
  # Add input to ruby LOAD_PATH, $:,if its not already there.
93
- if File.exist?(in_dir)
120
+ if in_dir && File.exist?(in_dir)
94
121
  in_dir = File.absolute_path(File.expand_path(in_dir))
95
122
  unless $LOAD_PATH
96
123
  .any? { |p| in_dir == File.absolute_path(File.expand_path(p)) }
@@ -99,6 +126,7 @@ module ErbTeX
99
126
  end
100
127
 
101
128
  # Read the input
129
+ warn " Erubis reading from #{in_file}..."
102
130
  in_contents = nil
103
131
  File.open(in_file) do |f|
104
132
  in_contents = f.read
@@ -107,17 +135,31 @@ module ErbTeX
107
135
 
108
136
  pat = ENV['ERBTEX_PATTERN'] || '{: :}'
109
137
 
110
- out_file = ErbTeX.out_file_name(in_file)
111
- File.open(out_file, 'w') do |f|
112
- er = ::Erubis::Eruby.new(in_contents, pattern: pat)
113
- f.write(er.result)
138
+ rendered = ::Erubis::Eruby.new(in_contents, pattern: pat, filename: in_file).result
139
+ warn " Erubis writing to #{out_file}..."
140
+ # Keep the temporary file beside its destination so rename is atomic.
141
+ Tempfile.create([".#{File.basename(out_file)}-", '.tmp'], File.dirname(out_file)) do |f|
142
+ f.puts(GENERATED_MARKER)
143
+ f.write(rendered)
144
+ f.close
145
+ check_output_file(out_file, no_clobber: no_clobber)
146
+ File.rename(f.path, out_file)
114
147
  end
148
+ warn 'done'
149
+ warn '================================================================'
115
150
  out_file
116
- rescue SystemCallError => e
117
- warn "Error: #{e}"
118
- exit 1
119
- rescue ScriptError => e
120
- warn "Erubis pre-processing failed: #{e}"
121
- exit 1
151
+ end
152
+
153
+ def self.check_output_file(out_file, no_clobber: false)
154
+ return unless File.exist?(out_file)
155
+
156
+ if no_clobber
157
+ raise OutputExists, "Refusing to overwrite #{out_file}: --no-clobber is set"
158
+ end
159
+
160
+ first_line = File.open(out_file, &:gets)
161
+ return if first_line&.chomp == GENERATED_MARKER
162
+
163
+ raise OutputExists, "Refusing to overwrite #{out_file}: missing erbtex generated-file marker"
122
164
  end
123
165
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ErbTeX
2
- VERSION = '0.4.3'
4
+ VERSION = '0.5.0'
3
5
  end
data/lib/erbtex.rb CHANGED
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Conditional added to prevent running bundler/setup twice when it already has
2
4
  # erbtex in the LOAD_PATH. Failure to do this was causing bundler to setup for
3
5
  # the wrong Gemfile if it was run in the development directory of another gem,
4
6
  # for example, ydl. This only happened on saturn for some reason that I don't
5
7
  # understand, but this kludge made it work.
6
8
 
7
- require 'bundler/setup' if $LOAD_PATH.none? { |p| p =~ /erbtex/ }
9
+ require 'bundler/setup' if $LOAD_PATH.none? { |p| p.include?('erbtex') }
8
10
 
9
11
  require 'shellwords'
10
12
  require 'erubis'