Class: IsoDoc::Convert

Inherits:
Common
  • Object
show all
Defined in:
lib/isodoc/css.rb,
lib/isodoc/init.rb,
lib/isodoc/convert.rb

Constant Summary

Constants included from Function::Utils

Function::Utils::CLAUSE_ANCESTOR, Function::Utils::DOCTYPE_HDR, Function::Utils::NOTE_CONTAINER_ANCESTOR

Constants included from Function::Table

Function::Table::SW

Constants included from Function::Section

Function::Section::TERM_CLAUSE

Constants included from Function::Lists

Function::Lists::OL_STYLE

Constants included from Function::Inline

Function::Inline::MATHML

Constants included from Function::Cleanup

Function::Cleanup::FIGURE_WITH_FOOTNOTES

Constants included from Function::Blocks

Function::Blocks::EXAMPLE_TBL_ATTR, Function::Blocks::EXAMPLE_TD_ATTR

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ClassUtils

#case_strict, #case_strict1, #case_with_markup, #date_range, #liquid, #nearest_block_parent, #ns, #start_of_sentence

Methods included from Function::Utils

#attr_code, #cleanup_entities, #date_range, #emf?, #empty2nil, #eps?, #external_path, #extract_delims, #from_xhtml, #get_clause_id, #get_note_container_id, #header_strip, #header_strip_elem?, #image_localfile, #insert_tab, #labelled_ancestor, #liquid, #noko, #ns, #numeric_escapes, #populate_template, #save_dataimage, #save_svg, #sentence_join, #start_of_sentence, #to_xhtml, #to_xhtml_fragment, #to_xhtml_prep

Methods included from Function::ToWordHtml

#body_attr, #boilerplate, #define_head, #in_sourcecode, #info, #init_dir, #init_file, #make_body, #make_body1, #make_body2, #make_body3, #middle, #note?, #parse, #rel_tmpimagedir, #set_termdomain, #tmpimagedir

Methods included from Function::Terms

#admitted_term_parse, #definition_parse, #deprecated_term_parse, #modification_parse, #para_then_remainder, #term_parse, #termdef_parse, #termdocsource_parse, #termnote_delim, #termnote_parse, #termref_parse

Methods included from Function::Table

#colgroup, #make_tr_attr, #table_attrs, #table_parse, #table_title_parse, #tbody_parse, #tcaption, #tfoot_parse, #thead_parse, #tr_parse

Methods included from Function::Section

#abstract, #acknowledgements, #annex, #annex_attrs, #annex_name, #clause, #clause_attrs, #clause_name, #clause_parse, #clause_parse_subtitle, #clause_parse_title, #clause_parse_title1, #clause_title_depth, #clausedelim, #clausedelimspace, #copyright_parse, #feedback_parse, #foreword, #inline_header_title, #introduction, #is_clause?, #legal_parse, #license_parse, #preceding_floating_titles, #preface, #preface_block, #scope, #single_term_clause?, #symbols_abbrevs, #symbols_parse, #terms_defs, #terms_parse, #variant_title

Methods included from Function::References

#bibitem_ref_code, #biblio_list, #bibliography, #bibliography_parse, #bibliography_xpath, #bracket_if_num, #date_note_process, #docid_l10n, #docid_prefix, #implicit_reference, #iso_bibitem_entry_attrs, #nonstd_bibitem, #norm_ref, #norm_ref_xpath, #omit_docid_prefix, #pref_ref_code, #prefix_bracketed_ref, #ref_entry_code, #reference_format, #render_identifier, #standard?, #std_bibitem_entry, #unbracket, #unbracket1

Methods included from Function::Lists

#dl_attrs, #dl_parse, #dl_parse1, #dt_dd?, #dt_parse, #li_parse, #list_title_parse, #ol_attrs, #ol_depth, #ol_parse, #ol_style, #ul_attrs, #ul_parse

Methods included from Function::Inline

