Class: PandocRefeqMathml

Inherits:
Object
  • Object
show all
Defined in:
lib/pandoc_refeq_mathml.rb

Overview

Class to handle MathML and LaTeX aux

Constant Summary collapse

EQNARRAY_ALIGNS =

Alignment for LaTeX eqnarray.

%w(right center left)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(page, auxstr, logio: $stderr, is_verbose: true) ⇒ PandocRefeqMathml

Returns a new instance of PandocRefeqMathml.

Parameters:

  • page (Nokogiri::HTML4::Document)
  • auxstr (String)

    String of the contents of a LaTeX aux file

  • logio (IO) (defaults to: $stderr)

    Output IO for logs. You may give IO.open(“/dev/null”, “w”). Def: $stderr

  • is_verbose (Boolean) (defaults to: true)

    If true (Default), verbose.



18
19
20
21
22
23
24
# File 'lib/pandoc_refeq_mathml.rb', line 18

def initialize(page, auxstr, logio: $stderr, is_verbose: true)
  @page = page
  @auxstr = auxstr
  @logio = logio
  @is_verbose = is_verbose
  @hslabel = {}  # String(label) => String(EqNumber), which have been detected.
end

Instance Attribute Details

#auxObject (readonly)

Returns the value of attribute aux.



9
10
11
# File 'lib/pandoc_refeq_mathml.rb', line 9

def aux
  @aux
end

#pageObject (readonly)

Returns the value of attribute page.



9
10
11
# File 'lib/pandoc_refeq_mathml.rb', line 9

def page
  @page
end

Instance Method Details

#alter_align_eqnarray!Object

Alter the alignments of mtable originating from eqnarray

Original is all right-aligned. After alteration, it will be right, center, left (which is the specification of eqnarray).



126
127
128
129
130
131
132
133
# File 'lib/pandoc_refeq_mathml.rb', line 126

def alter_align_eqnarray!
  @page.css("math mtable mtr").each do |ea_mtr|
    ea_mtr.css("mtd").each_with_index do |ea_mtd, i|
      break if i >= EQNARRAY_ALIGNS.size
      ea_mtd["columnalign"]=EQNARRAY_ALIGNS[i]
    end
  end
end

#alter_html!(fixalign: true) ⇒ Object

Parameters:

  • fixalign (Boolean) (defaults to: true)

    fix alignments if true



161
162
163
164
# File 'lib/pandoc_refeq_mathml.rb', line 161

def alter_html!(fixalign: true)
  alter_align_eqnarray! if fixalign
  alter_reflinks!
end

This method returns an undefined value.

Parameters:

  • kwdlink (String)

    label

  • taga (Nokogiri::HTML4::Document)

    Nokogiri <A> object.

  • n_eq_str (String)

    equation number string



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/pandoc_refeq_mathml.rb', line 108

