lbt 0.5
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.
- checksums.yaml +7 -0
- data/bin/lbt +32 -0
- data/lib/lbt/build.rb +36 -0
- data/lib/lbt/create.rb +218 -0
- data/lib/lbt/part_typeset.rb +55 -0
- data/lib/lbt/renumber.rb +50 -0
- data/lib/lbt/utils.rb +142 -0
- data/lib/lbt.rb +11 -0
- metadata +50 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 61cb8ee73b25172d9eccfc116cd96cfb5c80fe8b5569bb070ecf8d5bb678bb19
|
4
|
+
data.tar.gz: 79854bfca082e2aadf712c89f91d514163eb87d9465105cb59d358004595dc7d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bdb858eec9763e0df398028d895d5f3091d2ff2b682246210ff2cf43bc508fdf0ed266a458811db29e47eec52ba1072e09710b2850951387a7c88a3bb118c548
|
7
|
+
data.tar.gz: b956421ce68031ed88d80c4a67c6c8b71a626aeb3cf31f8b4e1b3506906818337bcc55e96c00eeec1cfc1ba7ea6de1636e2decb97cf9b6ea2faf066c0df0d73c
|
data/bin/lbt
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'lbt'
|
4
|
+
include Lbt
|
5
|
+
case ARGV[0]
|
6
|
+
when "new"
|
7
|
+
case ARGV.size
|
8
|
+
when 2 then create ARGV[1]
|
9
|
+
when 3 then create ARGV[1], ARGV[2]
|
10
|
+
when 4 then create ARGV[1], ARGV[2], ARGV[3]
|
11
|
+
else return
|
12
|
+
end
|
13
|
+
when "build"
|
14
|
+
build
|
15
|
+
when "part_typeset"
|
16
|
+
return unless ARGV.size == 2
|
17
|
+
part_typeset ARGV[1]
|
18
|
+
when "renum"
|
19
|
+
renum
|
20
|
+
else
|
21
|
+
$stderr.print <<~EOS
|
22
|
+
Usage: lbt command [argument]
|
23
|
+
The command and argument are one of:
|
24
|
+
new directory [document_style [build_directory]]: create a new working directory.
|
25
|
+
document_style: article, book (default) or beamer
|
26
|
+
build_directory: It will be made under the directory (the first argument). The default is _build.
|
27
|
+
build: build a pdf file from all the source files.
|
28
|
+
part_typeset file_or_numbers: build a pdf file from a single source file.
|
29
|
+
example: part_typeset 1-2-2 => part_typeset part1/chap2/sec2.xxx
|
30
|
+
renum: renumber the source files.
|
31
|
+
EOS
|
32
|
+
end
|
data/lib/lbt/build.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'utils.rb'
|
2
|
+
|
3
|
+
module Lbt
|
4
|
+
# Typeset LaTeX source files into a PDF file.
|
5
|
+
def build
|
6
|
+
m = File.read(".config").match(/^build_dir = (.*)$/)
|
7
|
+
build_dir = m[1] ? m[1] : "_build"
|
8
|
+
raise "main.tex not exist." unless File.exist?('main.tex')
|
9
|
+
mkdir build_dir unless Dir.exist?(build_dir)
|
10
|
+
|
11
|
+
# Build main.tex
|
12
|
+
main_tex = File.read('main.tex')
|
13
|
+
m = /\\title(\[(.*?)\])?\s*\{(.*?)\}/.match(main_tex.remove_tex_comment)
|
14
|
+
# Beamer has \title[short title]{title} command.
|
15
|
+
# Other documentclasses don't have such short style option.
|
16
|
+
title = m[2] || m[3]
|
17
|
+
files = PCS.new.to_a
|
18
|
+
input_commands = files.map{|f| "\\input{#{f.ext('.tex')}}\n"}.flatten.join
|
19
|
+
main_tex = main_tex.sub(/\\end{document}/, "#{input_commands}\n\\end{document}")
|
20
|
+
File.write("#{build_dir}/main.tex", main_tex)
|
21
|
+
# copy or convert the files into build_dir
|
22
|
+
cp_conv build_dir
|
23
|
+
# Typeset
|
24
|
+
cur_dir = Dir.pwd
|
25
|
+
cd build_dir
|
26
|
+
system "latexmk -lualatex -pdflualatex=\"lualatex --halt-on-error %O %S\" main.tex"
|
27
|
+
cd cur_dir
|
28
|
+
|
29
|
+
# Copy the pdf file.
|
30
|
+
temp = "#{build_dir}/main.pdf"
|
31
|
+
target = "#{title}.pdf"
|
32
|
+
unless File.exist?(target) && File.mtime(temp) <= File.mtime(target)
|
33
|
+
cp temp, target
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/lbt/create.rb
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module Lbt
|
5
|
+
=begin rdoc
|
6
|
+
The create method creates a source file directory and put some templates in the directory.
|
7
|
+
|
8
|
+
Parameters are:
|
9
|
+
|
10
|
+
[dir] The name of the source file directory
|
11
|
+
[document\_class] The document class of the LaTeX source file. For example, article, book and beamer.
|
12
|
+
[build\_dir] The working directory in which typeset is carried out.
|
13
|
+
=end
|
14
|
+
def create dir, document_class="book", build_dir="_build"
|
15
|
+
raise "Argument error." unless dir.is_a?(String) && dir =~ /[[:^space:]]+/
|
16
|
+
raise "#{dir} already exists." if Dir.exist?(dir)
|
17
|
+
mkdir_p(dir)
|
18
|
+
File.write("#{dir}/.config", "build_dir = #{build_dir}\n")
|
19
|
+
helper_tex = <<~EOS
|
20
|
+
\\usepackage{amsmath,amssymb}
|
21
|
+
\\usepackage[luatex]{graphicx}
|
22
|
+
\\usepackage{tikz}
|
23
|
+
\\usepackage[margin=2.4cm]{geometry}
|
24
|
+
\\usepackage[colorlinks=true,linkcolor=black]{hyperref}
|
25
|
+
% If your source includes Markdown, you probably need the following lines.
|
26
|
+
% It is because Pandoc generates some undefined commands.
|
27
|
+
% The Pandoc template file shows how to define them.
|
28
|
+
% You can see it by 'pandoc --print-default-template=latex'.
|
29
|
+
\\providecommand{\\tightlist}{%
|
30
|
+
\\setlength{\\itemsep}{0pt}\\setlength{\\parskip}{0pt}}
|
31
|
+
EOS
|
32
|
+
|
33
|
+
if ["book", "ltjsbook"].include? document_class
|
34
|
+
main_tex = <<~EOS
|
35
|
+
\\documentclass{#{document_class}}
|
36
|
+
\\input{helper.tex}
|
37
|
+
\\title{Title}
|
38
|
+
\\author{Author}
|
39
|
+
\\begin{document}
|
40
|
+
\\frontmatter
|
41
|
+
\\begin{titlepage}
|
42
|
+
\\input{cover.tex}
|
43
|
+
\\end{titlepage}
|
44
|
+
\\tableofcontents
|
45
|
+
\\mainmatter
|
46
|
+
|
47
|
+
\\end{document}
|
48
|
+
EOS
|
49
|
+
|
50
|
+
cover_tex = <<~EOS
|
51
|
+
\\newgeometry{margin=2.4cm}
|
52
|
+
\\begin{center}
|
53
|
+
\\begin{tikzpicture}
|
54
|
+
\\node at (0,0) {\\includegraphics[width=100pt]{gecko.png}};
|
55
|
+
\\node at (70pt,0) {\\includegraphics[width=100pt]{gecko.png}};
|
56
|
+
\\node at (140pt,0) {\\includegraphics[width=100pt]{gecko.png}};
|
57
|
+
\\node at (210pt,0) {\\includegraphics[width=100pt]{gecko.png}};
|
58
|
+
\\node at (280pt,0) {\\includegraphics[width=100pt]{gecko.png}};
|
59
|
+
\\node at (350pt,0) {\\includegraphics[width=100pt]{gecko.png}};
|
60
|
+
\\end{tikzpicture}
|
61
|
+
\\end{center}
|
62
|
+
|
63
|
+
\\vspace{2cm}
|
64
|
+
\\begin{center}
|
65
|
+
{\\fontsize{64}{0} \\selectfont Title}
|
66
|
+
\\end{center}
|
67
|
+
\\vspace{1cm}
|
68
|
+
\\begin{center}
|
69
|
+
{\\huge Author}
|
70
|
+
\\end{center}
|
71
|
+
|
72
|
+
\\vspace{9cm}
|
73
|
+
%\\vspace{6.5cm}
|
74
|
+
%\\begin{center}
|
75
|
+
%{\\Large Foobar University}
|
76
|
+
%\\end{center}
|
77
|
+
%\\begin{center}
|
78
|
+
%{\\Large School of Foobar}
|
79
|
+
%\\end{center}
|
80
|
+
|
81
|
+
\\vspace{3cm}
|
82
|
+
\\begin{center}
|
83
|
+
\\begin{tikzpicture}
|
84
|
+
\\node at (0,0) {\\includegraphics[width=100pt]{gecko.png}};
|
85
|
+
\\node at (70pt,0) {\\includegraphics[width=100pt]{gecko.png}};
|
86
|
+
\\node at (140pt,0) {\\includegraphics[width=100pt]{gecko.png}};
|
87
|
+
\\node at (210pt,0) {\\includegraphics[width=100pt]{gecko.png}};
|
88
|
+
\\node at (280pt,0) {\\includegraphics[width=100pt]{gecko.png}};
|
89
|
+
\\node at (350pt,0) {\\includegraphics[width=100pt]{gecko.png}};
|
90
|
+
\\end{tikzpicture}
|
91
|
+
\\end{center}
|
92
|
+
\\restoregeometry
|
93
|
+
EOS
|
94
|
+
|
95
|
+
File.write("#{dir}/main.tex", main_tex)
|
96
|
+
File.write("#{dir}/helper.tex", helper_tex)
|
97
|
+
File.write("#{dir}/cover.tex", cover_tex)
|
98
|
+
gecko_png = __dir__+"/../../images/gecko.png"
|
99
|
+
cp(gecko_png, "#{dir}/gecko.png")
|
100
|
+
elsif ["article", "ltjsarticle"].include? document_class
|
101
|
+
main_tex = <<~EOS
|
102
|
+
\\documentclass{#{document_class}}
|
103
|
+
\\input{helper.tex}
|
104
|
+
\\title{Title}
|
105
|
+
\\author{Author}
|
106
|
+
\\begin{document}
|
107
|
+
\\maketitle
|
108
|
+
\\tableofcontents
|
109
|
+
|
110
|
+
\\end{document}
|
111
|
+
EOS
|
112
|
+
File.write("#{dir}/main.tex", main_tex)
|
113
|
+
File.write("#{dir}/helper.tex", helper_tex)
|
114
|
+
elsif document_class == "beamer"
|
115
|
+
main_tex = <<~EOS
|
116
|
+
\\documentclass[utf8,aspectratio=149]{beamer}
|
117
|
+
\\mode<presentation>
|
118
|
+
{
|
119
|
+
\\usetheme{Warsaw}
|
120
|
+
\\setbeamercovered{transparent}
|
121
|
+
}
|
122
|
+
\\input{helper.tex}
|
123
|
+
% Don't show navigation symbol => If you want to show it, comment out the following line.
|
124
|
+
\\setbeamertemplate{navigation symbols}{}
|
125
|
+
\\title[short\\_title] % (optional, use only with long paper titles)
|
126
|
+
{titile}
|
127
|
+
\\subtitle
|
128
|
+
{substitile}
|
129
|
+
\\author[short\\_author] % (optional, use only with lots of authors)
|
130
|
+
{author \\\\ \\texttt{sample\\_address@email.com}}
|
131
|
+
% - Give the names in the same order as the appear in the paper.
|
132
|
+
% - Use the \\inst{?} command only if the authors have different
|
133
|
+
% affiliation.
|
134
|
+
\\institute[short\\_institute] % (optional, but mostly needed)
|
135
|
+
{
|
136
|
+
% \\inst{1}%
|
137
|
+
Department of Mathematics and Technology\\\\
|
138
|
+
School of Education and Humanities\\\\
|
139
|
+
XXXX University
|
140
|
+
}
|
141
|
+
% - Use the \\inst command only if there are several affiliations.
|
142
|
+
% - Keep it simple, no one is interested in your street address.
|
143
|
+
\\date[short\\_date] % (optional, should be abbreviation of conference name)
|
144
|
+
{XXXX meeting on Wednesday, April 27 2022}
|
145
|
+
% - Either use conference name or its abbreviation.
|
146
|
+
% - Not really informative to the audience, more for people (including
|
147
|
+
% yourself) who are reading the slides online
|
148
|
+
\\subject{subject}
|
149
|
+
% If you have a file called "university-logo-filename.xxx", where xxx
|
150
|
+
% is a graphic format that can be processed by lualatex,
|
151
|
+
% resp., then you can add a logo as follows:
|
152
|
+
% \\pgfdeclareimage[height=0.5cm]{university-logo}{university-logo-filename}
|
153
|
+
% \\logo{\\pgfuseimage{university-logo}}
|
154
|
+
\\begin{document}
|
155
|
+
\\begin{frame}
|
156
|
+
\\titlepage
|
157
|
+
\\end{frame}
|
158
|
+
\\begin{frame}{Outline}
|
159
|
+
\\tableofcontents
|
160
|
+
% \\begin{center}
|
161
|
+
% \\includegraphics[width=6cm,keepaspectratio]{photo.jpg}
|
162
|
+
% \\end{center}
|
163
|
+
\\end{frame}
|
164
|
+
|
165
|
+
\\end{document}
|
166
|
+
EOS
|
167
|
+
helper_tex = <<~EOS
|
168
|
+
\\usepackage{luatexja}
|
169
|
+
% 和文のデフォルトをゴシック体に
|
170
|
+
\\renewcommand{\\kanjifamilydefault}{\\gtdefault}
|
171
|
+
\\usepackage{amsmath,amssymb}
|
172
|
+
\\usepackage{tikz}
|
173
|
+
\\usepackage[absolute,overlay]{textpos}
|
174
|
+
EOS
|
175
|
+
sec1_tex = <<~EOS
|
176
|
+
% This is a sample latex file for the beamer documentclass.
|
177
|
+
\\begin{frame}{introduction}
|
178
|
+
About something
|
179
|
+
\\begin{itemize}
|
180
|
+
\\item item 1
|
181
|
+
\\item<2> item 2
|
182
|
+
\\end{itemize}
|
183
|
+
About another thing
|
184
|
+
\\begin{enumerate}
|
185
|
+
\\item<3> item 1
|
186
|
+
\\item<3-4> item 2
|
187
|
+
\\end{enumerate}
|
188
|
+
\\alert{alert message, which is red.}
|
189
|
+
\\end{frame}
|
190
|
+
% Show a photo that extends to the whole slide view.
|
191
|
+
\\begin{frame}
|
192
|
+
\\begin{textblock*}{128mm}(0pt,0pt)
|
193
|
+
\\includegraphics[width=128mm,height=96mm,keepaspectratio]{lagoon.jpg}
|
194
|
+
\\end{textblock*}
|
195
|
+
\\end{frame}
|
196
|
+
EOS
|
197
|
+
File.write("#{dir}/main.tex", main_tex)
|
198
|
+
File.write("#{dir}/helper.tex", helper_tex)
|
199
|
+
File.write("#{dir}/sec1.tex", sec1_tex)
|
200
|
+
lagoon_jpg = __dir__+"/../../images/lagoon.jpg"
|
201
|
+
cp(lagoon_jpg, "#{dir}/lagoon.jpg")
|
202
|
+
else
|
203
|
+
main_tex = <<~EOS
|
204
|
+
\\documentclass{#{document_class}}
|
205
|
+
\\input{helper.tex}
|
206
|
+
\\title{Title}
|
207
|
+
\\author{Author}
|
208
|
+
\\begin{document}
|
209
|
+
\\maketitle
|
210
|
+
\\tableofcontents
|
211
|
+
|
212
|
+
\\end{document}
|
213
|
+
EOS
|
214
|
+
File.write("#{dir}/main.tex", main_tex)
|
215
|
+
File.write("#{dir}/helper.tex", helper_tex)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative 'utils.rb'
|
2
|
+
|
3
|
+
module Lbt
|
4
|
+
# Typeset one source file to check the PDF.
|
5
|
+
#
|
6
|
+
# Parameter:
|
7
|
+
# [file_or_number]
|
8
|
+
# It can be either a filename or the number of a filename.
|
9
|
+
# For example, part1/chap2/sec3.tex or 1-2-3
|
10
|
+
def part_typeset file_or_number
|
11
|
+
return unless file_or_number.is_a? String
|
12
|
+
if File.file?(file_or_number)
|
13
|
+
file = file_or_number
|
14
|
+
else
|
15
|
+
file = num2path(file_or_number)
|
16
|
+
return unless File.file? file
|
17
|
+
end
|
18
|
+
|
19
|
+
m = File.read(".config").match(/^build_dir = (.*)$/)
|
20
|
+
build_dir = m[1] ? m[1] : "_build"
|
21
|
+
raise "main.tex not exist." unless File.exist?('main.tex')
|
22
|
+
mkdir build_dir unless Dir.exist?(build_dir)
|
23
|
+
|
24
|
+
main_tex = File.read('main.tex')
|
25
|
+
main_tex = main_tex.sub(/\\end{document}/, "\\input{#{file.ext('.tex')}}\n\\end{document}")
|
26
|
+
File.write("#{build_dir}/main.tex", main_tex)
|
27
|
+
# copy or convert the files into build_dir
|
28
|
+
cp_conv build_dir
|
29
|
+
# Typeset
|
30
|
+
cur_dir = Dir.pwd
|
31
|
+
cd build_dir
|
32
|
+
system "latexmk -lualatex -pdflualatex=\"lualatex --halt-on-error %O %S\" main.tex"
|
33
|
+
cd cur_dir
|
34
|
+
end
|
35
|
+
|
36
|
+
# :nodoc:
|
37
|
+
def num2path n_n_n
|
38
|
+
return nil unless n_n_n.is_a? String
|
39
|
+
num_pcs = /^(\d+(\.\d+)?)-(\d+(\.\d+)?)-(\d+(\.\d+)?)$/
|
40
|
+
num_cs = /^(\d+(\.\d+)?)-(\d+(\.\d+)?)$/
|
41
|
+
num_s = /^(\d+(\.\d+)?)$/
|
42
|
+
if n_n_n =~ num_pcs
|
43
|
+
path = "part#{$1}/chap#{$3}/sec#{$5}"
|
44
|
+
elsif n_n_n =~ num_cs
|
45
|
+
path = "chap#{$1}/sec#{$3}"
|
46
|
+
elsif n_n_n =~ num_s
|
47
|
+
path = "sec#{$1}"
|
48
|
+
else
|
49
|
+
return nil
|
50
|
+
end
|
51
|
+
srcs = Dir.glob("#{path}.*")
|
52
|
+
return nil if srcs.size != 1
|
53
|
+
srcs[0]
|
54
|
+
end
|
55
|
+
end
|
data/lib/lbt/renumber.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module Lbt
|
2
|
+
# Renumber the source files.
|
3
|
+
# For example,
|
4
|
+
# - sec1.tex, sec1.5.tex, sec2.tex => sec1.tex, sec2.tex, sec3.tex
|
5
|
+
# - chap1/sec1.tex, chap1/sec1.2.tex, chap1.3/sec10.tex => chap1/sec1.tex, chap1/sec2.tex, chap2/sec1.tex
|
6
|
+
def renum
|
7
|
+
if Dir.children(".").select{|d| d =~ /^part\d+(\.\d+)?$/}.size > 0
|
8
|
+
renumber "part"
|
9
|
+
elsif Dir.children(".").select{|d| d =~ /^chap\d+(\.\d+)?$/}.size > 0
|
10
|
+
renumber "chap"
|
11
|
+
else
|
12
|
+
renumber "sec"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# :nodoc:
|
17
|
+
def renumber pcs
|
18
|
+
case pcs
|
19
|
+
when "part", "chap"
|
20
|
+
files = Dir.children(".").select{|d| d =~ /^#{pcs}\d+(\.\d+)?$/}
|
21
|
+
when "sec"
|
22
|
+
files = Dir.children(".").select{|d| d =~ /^#{pcs}\d+(\.\d+)?\.\w+$/}
|
23
|
+
end
|
24
|
+
files.sort! do |a,b|
|
25
|
+
a.match(/^#{pcs}(\d+(\.\d+)?)/)[1] <=> b.match(/^#{pcs}(\d+(\.\d+)?)/)[1]
|
26
|
+
end
|
27
|
+
n = files.size
|
28
|
+
case pcs
|
29
|
+
when "part", "chap"
|
30
|
+
temp_files = (1..n).map{|i| "#{pcs}#{i}_temp"}
|
31
|
+
when "sec"
|
32
|
+
temp_files = (1..n).map{|i| "#{pcs}#{i}#{File.extname(files[i-1])}_temp"}
|
33
|
+
end
|
34
|
+
n.times do |i|
|
35
|
+
File.rename(files[i], temp_files[i])
|
36
|
+
end
|
37
|
+
n.times do |i|
|
38
|
+
File.rename(temp_files[i], temp_files[i].sub(/_temp$/, ""))
|
39
|
+
end
|
40
|
+
return if pcs == "sec"
|
41
|
+
Dir.children(".").select{|d| d =~ /^#{pcs}\d+(\.\d+)?$/}.each do |f|
|
42
|
+
cd f
|
43
|
+
case pcs
|
44
|
+
when "part" then renumber "chap"
|
45
|
+
when "chap" then renumber "sec"
|
46
|
+
end
|
47
|
+
cd ".."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/lbt/utils.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
include FileUtils
|
4
|
+
|
5
|
+
class String
|
6
|
+
# Remove verbatim environments and comments (including the following new line) from self (LaTeX source).
|
7
|
+
def remove_tex_comment
|
8
|
+
gsub(/\\begin\{verbatim\}.*\\end\{verbatim\}/m, '').gsub(/%.*\n/,'')
|
9
|
+
end
|
10
|
+
# Return a string with the new suffix.
|
11
|
+
# If the suffix is illegal, nil is returned.
|
12
|
+
# Be careful that the suffix begins with a period.
|
13
|
+
#
|
14
|
+
# It redefines itself if it has been defined. For example, rake defines ext method.
|
15
|
+
def ext(suffix)
|
16
|
+
return nil unless suffix.is_a?(String) && /^\.\w+$/ =~ suffix
|
17
|
+
s = File.extname(self)
|
18
|
+
self.sub(/#{s}$/, suffix)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module Lbt
|
23
|
+
=begin rdoc
|
24
|
+
When you create an instance of the PCS class, it keeps the structure of Part-Chapter-Section files.
|
25
|
+
For example,
|
26
|
+
+-part1-+-chap1-+-sec1.tex
|
27
|
+
| | +-sec2.tex`
|
28
|
+
| +-chap2-+-sec1.tex`
|
29
|
+
| | +-sec2.tex`
|
30
|
+
+-part2-+-chap1-+-sec1.tex
|
31
|
+
| +-sec2.tex`
|
32
|
+
If the files are as above, the PCS instance keeps the six filenames whch are sorted alphabetically.
|
33
|
+
=end
|
34
|
+
class PCS
|
35
|
+
# Type is one of :PCS, :CS and :S
|
36
|
+
# - :PCS => The file structure has part, chap directories.
|
37
|
+
# - :CS => The file structure has chap directories.
|
38
|
+
# - :S => The file structure doesn't have any directories.
|
39
|
+
attr_reader :type
|
40
|
+
# The name of the top direcotory
|
41
|
+
attr_reader :dir
|
42
|
+
# Create a new PCS instance.
|
43
|
+
# You can give a top directory as an argument.
|
44
|
+
def initialize dir="."
|
45
|
+
@dir = dir.dup
|
46
|
+
@dir.freeze
|
47
|
+
@files = Dir.glob("part*/chap*/sec*", base: @dir).select{|f| f.match?(/^part\d+(\.\d+)?\/chap\d+(\.\d+)?\/sec\d+(\.\d+)?\.\w+$/)}
|
48
|
+
unless @files.empty?
|
49
|
+
@type = :PCS
|
50
|
+
@files.sort! do |a, b|
|
51
|
+
m = /^part(\d+(\.\d+)?)\/chap(\d+(\.\d+)?)\/sec(\d+(\.\d+)?)\.\w*$/.match(a)
|
52
|
+
ap = m[1].to_f; ac= m[3].to_f; as = m[5].to_f
|
53
|
+
m = /^part(\d+(\.\d+)?)\/chap(\d+(\.\d+)?)\/sec(\d+(\.\d+)?)\.\w*$/.match(b)
|
54
|
+
bp = m[1].to_f; bc= m[3].to_f; bs = m[5].to_f
|
55
|
+
if ap != bp
|
56
|
+
ap <=> bp
|
57
|
+
elsif ac != bc
|
58
|
+
ac <=> bc
|
59
|
+
else
|
60
|
+
as <=> bs
|
61
|
+
end
|
62
|
+
end
|
63
|
+
return
|
64
|
+
end
|
65
|
+
@files = Dir.glob("chap*/sec*", base: @dir).select{|f| f.match?(/^chap\d+(\.\d+)?\/sec\d+(\.\d+)?\.\w+$/)}
|
66
|
+
unless @files.empty?
|
67
|
+
@type = :CS
|
68
|
+
@files.sort! do |a, b|
|
69
|
+
m = /^chap(\d+(\.\d+)?)\/sec(\d+(\.\d+)?)\.\w*$/.match(a)
|
70
|
+
ac= m[1].to_f; as = m[3].to_f
|
71
|
+
m = /^chap(\d+(\.\d+)?)\/sec(\d+(\.\d+)?)\.\w*$/.match(b)
|
72
|
+
bc= m[1].to_f; bs = m[3].to_f
|
73
|
+
if ac != bc
|
74
|
+
ac <=> bc
|
75
|
+
else
|
76
|
+
as <=> bs
|
77
|
+
end
|
78
|
+
end
|
79
|
+
return
|
80
|
+
end
|
81
|
+
@files = Dir.glob("sec*", base: @dir).select{|f| f.match?(/^sec\d+(\.\d+)?\.\w+$/)}
|
82
|
+
unless @files.empty?
|
83
|
+
@type = :S
|
84
|
+
@files.sort! do |a, b|
|
85
|
+
m = /^sec(\d+(\.\d+)?)\.\w*$/.match(a)
|
86
|
+
as = m[1].to_f
|
87
|
+
m = /^sec(\d+(\.\d+)?)\.\w*$/.match(b)
|
88
|
+
bs = m[1].to_f
|
89
|
+
as <=> bs
|
90
|
+
end
|
91
|
+
return
|
92
|
+
end
|
93
|
+
raise "No [[part/]chap/]sec files exist.\n" if @files.empty?
|
94
|
+
end
|
95
|
+
|
96
|
+
# Return an array of pathnames which are relative from the top directory.
|
97
|
+
# The returned pathnames are the copies.
|
98
|
+
# So, even if a user changes them, the original pathnames in the PCS instance are not changed.
|
99
|
+
def to_a
|
100
|
+
@files.map {|s| s.dup}
|
101
|
+
end
|
102
|
+
# Executes the block with each pathname.
|
103
|
+
def each
|
104
|
+
@files.each {|f| yield(f)}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Return a hash (key: extension, value: Proc object) of converters.
|
109
|
+
def get_converters
|
110
|
+
converters = {'.md': lambda {|src, dst| system("pandoc -o #{dst} #{src}")} }
|
111
|
+
if File.file?("converters.rb")
|
112
|
+
c = eval(File.read("converters.rb"))
|
113
|
+
c.each {|key, val| converters[key] = val} if c.is_a?(Hash)
|
114
|
+
end
|
115
|
+
converters
|
116
|
+
end
|
117
|
+
|
118
|
+
# copy or convert source files into build directory.
|
119
|
+
def cp_conv build_dir
|
120
|
+
converters = get_converters
|
121
|
+
files = Dir.children(".").reject{|f| f == build_dir || f == "main.tex"}
|
122
|
+
cp_conv_0 ".", files, build_dir, converters
|
123
|
+
end
|
124
|
+
# :nodoc:
|
125
|
+
def cp_conv_0 sdir, files, ddir, converters
|
126
|
+
files.each do |f|
|
127
|
+
f1 = "#{sdir}/#{f}"; f2 = "#{ddir}/#{f}"; ext = File.extname(f).to_sym
|
128
|
+
if Dir.exist?(f1)
|
129
|
+
mkdir_p f2
|
130
|
+
f1_files = Dir.children(f1)
|
131
|
+
cp_conv_0 f1, f1_files, f2, converters
|
132
|
+
elsif converters.has_key?(ext)
|
133
|
+
f2 = f2.ext ".tex"
|
134
|
+
unless File.exist?(f2) && File.mtime(f1) <= File.mtime(f2)
|
135
|
+
converters[ext].call(f1, f2)
|
136
|
+
end
|
137
|
+
elsif File.file?(f1)
|
138
|
+
cp f1, f2
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
data/lib/lbt.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative 'lbt/build.rb'
|
2
|
+
require_relative 'lbt/create.rb'
|
3
|
+
require_relative 'lbt/part_typeset.rb'
|
4
|
+
require_relative 'lbt/renumber.rb'
|
5
|
+
require_relative 'lbt/utils.rb'
|
6
|
+
|
7
|
+
# LaTeX-Buildtools provides Ruby script +lbt+ to create template, build it and do other tasks.
|
8
|
+
# The +lbt+ command includes Lbt module and calls its instance methods.
|
9
|
+
# All the methods are instance methods and Lbt module doesn't have any singleton methods.
|
10
|
+
module Lbt
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lbt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.5'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Toshio Sekiya
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-04-15 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Lbt is a build tool for LaTeX. It is useful for big documents.
|
14
|
+
email: lxboyjp@gmail.com
|
15
|
+
executables:
|
16
|
+
- lbt
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/lbt
|
21
|
+
- lib/lbt.rb
|
22
|
+
- lib/lbt/build.rb
|
23
|
+
- lib/lbt/create.rb
|
24
|
+
- lib/lbt/part_typeset.rb
|
25
|
+
- lib/lbt/renumber.rb
|
26
|
+
- lib/lbt/utils.rb
|
27
|
+
homepage: https://github.com/ToshioCP/LaTeX-BuildTools
|
28
|
+
licenses:
|
29
|
+
- GPL-3.0
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubygems_version: 3.4.11
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: LaTeX Build Tools
|
50
|
+
test_files: []
|