#add_parse, #asciimath_parse, #bookmark_parse, #br_parse, #callout_parse, #del_parse, #em_parse, #eref_parse, #eref_target, #eref_url, #error_parse, #hr_parse, #image_parse, #image_title_parse, #index_parse, #index_xref_parse, #keyword_parse, #latexmath_parse, #link_parse, #location_parse, #mathml_parse, #no_locality_parse, #origin_parse, #page_break, #pagebreak_parse, #section_break, #smallcap_parse, #span_parse, #stem_parse, #strike_parse, #strong_parse, #sub_parse, #suffix_url, #sup_parse, #termrefelem_parse, #text_parse, #tt_parse, #underline_parse, #xref_parse

Methods included from Function::Form

#form_parse, #input_parse, #label_parse, #option_parse, #select_parse, #text_input, #textarea_parse

Methods included from Function::Cleanup

#admonition_cleanup, #break_up_long_strings, #break_up_long_strings1, #cleanup, #example_cleanup, #figure_aside_process, #figure_cleanup, #figure_get_or_make_dl, #footnote_cleanup, #footnote_reference_format, #inline_header_cleanup, #merge_fnref_into_fn_text, #new_fullcolspan_row, #passthrough_cleanup, #remove_bottom_border, #symbols_cleanup, #table_cleanup, #table_footnote_cleanup, #table_footnote_cleanup_propagate, #table_footnote_reference_format, #table_get_or_make_tfoot, #table_long_strings_cleanup, #table_note_cleanup, #textcleanup

Methods included from Function::Blocks

#admonition_attrs, #admonition_class, #admonition_name, #admonition_name_parse, #admonition_parse, #annotation_parse, #div_parse, #example_div_attr, #example_div_parse, #example_label, #example_parse, #example_table_attr, #example_table_parse, #figure_attrs, #figure_key, #figure_name_parse, #figure_parse, #figure_parse1, #formula_attrs, #formula_parse, #formula_parse1, #formula_where, #keep_style, #middle_admonitions, #middle_title, #note_attrs, #note_delim, #note_p_parse, #note_parse, #note_parse1, #para_attrs, #para_class, #para_parse, #passthrough_parse, #permission_parse, #pre_parse, #pseudocode_attrs, #pseudocode_parse, #quote_attribution, #quote_parse, #recommendation_name, #recommendation_parse, #recommendation_parse1, #reqt_attrs, #requirement_parse, #sourcecode_attrs, #sourcecode_name_parse, #sourcecode_parse, #svg_parse, #toc_parse

Constructor Details

#initialize(options) ⇒ Convert

htmlstylesheet: Generic stylesheet for HTML htmlstylesheet_override: Override stylesheet for HTML wordstylesheet: Generic stylesheet for Word wordstylesheet_override: Override stylesheet for Word standardsheet: Stylesheet specific to Standard header: Header file for Word htmlcoverpage: Cover page for HTML wordcoverpage: Cover page for Word htmlintropage: Introductory page for HTML wordintropage: Introductory page for Word normalfontsize: Font size for body text smallerfontsize: Font size for smaller than body text monospacefontsize: Font size for monospace font footnotefontsize: Font size for footnotes i18nyaml: YAML file for internationalisation of text ulstyle: list style in Word CSS for unordered lists olstyle: list style in Word CSS for ordered lists bodyfont: font to use for body text headerfont: font to use for header text monospace: font to use for monospace text suppressheadingnumbers: suppress heading numbers for clauses scripts: Scripts file for HTML scripts_override: Override scripts file for HTML scripts_pdf: Scripts file for PDF (not used in XSLT PDF) datauriimage: Encode images in HTML output as data URIs break_up_urls_in_tables: whether to insert spaces in URLs in tables

every 40-odd chars

sectionsplit: split up HTML output on sections bare: do not insert any prefatory material (coverpage, boilerplate) tocfigures: add ToC for figures toctables: add ToC for tables tocrecommendations: add ToC for rcommendations fonts: fontist fonts to install fontlicenseagreement: fontist font license agreement



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/isodoc/convert.rb', line 50

