require 'tmpdir' require 'pdf-reader' require 'zip/zipfilesystem' require 'lncs/actions' module LNCS class Paper attr_accessor :manifest, :path, :proceedings def pdf manifest["pdf"] end def title manifest["title"] end def authors manifest["authors"] end def name File.basename(path) end def id name.match(/(\d+).(pdf|zip)/)[1] end def type name.match(/(pdf|zip)/)[1] end def generate_title_to(dst, start_page) raise "Error: Cannot generate title from PDF for paper ##{id}" if type == "pdf" check_pdf_exists captured = title_page_from_manifest_or_latex captured += "\n" + authors_from_manifest_or_latex.map do |a| a.gsub!(/(?\S*) (?.*)/, '\k, \k') if a "\\index{#{a}}" end.join("\n") + "\n" captured += "\\maketitle\n" captured += "\\clearpage\n" captured += "\\setcounter{page}{#{start_page + page_count}}" actions.create_file(dst, captured) end def copy_to(dst) FileUtils.mkdir_p(dst) if type == "zip" Zip::ZipFile.open(path) do |zipfile| zipfile.select { |file| zipfile.get_entry(file).file? }.each do |file| actions.create_file(File.join(dst, file.name), zipfile.read(file)) end end else actions.copy_file(path, File.join(dst, name)) end end def page_count check_pdf_exists PDF::Reader.new(open_pdf).page_count end private def check_pdf_exists raise "Error: no file found at path '#{path}'" unless File.exist?(path) if type == "zip" pdf_exists = Zip::ZipFile.open(path) { |zipfile| zipfile.find_entry(pdf) } raise "Error: no PDF file found at path '#{pdf}' within the ZIP file #{path}" unless pdf_exists end end def open_pdf if type == "zip" extracted_pdf = File.join(Dir.tmpdir, pdf) Zip::ZipFile.open(path) do |zipfile| FileUtils.mkdir_p(File.dirname(extracted_pdf)) zipfile.extract(pdf, extracted_pdf) { true } end File.open(extracted_pdf, "rb") else File.open(path, "rb") end end def authors_from_manifest_or_latex if authors authors else regex = %r{ \\author(? \{ (?: (?> [^{}]+ ) | \g )* \} ) }x title_page = title_page_from_manifest_or_latex if regex.match(title_page) author_tag = regex.match(title_page)[1] author_tag = author_tag[1..-2] # strip starting and closing bracket author_tag.gsub! /\\\\/, '' # strip forced linebreaks author_tag.gsub! /\\inst\{[^\}]*?\}/, '' # strip institutions author_tag.split('\and').map do |a| a.strip! end else [] end end end def title_page_from_manifest_or_latex if title """ \\title{#{title}}\n \\author{#{authors_from_manifest_or_latex.join(" \\and ")}}\n """ else captured = "" each_tex do |tex| capturing = false while (line = tex.gets) break if line.include? '\maketitle' captured += line if capturing and not line.include? '\frontmatter' and not line.include? '\mainmatter' capturing = true if line.include? '\begin{document}' end end captured.gsub /\\mails[a-z](\\\\)?/, '$ $' # remove any \mailsa or similar commands end end def each_tex if type == "zip" Zip::ZipFile.open(path) do |zipfile| zipfile.each do |file| if file.name.end_with? "tex" and not file.name.end_with? "llncs.tex" extracted_tex = File.join(Dir.tmpdir, file.name) FileUtils.mkdir_p(File.dirname(extracted_tex)) zipfile.extract(file, extracted_tex) { true } File.open(extracted_tex, "rb") { |file| yield(file) } end end end end end def actions Actions.new(proceedings.source_directory) end end end