# # Copyright (c) 2012-2022 Masanori Kado, Masayoshi Takahashi, Kenshi Muto # # This program is free software. # You can distribute or modify this program under the terms of # the GNU LGPL, Lesser General Public License version 2.1. # For details of the GNU LGPL, see the file "COPYING". # require 'securerandom' require 'review/yamlloader' module ReVIEW class Configure < Hash attr_accessor :maker def self.values # rubocop:disable Metrics/MethodLength conf = Configure[ # These parameters can be overridden by YAML file. 'bookname' => 'book', # it defines epub file name also 'booktitle' => 'Re:VIEW Sample Book', 'title' => nil, 'aut' => nil, # author 'prt' => nil, # printer(publisher) 'asn' => nil, # associated name 'ant' => nil, # bibliographic antecedent 'clb' => nil, # Collaborator 'edt' => nil, # Editor 'dsr' => nil, # Designer 'ill' => nil, # Illustrator 'pht' => nil, # Photographer 'trl' => nil, # Translator 'date' => Time.now.strftime('%Y-%m-%d'), # publishing date 'rights' => nil, # Copyright messages 'description' => nil, # Description 'urnid' => "urn:uuid:#{SecureRandom.uuid}", # Identifier 'stylesheet' => [], # stylesheet file 'coverfile' => nil, # content file of body of cover page 'mytoc' => nil, # whether make own table of contents or not 'params' => '', # specify review2html parameters 'toclevel' => 3, # level of toc 'secnolevel' => 2, # level of section # 'epubversion' => 3, 'titlepage' => true, # Use title page 'toc' => nil, # Use table of contents in body 'colophon' => nil, # Use colophon 'debug' => nil, # debug flag 'catalogfile' => 'catalog.yml', 'language' => 'ja', # XXX default language should be JA?? 'math_format' => nil, 'htmlext' => 'html', 'htmlversion' => 5, 'contentdir' => '.', 'imagedir' => 'images', 'image_ext' => %w[png gif jpg jpeg svg ttf woff otf], 'fontdir' => 'fonts', 'chapter_file' => 'CHAPS', 'part_file' => 'PART', 'reject_file' => 'REJECT', 'predef_file' => 'PREDEF', 'postdef_file' => 'POSTDEF', 'page_metric' => ReVIEW::Book::PageMetric::A5, 'ext' => '.re', 'image_types' => %w[.ai .psd .eps .pdf .tif .tiff .png .bmp .jpg .jpeg .gif .svg], 'bib_file' => 'bib.re', 'words_file' => nil, 'colophon_order' => %w[aut csl trl dsr ill cov edt pbl contact prt pht], 'chapterlink' => true, 'externallink' => true, 'join_lines_by_lang' => nil, # experimental. default should be nil 'table_row_separator' => 'tabs', # for Playwright 'playwright_options' => { 'playwright_path' => './node_modules/.bin/playwright', 'selfcrop' => true, 'pdfcrop_path' => 'pdfcrop', 'pdftocairo_path' => 'pdftocairo' }, # for IDGXML 'tableopt' => nil, 'listinfo' => nil, 'nolf' => true, 'chapref' => nil, 'structuredxml' => nil, 'pt_to_mm_unit' => 0.3528, # DTP: 1pt = 0.3528mm, JIS: 1pt = 0.3514mm # for LaTeX 'footnotetext' => nil, 'texcommand' => 'uplatex', 'texoptions' => '-interaction=nonstopmode -file-line-error -halt-on-error', '_texdocumentclass' => ['review-jsbook', ''], 'texstyle' => ['reviewmacro'], 'dvicommand' => 'dvipdfmx', 'dvioptions' => '-d 5 -z 9', # for PDFMaker 'pdfmaker' => { 'image_scale2width' => true, 'makeindex' => nil, # Make index page 'makeindex_command' => 'mendex', # works only when makeindex is true 'makeindex_options' => '-f -r -I utf8', 'makeindex_sty' => nil, 'makeindex_dic' => nil, 'makeindex_mecab' => true, 'makeindex_mecab_opts' => '-Oyomi', 'use_cover_nombre' => true, 'use_original_image_size' => nil }, 'imgmath_options' => { 'format' => 'png', 'converter' => 'pdfcrop', # dvipng | pdfcrop 'pdfcrop_cmd' => 'pdfcrop --hires %i %o', 'extract_singlepage' => nil, 'pdfextract_cmd' => 'pdfjam -q --outfile %o %i %p', 'preamble_file' => nil, 'fontsize' => 10, 'lineheight' => 10 * 1.2, 'pdfcrop_pixelize_cmd' => 'pdftocairo -%t -r 90 -f %p -l %p -singlefile %i %O', 'dvipng_cmd' => 'dvipng -T tight -z 9 -p %p -l %p -o %o %i' }, 'caption_position' => { 'list' => 'top', 'image' => 'bottom', 'table' => 'top', 'equation' => 'top' }, # for EPUBMaker 'modified' => Time.now.utc.strftime('%Y-%02m-%02dT%02H:%02M:%02SZ'), 'isbn' => nil, 'titlefile' => nil, 'originaltitlefile' => nil, 'profile' => nil, 'direction' => 'ltr', 'image_maxpixels' => 4_000_000, 'font_ext' => %w[ttf woff otf], 'epubmaker' => { 'flattoc' => nil, 'flattocindent' => true, 'ncx_indent' => [], 'zip_stage1' => 'zip -0Xq', 'zip_stage2' => 'zip -Xr9Dq', 'zip_addpath' => nil, 'hook_beforeprocess' => nil, 'hook_afterfrontmatter' => nil, 'hook_afterbody' => nil, 'hook_afterbackmatter' => nil, 'hook_aftercopyimage' => nil, 'hook_prepack' => nil, 'rename_for_legacy' => nil, 'verify_target_images' => nil, 'force_include_images' => [], 'cover_linear' => nil, 'back_footnote' => nil }, 'textmaker' => { 'th_bold' => nil } ] conf.maker = nil conf end def self.create(maker: nil, yamlfile: nil, config: nil) conf = self.values conf.maker = maker if yamlfile begin loader = ReVIEW::YAMLLoader.new conf.deep_merge!(loader.load_file(yamlfile)) rescue StandardError => e raise ReVIEW::ConfigError, "yaml error #{e.message}" end end # YAML configs will be overridden by command line options. if config conf.deep_merge!(config) end conf.migrate_parameters conf end def migrate_parameters # string to array %w[subject aut a-adp a-ann a-arr a-art a-asn a-aqt a-aft a-aui a-ant a-bkp a-clb a-cmm a-dsr a-edt a-ill a-lyr a-mdc a-mus a-nrt a-oth a-pht a-prt a-red a-rev a-spn a-ths a-trc a-trl adp ann arr art asn aut aqt aft aui ant bkp clb cmm dsr edt ill lyr mdc mus nrt oth pht pbl prt red rev spn ths trc trl stylesheet rights].each do |item| if self[item] && self[item].is_a?(String) self[item] = [self[item]] end end # backward compatibility if self['mathml'] warn '"mathml: true" is obsoleted. Please use "math_format: mathml"' self['math_format'] = 'mathml' end if self['imgmath'] warn '"imgmath: true" is obsoleted. Please use "math_format: imgmath"' self['math_format'] = 'imgmath' end end def [](key) maker = self.maker if maker && self.key?(maker) && self.fetch(maker) && self.fetch(maker).key?(key) return self.fetch(maker).fetch(key, nil) end if self.key?(key) return self.fetch(key) end nil end def check_version(version, exception: true) unless self.key?('review_version') if exception raise ReVIEW::ConfigError, 'configuration file has no review_version property.' else return false end end if self['review_version'].blank? return true end if self['review_version'].to_i != version.to_i ## major version if exception raise ReVIEW::ConfigError, 'major version of configuration file is different.' else return false end elsif self['review_version'].to_f > version.to_f ## minor version if exception raise ReVIEW::ConfigError, "Re:VIEW version '#{version}' is older than configuration file's version '#{self['review_version']}'." else return false end end return true end def name_of(key) if self[key].is_a?(Array) self[key].join(',') # i18n? elsif self[key].is_a?(Hash) self[key]['name'] else self[key] end end def names_of(key) if self[key].is_a?(Array) self[key].map do |a| if a.is_a?(Hash) a['name'] else a end end elsif self[key].is_a?(Hash) [self[key]['name']] else [self[key]] end end end end