def initialize(options) # rubocop:disable Lint/MissingSuper
  @options = options_preprocess(options)
  init_stylesheets(@options)
  init_covers(@options)
  init_toc(@options)
  init_fonts(@options)
  init_processing
  init_locations(@options)
  init_i18n(@options)
  init_rendering(@options)
end

Instance Attribute Details

#i18nObject

Returns the value of attribute i18n.



14
15
16
# File 'lib/isodoc/convert.rb', line 14

def i18n
  @i18n
end

#metaObject

Returns the value of attribute meta.



14
15
16
# File 'lib/isodoc/convert.rb', line 14

def meta
  @meta
end

#optionsObject

Returns the value of attribute options.



14
15
16
# File 'lib/isodoc/convert.rb', line 14

def options
  @options
end

#reqt_modelsObject

Returns the value of attribute reqt_models.



14
15
16
# File 'lib/isodoc/convert.rb', line 14

def reqt_models
  @reqt_models
end

#requirements_processorObject

Returns the value of attribute requirements_processor.



14
15
16
# File 'lib/isodoc/convert.rb', line 14

def requirements_processor
  @requirements_processor
end

#xrefsObject

Returns the value of attribute xrefs.



14
15
16
# File 'lib/isodoc/convert.rb', line 14

def xrefs
  @xrefs
end

Instance Method Details

#bibitem_lookup(docxml) ⇒ Object



195
196
197
198
199
200
# File 'lib/isodoc/convert.rb', line 195

def bibitem_lookup(docxml)
  @bibitems = docxml.xpath(ns("//references/bibitem"))
    .each_with_object({}) do |b, m|
    m[b["id"]] = b
  end
end

#convert(input_filename, file = nil, debug = false, output_filename = nil) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/isodoc/convert.rb', line 222

def convert(input_filename, file = nil, debug = false,
            output_filename = nil)
  file = File.read(input_filename, encoding: "utf-8") if file.nil?
  @openmathdelim, @closemathdelim = extract_delims(file)
  docxml, filename, dir = convert_init(file, input_filename, debug)
  result = convert1(docxml, filename, dir)
  return result if debug

  output_filename ||= "#{filename}.#{@suffix}"
  postprocess(result, output_filename, dir)
  FileUtils.rm_rf dir
end

#convert1(docxml, filename, dir) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/isodoc/convert.rb', line 181

def convert1(docxml, filename, dir)
  @xrefs.parse docxml
  bibitem_lookup(docxml)
  noko do |xml|
    xml.html **{ lang: @lang.to_s } do |html|
      html.parent.add_namespace("epub", "http://www.idpf.org/2007/ops")
      info docxml, nil
      populate_css
      html.head { |head| define_head head, filename, dir }
      make_body(html, docxml)
    end
  end.join("\n")
end

#convert_i18n_init(docxml) ⇒ Object



212
213
214
215
216
217
218
219
220
# File 'lib/isodoc/convert.rb', line 212

def convert_i18n_init(docxml)
  lang = docxml.at(ns("//bibdata/language")) and @lang = lang.text
  script = docxml.at(ns("//bibdata/script")) and @script = script.text
  locale = docxml.at(ns("//bibdata/locale")) and @locale = locale.text
  i18n_init(@lang, @script, @locale)
  @reqt_models = requirements_processor
    .new({ default: "default", lang: @lang, script: @script, locale: @locale,
           labels: @i18n.get })
end

#convert_init(file, input_filename, debug) ⇒ Object



202
203
204
205
206
207
208
209
210
# File 'lib/isodoc/convert.rb', line 202

def convert_init(file, input_filename, debug)
  docxml = Nokogiri::XML(file) { |config| config.huge }
  filename, dir = init_file(input_filename, debug)
  docxml.root.default_namespace = ""
  convert_i18n_init(docxml)
  (@lang, @script, @locale, @i18n)
  xref_init(@lang, @script, self, @i18n, {locale: @locale})
  [docxml, filename, dir]
end

#convert_scss(filename, stylesheet, stripwordcss) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/isodoc/css.rb', line 77