def alter_link_text(kwdlink, taga, n_eq_str)
  textnode = taga.children[0]
  if !textnode.text?
    @logio.puts "WARNING: Inconsistent text inside href: "+taga.to_s
    return nil
  end

  if /\A\[?#{Regexp.quote(kwdlink)}\]?\z/ !~ textnode.to_s.strip
    @logio.puts "WARNING: Strange linked-text=(#{textnode.to_s}) inside <a>: "+a.to_s if @is_verbose
  end

  taga.content=n_eq_str
end

#alter_reflinks!Object

Alter the existing HTML Nokogiri content



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/pandoc_refeq_mathml.rb', line 136

def alter_reflinks!
  all_ref_href = @page.css("a[data-reference-type=ref]")
  all_ref_href.each do |ea_nodes|
    # Gets a label from MathML
    (kwdlink = get_label(ea_nodes)) || next

    if !@hslabel.keys.include? kwdlink
      # Gets the number of the equation from Aux
      n_eq = get_eq_num(kwdlink)
      next if !n_eq
      @hslabel[kwdlink] = n_eq

      # Finds the equation in MathML and adds the number of the equation.
      find_insert_n_eq(kwdlink, n_eq) # this returns nil if something goes wrong
    elsif !@hslabel[kwdlink]
      # the label "kwdlink" has been detected, but no Equation-number was found.
      next
    end

    # Alter the original link text in MathML to Equation number.
    alter_link_text(kwdlink, ea_nodes, @hslabel[kwdlink])
  end
end

#find_insert_n_eq(kwdlink, n_eq) ⇒ Integer, NilClass

Returns If something goes wrong,.

Parameters:

  • kwdlink (String)

    label

  • n_eq (String)

    Equation number like “58”, maybe “52.3”

Returns:

  • (Integer, NilClass)

    If something goes wrong,



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/pandoc_refeq_mathml.rb', line 55

def find_insert_n_eq(kwdlink, n_eq)
  # Select the <math> tag component that hs the kwdlink
  maths = @page.css('math').select{|ep|
    /\\label\{\s*#{Regexp.quote(kwdlink)}\s*\}/ =~ (ep.css('annotation[encoding="application/x-tex"]').children[0].text.strip rescue "X")
  }
  if maths.size != 1
    if maths.size == 0
      @logio.puts 'WARNING: no math tag contains label="#{kwdlink}"'
    else
      @logio.print 'WARNING: Multiple math tags contain label="#{kwdlink}"'
      @logio.puts (@is_verbose ? ": maths="+maths.inspect : "")
    end
    return nil
  end

  mtext = sprintf '<mtext id="%s" style="padding-left:1em; text-align:right;">(%s)</mtext>', kwdlink, n_eq
  
  if maths[0].css('mtable').empty?
    # \begin{equation}
    #
    # Insert the new node (<mrow><mtext...>(65)</mtext></mrow>) as the last child of
    # the last top-level existing <mrow>; if it is added AFTER the <mrow>
    # the <mtext> number would not be displayed!
    newnode = '<mrow>' + mtext + '</mrow>'
    begin
      maths[0].css("mrow")[0].parent.css("> mrow")[-1].add_child(newnode)
        # Between the last <mrow> and <annotation>
        # n.b., css('mrow')[-1] would give an mrow inside another mrow!
    rescue
      msg = "FATAL: contact the code developer: equation: maths[0]="+maths[0].inspect
      @logio.puts msg
      raise msg
    end
    return 0
  else
    # \begin{eqnarray}
    newnode = '<mtd columnalign="right">' + mtext + '</mtd>'
    annot_node= maths[0].css('annotation[encoding="application/x-tex"]')[0]
    i_eq_annot = annot_node.children[0].text.split(/\\\\\s*(?:\%[^\n]*)?\n?/).find_index{|ev| /\\label\{#{kwdlink}\}/ =~ ev}  # Index of the equation (starting from 0) in the eqnarray
    raise "FATAL: contact the code developer: eqnarray: "+annot_node.inspect if !i_eq_annot

    # Insert the new node (<mtd><mtext...>(65)</mtext></mtd>)
    mtrnode = maths[0].css('mtable mtr')[i_eq_annot]
    # mtrnode.css('mtd')[-1].add_next_sibling(newnode)  # not considering multi-layer tables
    find_last_shallowest(mtrnode, 'mtd').add_next_sibling(newnode)
  end
  return i_eq_annot+1
end

#get_eq_num(kwdlink) ⇒ String, NilClass

Return the equation number.

The number is assumed to contain only numbers and maybe full-stops [d.].

Returns:

  • (String, NilClass)

    Equation number guessed from the Aux file. nil if something goes wrong.



41
42
43
44
45
46
47
48
49
50
# File 'lib/pandoc_refeq_mathml.rb', line 41

def get_eq_num(kwdlink)
  mat = /^\\newlabel\{#{kwdlink}\}\{\{([\d\.]+)\}\{(\d+)\}\{(.*)\}\{equation.([a-zA-Z\d\.]+)\}/.match @auxstr  # it may be like equation.B.193 (for Appendix B).
     # => #<MatchData "\\newlabel{eq_my_lab}{{65}{35}{割り算}{equation.4.62}" 1:"65" 2:"35" 3:"割り算" 4:"4.62">
  return mat[1] if mat && mat[1] && !mat[1].empty?

  ## Something is wrong. 
  str = sprintf 'WARNING: Not found equation number for label="%s" (maybe it is for a section etc?): MatchData=%s', kwdlink, mat.inspect
  @logio.puts str
  return nil
end

#get_label(taga) ⇒ String, NilClass

Returns Label string used in <a href=..>. Nil if something is wrong.

Parameters:

  • taga (Nokogiri::HTML4::Document)

    Nokogiri <A> object.

Returns:

  • (String, NilClass)

    Label string used in <a href=..>. Nil if something is wrong.



28
29
30
31
32
33
34
# File 'lib/pandoc_refeq_mathml.rb', line 28

def get_label(taga)
  kwdlink = taga['href'].split('#')[1]
  return kwdlink if kwdlink == taga['data-reference']

  @logio.puts "WARNING: Inconsistent href and data-reference: "+a.to_s if @is_verbose
  return nil
end