lncs 0.0.1
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/.gitignore +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +35 -0
- data/LICENCE +21 -0
- data/README.md +176 -0
- data/Rakefile +1 -0
- data/bin/lncs +9 -0
- data/lib/lncs/actions.rb +7 -0
- data/lib/lncs/cli.rb +62 -0
- data/lib/lncs/initialiser.rb +22 -0
- data/lib/lncs/paper.rb +166 -0
- data/lib/lncs/proceedings.rb +75 -0
- data/lib/lncs/section.rb +60 -0
- data/lib/lncs/version.rb +3 -0
- data/lib/lncs.rb +6 -0
- data/lncs.gemspec +30 -0
- data/templates/front_matter/organisation.tex +110 -0
- data/templates/front_matter/preface.tex +19 -0
- data/templates/front_matter/sponsors.tex +8 -0
- data/templates/llncs.cls +1206 -0
- data/templates/main.tex +39 -0
- data/templates/manifest.json +36 -0
- data/templates/sprmindx.sty +4 -0
- metadata +167 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
lncs (0.0.1)
|
5
|
+
json (~> 1.7)
|
6
|
+
pdf-reader (~> 1.3)
|
7
|
+
thor (~> 0.18)
|
8
|
+
zip (~> 2.0)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
Ascii85 (1.0.2)
|
14
|
+
afm (0.2.0)
|
15
|
+
hashery (2.1.0)
|
16
|
+
json (1.7.7)
|
17
|
+
pdf-reader (1.3.3)
|
18
|
+
Ascii85 (~> 1.0.0)
|
19
|
+
afm (~> 0.2.0)
|
20
|
+
hashery (~> 2.0)
|
21
|
+
ruby-rc4
|
22
|
+
ttfunk
|
23
|
+
rake (10.0.4)
|
24
|
+
ruby-rc4 (0.1.5)
|
25
|
+
thor (0.18.1)
|
26
|
+
ttfunk (1.0.3)
|
27
|
+
zip (2.0.2)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
bundler (~> 1.3)
|
34
|
+
lncs!
|
35
|
+
rake
|
data/LICENCE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Louis M. Rose
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
LNCS Volume Editor Tools
|
2
|
+
========================
|
3
|
+
A small set of tools that automate some of the more tedious parts of preparing an LNCS volume.
|
4
|
+
|
5
|
+
The conventions enforced by `lncs` are intended to comply with the LNCS guidelines for volume editors. If you find an inconsistency between `lncs` and the LNCS guidelines, please [file a bug report](https://github.com/louismrose/lncs/issues).
|
6
|
+
|
7
|
+
Installation
|
8
|
+
------------
|
9
|
+
You'll need to install Ruby 1.9 or later. I recommend doing so via [rvm](https://rvm.io).
|
10
|
+
|
11
|
+
You can then install `lncs` via Ruby gems: `gem install lncs`
|
12
|
+
|
13
|
+
Get started with the `lncs` executable: `lncs help`
|
14
|
+
|
15
|
+
Recommended workflow
|
16
|
+
--------------------
|
17
|
+
|
18
|
+
1. Download the submissions for your volume
|
19
|
+
|
20
|
+
2. Setup a working directory
|
21
|
+
|
22
|
+
> mkdir ecmfa2013
|
23
|
+
> cd ecmfa2013
|
24
|
+
> lncs init
|
25
|
+
|
26
|
+
3. Customise the manifest (e.g., set the path to the submissions, the volume number, ...)
|
27
|
+
|
28
|
+
> vi manifest.json
|
29
|
+
> cat manifest.json
|
30
|
+
{
|
31
|
+
"volume_number": 7949,
|
32
|
+
"sources": "/Users/louis/Downloads/submissions",
|
33
|
+
"sections": [
|
34
|
+
{
|
35
|
+
title: "Foundations",
|
36
|
+
papers: [7,11,14,18,20,24,35,46,63]
|
37
|
+
},
|
38
|
+
{
|
39
|
+
title: "Applications",
|
40
|
+
papers: [2,6,22,29,58,68]
|
41
|
+
}
|
42
|
+
]
|
43
|
+
}
|
44
|
+
|
45
|
+
4. Unpack and inspect all of the submissions
|
46
|
+
|
47
|
+
> lncs inspect
|
48
|
+
> cd submissions
|
49
|
+
> ls -R
|
50
|
+
|
51
|
+
./ecmfa2013_submission_07:
|
52
|
+
7
|
53
|
+
./ecmfa2013_submission_07/7:
|
54
|
+
paper7.tex paper7.pdf copyright.pdf
|
55
|
+
|
56
|
+
./ecmfa2013_submission_24:
|
57
|
+
ECMFA2013-cameraready.pdf ECMFA2013-cameraready.docx copyright.pdf
|
58
|
+
|
59
|
+
|
60
|
+
5. Update the manifest with the paths to the PDF files of each paper
|
61
|
+
|
62
|
+
> vi manifest.json
|
63
|
+
> cat manifest.json
|
64
|
+
{
|
65
|
+
"volume_number": 7949,
|
66
|
+
"sources": "/Users/louis/Downloads/submissions",
|
67
|
+
"sections": [
|
68
|
+
{
|
69
|
+
title: "Foundations",
|
70
|
+
papers: [7,11,14,18,20,24,35,46,63]
|
71
|
+
},
|
72
|
+
{
|
73
|
+
title: "Applications",
|
74
|
+
papers: [2,6,22,29,58,68]
|
75
|
+
}
|
76
|
+
],
|
77
|
+
papers: {
|
78
|
+
"7" : {
|
79
|
+
pdf: "7/paper.pdf"
|
80
|
+
},
|
81
|
+
"24" : {
|
82
|
+
pdf: "ECMFA2013-cameraready.pdf"
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
6. Check the status of the submissions
|
88
|
+
|
89
|
+
> lncs report
|
90
|
+
Foundations
|
91
|
+
007 -- 17pgs zip
|
92
|
+
011 -- 17pgs zip
|
93
|
+
014 -- 17pgs zip
|
94
|
+
018 -- 16pgs zip
|
95
|
+
020 -- 16pgs zip
|
96
|
+
024 -- 16pgs zip
|
97
|
+
035 -- 17pgs zip
|
98
|
+
046 -- 16pgs zip
|
99
|
+
063 -- 17pgs zip
|
100
|
+
Applications
|
101
|
+
002 -- 13pgs zip
|
102
|
+
006 -- 13pgs zip
|
103
|
+
022 -- 13pgs zip
|
104
|
+
029 -- 13pgs zip
|
105
|
+
058 -- 13pgs zip
|
106
|
+
068 -- 11pgs zip
|
107
|
+
|
108
|
+
If a submission exceeds your page limit, you may wish to contact the authors. If a submission is a PDF rather than a ZIP file, you may wish to do the same as you will need to send to Springer the sources and a signed copyright form for each submission.
|
109
|
+
|
110
|
+
7. Generate the set of directories required by Springer for the body of the proceedings
|
111
|
+
|
112
|
+
> lncs body
|
113
|
+
> ls body
|
114
|
+
79490001 79490020 79490054 79490086 79490119 79490152 79490178 79490204
|
115
|
+
79490003 79490037 79490070 79490102 79490135 79490165 79490191 79490217
|
116
|
+
|
117
|
+
> ls -R body/79490001
|
118
|
+
7
|
119
|
+
|
120
|
+
body/79490001/7:
|
121
|
+
paper7.tex paper7.pdf copyright.pdf
|
122
|
+
|
123
|
+
8. Generate the title pages used to construct the table of contents and author index
|
124
|
+
|
125
|
+
> lncs titles
|
126
|
+
> ls titles
|
127
|
+
0001.tex 0020.tex 0054.tex 0086.tex 0119.tex 0152.tex 0178.tex 0204.tex index.tex
|
128
|
+
0003.tex 0037.tex 0070.tex 0102.tex 0135.tex 0165.tex 0191.tex 0217.tex
|
129
|
+
|
130
|
+
9. Run LaTeX to produce your PDF
|
131
|
+
|
132
|
+
> latex2pdf main.tex
|
133
|
+
> open main.pdf
|
134
|
+
|
135
|
+
10. Override any titles or names of authors (because, for example, `lncs` cannot extract title page information from MS Word source files).
|
136
|
+
|
137
|
+
> vi manifest.json
|
138
|
+
> cat manifest.json
|
139
|
+
{
|
140
|
+
"volume_number": 7949,
|
141
|
+
"sources": "/Users/louis/Downloads/submissions",
|
142
|
+
"sections": [
|
143
|
+
{
|
144
|
+
title: "Foundations",
|
145
|
+
papers: [7,11,14,18,20,24,35,46,63]
|
146
|
+
},
|
147
|
+
{
|
148
|
+
title: "Applications",
|
149
|
+
papers: [2,6,22,29,58,68]
|
150
|
+
}
|
151
|
+
],
|
152
|
+
papers: {
|
153
|
+
"7" : {
|
154
|
+
pdf: "7/paper.pdf",
|
155
|
+
title: "MOCQL: A Declarative Language for Ad-Hoc Model Querying",
|
156
|
+
authors: ["Harald St\\\"orrle"]
|
157
|
+
},
|
158
|
+
"24" : {
|
159
|
+
pdf: "ECMFA2013-cameraready.pdf"
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
11. Regenerate your titles and PDF.
|
165
|
+
|
166
|
+
> lncs titles
|
167
|
+
> latex2pdf main.tex
|
168
|
+
> open main.pdf
|
169
|
+
|
170
|
+
|
171
|
+
Contributing
|
172
|
+
------------
|
173
|
+
I'm afraid that this code is not well tested, factored or documented. It was quickly hacked together whilst in my first attempt to edit an LNCS volume. If I'm ever asked to edit a second volume, I plan to tidy up this gem and add a few more features. In the meantime, pull requests are very welcome.
|
174
|
+
|
175
|
+
Todo list:
|
176
|
+
* Better error reporting when the titles key is specified but not authors and vice versa
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/lncs
ADDED
data/lib/lncs/actions.rb
ADDED
data/lib/lncs/cli.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module LNCS
|
5
|
+
class CLI < Thor
|
6
|
+
include Thor::Actions
|
7
|
+
|
8
|
+
desc "init", "Start an lncs project in the current directory"
|
9
|
+
def init
|
10
|
+
Initialiser.new.run
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "clean", "Remove all working directories"
|
14
|
+
def clean
|
15
|
+
working_directories = %w{submissions body titles}
|
16
|
+
working_directories.each {|d| remove_dir(d) }
|
17
|
+
create_file 'titles/index.tex'
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "inspect", "Unpack the submissions so that their contents can be inspected manually"
|
21
|
+
def inspect
|
22
|
+
remake_directory("submissions")
|
23
|
+
proceedings.copy_to("submissions")
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "body", "Generate the set of directories containing the body of the report, in the format required by Springer LNCS"
|
27
|
+
def body
|
28
|
+
remake_directory("body")
|
29
|
+
proceedings.generate_body_to("body")
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "titles", "Generate a title page for each submission, including correct page numbers and author index entries"
|
33
|
+
def titles
|
34
|
+
remake_directory("titles")
|
35
|
+
proceedings.generate_titles_to("titles")
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "report", "Print useful statistics about the submissions"
|
39
|
+
def report
|
40
|
+
proceedings.report
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def remake_directory(dir)
|
45
|
+
remove_dir dir
|
46
|
+
empty_directory dir
|
47
|
+
end
|
48
|
+
|
49
|
+
def proceedings
|
50
|
+
manifest_missing unless File.exist?("manifest.json")
|
51
|
+
Proceedings.new.tap do |p|
|
52
|
+
p.manifest = JSON.parse(File.read("manifest.json"))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def manifest_missing
|
57
|
+
puts "Error: lncs could not find a manifest.json file in the current directory."
|
58
|
+
puts "You can use 'lncs init' to create a basic manifest file."
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module LNCS
|
2
|
+
class Initialiser < Thor
|
3
|
+
include Thor::Actions
|
4
|
+
|
5
|
+
def self.source_root
|
6
|
+
File.join(File.dirname(__FILE__), '..', '..', 'templates')
|
7
|
+
end
|
8
|
+
|
9
|
+
no_commands do
|
10
|
+
def run
|
11
|
+
copy_file 'manifest.json'
|
12
|
+
copy_file 'main.tex'
|
13
|
+
copy_file 'llncs.cls'
|
14
|
+
copy_file 'sprmindx.sty'
|
15
|
+
copy_file 'front_matter/organisation.tex'
|
16
|
+
copy_file 'front_matter/preface.tex'
|
17
|
+
copy_file 'front_matter/sponsors.tex'
|
18
|
+
create_file 'titles/index.tex'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/lncs/paper.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'pdf-reader'
|
3
|
+
require 'zip/zipfilesystem'
|
4
|
+
require 'lncs/actions'
|
5
|
+
|
6
|
+
module LNCS
|
7
|
+
class Paper
|
8
|
+
attr_accessor :manifest, :path
|
9
|
+
|
10
|
+
def pdf
|
11
|
+
manifest["pdf"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def title
|
15
|
+
manifest["title"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def authors
|
19
|
+
manifest["authors"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
File.basename(path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def id
|
27
|
+
name.match(/(\d+).(pdf|zip)/)[1]
|
28
|
+
end
|
29
|
+
|
30
|
+
def type
|
31
|
+
name.match(/(pdf|zip)/)[1]
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate_title_to(dst, start_page)
|
35
|
+
raise "Error: Cannot generate title from PDF for paper ##{id}" if type == "pdf"
|
36
|
+
check_pdf_exists
|
37
|
+
|
38
|
+
captured = title_page_from_manifest_or_latex
|
39
|
+
captured += "\n" + authors_from_manifest_or_latex.map do |a|
|
40
|
+
a.gsub!(/(?<forename>\S*) (?<surname>.*)/, '\k<surname>, \k<forename>') if a
|
41
|
+
"\\index{#{a}}"
|
42
|
+
end.join("\n") + "\n"
|
43
|
+
|
44
|
+
captured += "\\maketitle\n"
|
45
|
+
captured += "\\clearpage\n"
|
46
|
+
captured += "\\setcounter{page}{#{start_page + page_count}}"
|
47
|
+
|
48
|
+
actions.create_file(dst, captured)
|
49
|
+
end
|
50
|
+
|
51
|
+
def copy_to(dst)
|
52
|
+
check_pdf_exists
|
53
|
+
|
54
|
+
FileUtils.mkdir_p(dst)
|
55
|
+
|
56
|
+
if type == "zip"
|
57
|
+
Zip::ZipFile.open(path) do |zipfile|
|
58
|
+
zipfile.select { |file| zipfile.get_entry(file).file? }.each do |file|
|
59
|
+
actions.create_file(File.join(dst, file.name), zipfile.read(file))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
else
|
63
|
+
actions.copy_file(path, File.join(dst, name))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def page_count
|
68
|
+
check_pdf_exists
|
69
|
+
|
70
|
+
PDF::Reader.new(open_pdf).page_count
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
def check_pdf_exists
|
75
|
+
raise "Error: no file found at path '#{path}'" unless File.exist?(path)
|
76
|
+
|
77
|
+
if type == "zip"
|
78
|
+
pdf_exists = Zip::ZipFile.open(path) { |zipfile| zipfile.find_entry(pdf) }
|
79
|
+
raise "Error: no PDF file found at path '#{pdf}' within the ZIP file #{path}" unless pdf_exists
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def open_pdf
|
84
|
+
if type == "zip"
|
85
|
+
extracted_pdf = File.join(Dir.tmpdir, pdf)
|
86
|
+
Zip::ZipFile.open(path) do |zipfile|
|
87
|
+
FileUtils.mkdir_p(File.dirname(extracted_pdf))
|
88
|
+
zipfile.extract(pdf, extracted_pdf) { true }
|
89
|
+
end
|
90
|
+
File.open(extracted_pdf, "rb")
|
91
|
+
else
|
92
|
+
File.open(path, "rb")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def authors_from_manifest_or_latex
|
97
|
+
if authors
|
98
|
+
authors
|
99
|
+
else
|
100
|
+
regex = %r{
|
101
|
+
\\author(?<re>
|
102
|
+
\{
|
103
|
+
(?:
|
104
|
+
(?> [^{}]+ )
|
105
|
+
|
|
106
|
+
\g<re>
|
107
|
+
)*
|
108
|
+
\}
|
109
|
+
)
|
110
|
+
}x
|
111
|
+
|
112
|
+
title_page = title_page_from_manifest_or_latex
|
113
|
+
if regex.match(title_page)
|
114
|
+
author_tag = regex.match(title_page)[1]
|
115
|
+
author_tag = author_tag[1..-2] # strip starting and closing bracket
|
116
|
+
author_tag.gsub! /\\\\/, '' # strip forced linebreaks
|
117
|
+
author_tag.gsub! /\\inst\{[^\}]*?\}/, '' # strip institutions
|
118
|
+
author_tag.split('\and').map do |a|
|
119
|
+
a.strip!
|
120
|
+
end
|
121
|
+
else
|
122
|
+
[]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def title_page_from_manifest_or_latex
|
128
|
+
if title
|
129
|
+
"""
|
130
|
+
\\title{#{title}}\n
|
131
|
+
\\author{#{authors_from_manifest_or_latex.join(" \\and ")}}\n
|
132
|
+
"""
|
133
|
+
else
|
134
|
+
captured = ""
|
135
|
+
each_tex do |tex|
|
136
|
+
capturing = false
|
137
|
+
while (line = tex.gets)
|
138
|
+
break if line.include? '\maketitle'
|
139
|
+
captured += line if capturing and not line.include? '\frontmatter' and not line.include? '\mainmatter'
|
140
|
+
capturing = true if line.include? '\begin{document}'
|
141
|
+
end
|
142
|
+
end
|
143
|
+
captured.gsub /\\mails[a-z](\\\\)?/, '$ $' # remove any \mailsa or similar commands
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def each_tex
|
148
|
+
if type == "zip"
|
149
|
+
Zip::ZipFile.open(path) do |zipfile|
|
150
|
+
zipfile.each do |file|
|
151
|
+
if file.name.end_with? "tex" and not file.name.end_with? "llncs.tex"
|
152
|
+
extracted_tex = File.join(Dir.tmpdir, file.name)
|
153
|
+
FileUtils.mkdir_p(File.dirname(extracted_tex))
|
154
|
+
zipfile.extract(file, extracted_tex) { true }
|
155
|
+
File.open(extracted_tex, "rb") { |file| yield(file) }
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def actions
|
163
|
+
Actions.new
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'lncs/actions'
|
2
|
+
|
3
|
+
module LNCS
|
4
|
+
class Proceedings
|
5
|
+
attr_accessor :manifest
|
6
|
+
|
7
|
+
def volume_number
|
8
|
+
manifest["volume_number"]
|
9
|
+
end
|
10
|
+
|
11
|
+
def source_directory
|
12
|
+
manifest["sources"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def papers
|
16
|
+
manifest["papers"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def paper_file_name_for(paper_id)
|
20
|
+
Dir.chdir(source_directory) do
|
21
|
+
Dir.glob("*_#{paper_id}.{pdf,zip}")[0]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def paper_path_for(paper_id)
|
26
|
+
filename = paper_file_name_for(paper_id)
|
27
|
+
raise "Error: no file with name ending '#{paper_id}.pdf' or '#{paper_id}.zip' found at path '#{source_directory}'" unless filename
|
28
|
+
File.join(source_directory, filename)
|
29
|
+
end
|
30
|
+
|
31
|
+
def paper_manifest_for(paper_id)
|
32
|
+
paper_manifest = papers.fetch(paper_id.to_s, {})
|
33
|
+
paper_manifest["pdf"] = paper_file_name_for(paper_id) unless paper_manifest["pdf"]
|
34
|
+
paper_manifest
|
35
|
+
end
|
36
|
+
|
37
|
+
def sections
|
38
|
+
manifest["sections"].map do |section|
|
39
|
+
Section.new.tap do |s|
|
40
|
+
s.manifest = section
|
41
|
+
s.proceedings = self
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def copy_to(dst)
|
47
|
+
sections.each { |section| section.copy_to(dst) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def generate_body_to(dst)
|
51
|
+
start_page = 1
|
52
|
+
sections.each do |s|
|
53
|
+
start_page = s.generate_body_to(dst, volume_number, start_page)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def generate_titles_to(dst)
|
58
|
+
actions.remove_file("#{dst}/index.tex")
|
59
|
+
actions.create_file("#{dst}/index.tex")
|
60
|
+
start_page = 1
|
61
|
+
sections.each do |s|
|
62
|
+
start_page = s.generate_titles_to(dst, start_page)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def report
|
67
|
+
sections.each { |s| s.report }
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def actions
|
72
|
+
Actions.new
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/lncs/section.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'lncs/actions'
|
2
|
+
|
3
|
+
module LNCS
|
4
|
+
class Section
|
5
|
+
attr_accessor :manifest, :proceedings
|
6
|
+
|
7
|
+
def papers
|
8
|
+
manifest["papers"].map do |paper_id|
|
9
|
+
Paper.new.tap do |p|
|
10
|
+
p.manifest = proceedings.paper_manifest_for(paper_id)
|
11
|
+
p.path = proceedings.paper_path_for(paper_id)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def title
|
17
|
+
manifest["title"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def copy_to(dst)
|
21
|
+
papers.each { |paper| paper.copy_to("#{dst}/#{paper.id}") }
|
22
|
+
end
|
23
|
+
|
24
|
+
def generate_body_to(dst, volume_number, start_page)
|
25
|
+
papers.each do |paper|
|
26
|
+
padded_start_page = "%04d" % start_page.to_s
|
27
|
+
paper.copy_to("#{dst}/#{volume_number}#{padded_start_page}")
|
28
|
+
start_page += paper.page_count
|
29
|
+
end
|
30
|
+
start_page
|
31
|
+
end
|
32
|
+
|
33
|
+
def generate_titles_to(dst, start_page)
|
34
|
+
titles = []
|
35
|
+
papers.each do |paper|
|
36
|
+
padded_start_page = "%04d" % start_page.to_s
|
37
|
+
titles << "#{dst}/#{padded_start_page}.tex"
|
38
|
+
paper.generate_title_to(titles.last, start_page)
|
39
|
+
start_page += paper.page_count
|
40
|
+
end
|
41
|
+
|
42
|
+
actions.append_file("#{dst}/index.tex") do
|
43
|
+
"\\addtocmark{#{title}}\n" +
|
44
|
+
titles.map {|title| "\\input{#{title}}\n"}.join
|
45
|
+
end
|
46
|
+
|
47
|
+
start_page
|
48
|
+
end
|
49
|
+
|
50
|
+
def report
|
51
|
+
puts title
|
52
|
+
papers.each { |paper| puts "#{"%03d" % paper.id} -- #{paper.page_count}pgs #{paper.type}" }
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def actions
|
57
|
+
Actions.new
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/lncs/version.rb
ADDED
data/lib/lncs.rb
ADDED
data/lncs.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
2
|
+
$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'lncs/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'lncs'
|
7
|
+
spec.version = LNCS::VERSION
|
8
|
+
spec.licenses = ['MIT']
|
9
|
+
spec.authors = ["Louis M. Rose"]
|
10
|
+
spec.email = ["louismrose@gmail.com"]
|
11
|
+
spec.homepage = "https://github.com/louismrose/lncs"
|
12
|
+
spec.summary = %q{A few tools for automating the preparation of a Springer LNCS volume}
|
13
|
+
spec.description = %q{Automates the production of tables of contents and author indexes, and the arrangement of papers for a Springer LNCS volume.}
|
14
|
+
|
15
|
+
spec.required_ruby_version = '>= 1.9.3'
|
16
|
+
spec.required_rubygems_version = '>= 1.3.6'
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split($/)
|
19
|
+
spec.executables = %w(lncs)
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_dependency "json", "~> 1.7"
|
24
|
+
spec.add_dependency "thor", "~> 0.18"
|
25
|
+
spec.add_dependency "zip", "~> 2.0"
|
26
|
+
spec.add_dependency "pdf-reader", "~> 1.3"
|
27
|
+
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
29
|
+
spec.add_development_dependency "rake"
|
30
|
+
end
|