def convert_scss(filename, stylesheet, stripwordcss)
  require "sassc"
  require "isodoc/sassc_importer"

  [File.join(Gem.loaded_specs["isodoc"].full_gem_path,
             "lib", "isodoc"),
   File.dirname(filename)].each do |name|
    SassC.load_paths << name
  end
  SassC::Engine.new(scss_fontheader(stripwordcss) + stylesheet,
                    syntax: :scss, importer: SasscImporter)
    .render
end

#default_file_locations(_options) ⇒ Object

none for this parent gem, but will be populated in child gems which have access to stylesheets &c



48
49
50
# File 'lib/isodoc/css.rb', line 48

def default_file_locations(_options)
  {}
end

#default_fonts(_options) ⇒ Object



38
39
40
41
42
43
44
# File 'lib/isodoc/css.rb', line 38

def default_fonts(_options)
  {
    bodyfont: "Arial",
    headerfont: "Arial",
    monospacefont: "Courier New",
  }
end

#fonts_optionsObject



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/isodoc/css.rb', line 52

def fonts_options
  {
    "bodyfont" => options[:bodyfont] || "Arial",
    "headerfont" => options[:headerfont] || "Arial",
    "monospacefont" => options[:monospacefont] || "Courier New",
    "normalfontsize" => options[:normalfontsize],
    "monospacefontsize" => options[:monospacefontsize],
    "smallerfontsize" => options[:smallerfontsize],
    "footnotefontsize" => options[:footnotefontsize],
  }
end

#generate_css(filename, stripwordcss) ⇒ Object

stripwordcss if HTML stylesheet, !stripwordcss if DOC stylesheet



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/isodoc/css.rb', line 92

def generate_css(filename, stripwordcss)
  return nil if filename.nil?

  filename = precompiled_style_or_original(filename)
  stylesheet = File.read(filename, encoding: "UTF-8")
  stylesheet = populate_template(stylesheet, :word)
  stylesheet.gsub!(/(\s|\{)mso-[^:]+:[^;]+;/m, "\\1") if stripwordcss
  stylesheet.gsub!(/--/, "-DOUBLE_HYPHEN_ESCAPE-") unless stripwordcss
  if File.extname(filename) == ".scss"
    stylesheet = convert_scss(filename, stylesheet, stripwordcss)
  end
  Tempfile.open([File.basename(filename, ".*"), "css"],
                encoding: "utf-8") do |f|
    f.write(stylesheet)
    f
  end
end

#html_doc_path(*file) ⇒ Object



169
170
171
172
173
174
175
# File 'lib/isodoc/convert.rb', line 169

def html_doc_path(*file)
  file.each do |f|
    ret = File.join(@libdir, File.join("html", f))
    File.exist?(ret) and return ret
  end
  nil
end

#i18n_init(lang, script, locale, i18nyaml = nil) ⇒ Object



12
13
14
15
# File 'lib/isodoc/init.rb', line 12

def i18n_init(lang, script, locale, i18nyaml = nil)
  @i18n = I18n.new(lang, script, locale: locale,
                                 i18nyaml: i18nyaml || @i18nyaml)
end

#init_covers(options) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
# File 'lib/isodoc/convert.rb', line 131

def init_covers(options)
  @header = options[:header]
  @htmlcoverpage = options[:htmlcoverpage]
  @wordcoverpage = options[:wordcoverpage]
  @htmlintropage = options[:htmlintropage]
  @wordintropage = options[:wordintropage]
  @scripts = options[:scripts] ||
    File.join(File.dirname(__FILE__), "base_style", "scripts.html")
  @scripts_pdf = options[:scripts_pdf]
  @scripts_override = options[:scripts_override]
end

#init_fonts(options) ⇒ Object



122
123
124
125
126
127
128
129
# File 'lib/isodoc/convert.rb', line 122

def init_fonts(options)
  @normalfontsize = options[:normalfontsize]
  @smallerfontsize = options[:smallerfontsize]
  @monospacefontsize = options[:monospacefontsize]
  @footnotefontsize = options[:footnotefontsize]
  @fontist_fonts = options[:fonts]
  @fontlicenseagreement = options[:fontlicenseagreement]
end

#init_i18n(options) ⇒ Object



83
84
85
86
87
88
89
# File 'lib/isodoc/convert.rb', line 83

def init_i18n(options)
  @i18nyaml = options[:i18nyaml]
  @lang = options[:language] || "en"
  @script = options[:script] || "Latn"
  @locale = options[:locale]
  @localizenumber = options[:localizenumber]
end

#init_locations(options) ⇒ Object



91
92
93
94
95
96
97
98
99
# File 'lib/isodoc/convert.rb', line 91

def init_locations(options)
  @libdir ||= File.dirname(__FILE__)
  @baseassetpath = options[:baseassetpath]
  @tmpimagedir_suffix = tmpimagedir_suffix
  @tmpfilesdir_suffix = tmpfilesdir_suffix
  @sourcefilename = options[:sourcefilename]
  @files_to_delete = []
  @tempfile_cache = []
end

#init_processingObject



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/isodoc/convert.rb', line 101

def init_processing
  @termdomain = ""
  @termexample = false
  @note = false
  @sourcecode = false
  @footnotes = []
  @comments = []
  @in_footnote = false
  @in_comment = false
  @in_table = false
  @in_figure = false
  @seen_footnote = Set.new
  @c = HTMLEntities.new
  @openmathdelim = "`"
  @closemathdelim = "`"
  @maxwidth = 1200
  @maxheight = 800
  @bookmarks_allocated = { "X" => true }
  @fn_bookmarks = {}
end

#init_rendering(options) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/isodoc/convert.rb', line 71

def init_rendering(options)
  @ulstyle = options[:ulstyle]
  @olstyle = options[:olstyle]
  @datauriimage = options[:datauriimage]
  @suppressheadingnumbers = options[:suppressheadingnumbers]
  @break_up_urls_in_tables = options[:break_up_urls_in_tables] == "true"
  @sectionsplit = options[:sectionsplit] == "true"
  @suppressasciimathdup = options[:suppressasciimathdup] == "true"
  @bare = options[:bare]
  @aligncrosselements = options[:aligncrosselements]
end

#init_stylesheets(options) ⇒ Object



143
144
145
146
147
148
149
# File 'lib/isodoc/convert.rb', line 143

def init_stylesheets(options)
  @htmlstylesheet_name = options[:htmlstylesheet]
  @wordstylesheet_name = options[:wordstylesheet]
  @htmlstylesheet_override_name = options[:htmlstylesheet_override]
  @wordstylesheet_override_name = options[:wordstylesheet_override]
  @standardstylesheet_name = options[:standardstylesheet]
end

#init_toc(options) ⇒ Object



151
152
153
154
155
156
157
158
159
# File 'lib/isodoc/convert.rb', line 151

def init_toc(options)
  @wordToClevels = options[:doctoclevels].to_i
  @wordToClevels = 2 if @wordToClevels.zero?
  @htmlToClevels = options[:htmltoclevels].to_i
  @htmlToClevels = 2 if @htmlToClevels.zero?
  @tocfigures = options[:tocfigures]
  @toctables = options[:toctables]
  @tocrecommendations = options[:tocrecommendations]
end

#l10n(expr, lang = @lang, script = @script, locale = @locale) ⇒ Object



17
18
19
# File 'lib/isodoc/init.rb', line 17

def l10n(expr, lang = @lang, script = @script, locale = @locale)
  @i18n.l10n(expr, lang, script, locale)
end

#localpath(path) ⇒ Object



19
20
21
22
23
24
# File 'lib/isodoc/css.rb', line 19

def localpath(path)
  return path if %r{^[A-Z]:|^/|^file:/}.match?(path)
  return path unless (@sourcedir || @localdir) && path

  File.expand_path(File.join((@sourcedir || @localdir), path))
end

#metadata_init(lang, script, locale, i18n) ⇒ Object



3
4
5
# File 'lib/isodoc/init.rb', line 3

def (lang, script, locale, i18n)
  @meta = Metadata.new(lang, script, locale, i18n)
end

#middle_clause(_docxml = nil) ⇒ Object



235
236
237
238
# File 'lib/isodoc/convert.rb', line 235

def middle_clause(_docxml = nil)
  "//clause[parent::sections][not(@type = 'scope')]"\
    "[not(descendant::terms)]"
end

#options_preprocess(options) ⇒ Object



62
63
64
65
66
67
68
69
# File 'lib/isodoc/convert.rb', line 62

def options_preprocess(options)
  options.merge!(default_fonts(options)) do |_, old, new|
    old || new
  end.merge!(default_file_locations(options)) do |_, old, new|
    old || new
  end
  options
end

#populate_cssObject

run this after @meta is populated



27
28
29
30
31
32
33
34
35
36
# File 'lib/isodoc/css.rb', line 27

def populate_css
  @htmlstylesheet = generate_css(localpath(@htmlstylesheet_name), true)
  @wordstylesheet = generate_css(localpath(@wordstylesheet_name), false)
  @standardstylesheet =
    generate_css(localpath(@standardstylesheet_name), false)
  @htmlstylesheet_override_name and
    @htmlstylesheet_override = File.open(localpath(@htmlstylesheet_override_name))
  @wordstylesheet_override_name and
    @wordstylesheet_override = File.open(localpath(@wordstylesheet_override_name))
end

#precompiled_style_or_original(stylesheet_path) ⇒ Object

Check if already compiled version(.css) exists,

if not, return original scss file. During release
we compile scss into css files in order to not depend on scss


6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/isodoc/css.rb', line 6

def precompiled_style_or_original(stylesheet_path)
  # Already have compiled stylesheet, use it
  return stylesheet_path if stylesheet_path.nil? ||
    File.extname(stylesheet_path) == ".css"

  basename = File.basename(stylesheet_path, ".*")
  compiled_path = File.join(File.dirname(stylesheet_path),
                            "#{basename}.css")
  return stylesheet_path unless File.file?(compiled_path)

  compiled_path
end

#scss_fontheader(is_html_css) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/isodoc/css.rb', line 64

def scss_fontheader(is_html_css)
  b = options[:bodyfont] || "Arial"
  h = options[:headerfont] || "Arial"
  m = options[:monospacefont] || "Courier New"
  ns = options[:normalfontsize] || (is_html_css ? "1.0em" : "12.0pt")
  ms = options[:monospacefontsize] || (is_html_css ? "0.8em" : "11.0pt")
  ss = options[:smallerfontsize] || (is_html_css ? "0.9em" : "10.0pt")
  fs = options[:footnotefontsize] || (is_html_css ? "0.9em" : "9.0pt")
  "$bodyfont: #{b};\n$headerfont: #{h};\n$monospacefont: #{m};\n"\
    "$normalfontsize: #{ns};\n$monospacefontsize: #{ms};\n"\
    "$smallerfontsize: #{ss};\n$footnotefontsize: #{fs};\n"
end

#target_pdf(node) ⇒ Object



240
241
242
243
244
# File 'lib/isodoc/convert.rb', line 240

def target_pdf(node)
  if /#/.match?(node["target"]) then node["target"].sub(/#/, ".pdf#")
  else "##{node['target']}"
  end
end

#tmpfilesdir_suffixObject



165
166
167
# File 'lib/isodoc/convert.rb', line 165

def tmpfilesdir_suffix
  "_#{SecureRandom.hex(8)}_files"
end

#tmpimagedir_suffixObject



161
162
163
# File 'lib/isodoc/convert.rb', line 161

def tmpimagedir_suffix
  "_#{SecureRandom.hex(8)}_images"
end

#xref_init(lang, script, _klass, i18n, options) ⇒ Object



7
8
9
10
# File 'lib/isodoc/init.rb', line 7

def xref_init(lang, script, _klass, i18n, options)
  html = HtmlConvert.new(language: @lang, script: @script)
  @xrefs = Xref.new(lang, script, html, i18n, options)
end