html2doc 0.9.4 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/macos.yml +10 -4
- data/.github/workflows/ubuntu.yml +29 -5
- data/.github/workflows/windows.yml +11 -6
- data/README.adoc +8 -4
- data/html2doc.gemspec +1 -1
- data/lib/html2doc/lists.rb +17 -8
- data/lib/html2doc/math.rb +5 -1
- data/lib/html2doc/mime.rb +1 -0
- data/lib/html2doc/notes.rb +19 -7
- data/lib/html2doc/version.rb +1 -1
- data/spec/html2doc_spec.rb +59 -23
- metadata +8 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89f05f87cd25266b64654929b7087a07c912fcf8b24beb33f2faceb5123da190
|
4
|
+
data.tar.gz: de12518aafb1ac65bf1f4addf76f16ff246c58aa99561e321dc3d8af7cd0a623
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 535aa46b12785253d9b5ebacf7f0c70f2f7045a5367dbf3ae2c023188a6005be39f6f003574d7855ca8ca2e757ddcde2f5128602e18156699248281fa6db4502
|
7
|
+
data.tar.gz: 5452e2880c9ba6f231d02039e5f2b2054e5535c903539f34804c65aeb77b63361994fd604f9d3d92ce808244fa5c46e9fc790f747041955606a1a474bdd02449
|
data/.github/workflows/macos.yml
CHANGED
@@ -1,28 +1,34 @@
|
|
1
|
-
# Auto-generated
|
2
|
-
#
|
1
|
+
# Auto-generated by Cimas: Do not edit it manually!
|
2
|
+
# See https://github.com/metanorma/cimas
|
3
3
|
name: macos
|
4
4
|
|
5
5
|
on:
|
6
6
|
push:
|
7
7
|
branches: [ master ]
|
8
8
|
pull_request:
|
9
|
-
|
9
|
+
paths-ignore:
|
10
|
+
- .github/workflows/ubuntu.yml
|
11
|
+
- .github/workflows/windows.yml
|
10
12
|
|
11
13
|
jobs:
|
12
14
|
test-macos:
|
13
15
|
name: Test on Ruby ${{ matrix.ruby }} macOS
|
14
16
|
runs-on: macos-latest
|
17
|
+
continue-on-error: ${{ matrix.experimental }}
|
15
18
|
strategy:
|
16
19
|
fail-fast: false
|
17
20
|
matrix:
|
18
21
|
ruby: [ '2.6', '2.5', '2.4' ]
|
22
|
+
experimental: [false]
|
23
|
+
include:
|
24
|
+
- ruby: '2.7'
|
25
|
+
experimental: true
|
19
26
|
steps:
|
20
27
|
- uses: actions/checkout@master
|
21
28
|
- name: Use Ruby
|
22
29
|
uses: actions/setup-ruby@v1
|
23
30
|
with:
|
24
31
|
ruby-version: ${{ matrix.ruby }}
|
25
|
-
architecture: 'x64'
|
26
32
|
- name: Update gems
|
27
33
|
run: |
|
28
34
|
sudo gem install bundler --force
|
@@ -1,32 +1,56 @@
|
|
1
|
-
# Auto-generated
|
2
|
-
#
|
1
|
+
# Auto-generated by Cimas: Do not edit it manually!
|
2
|
+
# See https://github.com/metanorma/cimas
|
3
3
|
name: ubuntu
|
4
4
|
|
5
5
|
on:
|
6
6
|
push:
|
7
7
|
branches: [ master ]
|
8
|
+
tags:
|
9
|
+
- '*'
|
8
10
|
pull_request:
|
9
|
-
|
11
|
+
paths-ignore:
|
12
|
+
- .github/workflows/macos.yml
|
13
|
+
- .github/workflows/windows.yml
|
10
14
|
|
11
15
|
jobs:
|
12
16
|
test-linux:
|
13
17
|
name: Test on Ruby ${{ matrix.ruby }} Ubuntu
|
14
18
|
runs-on: ubuntu-latest
|
19
|
+
continue-on-error: ${{ matrix.experimental }}
|
15
20
|
strategy:
|
16
21
|
fail-fast: false
|
17
22
|
matrix:
|
18
23
|
ruby: [ '2.6', '2.5', '2.4' ]
|
24
|
+
experimental: [false]
|
25
|
+
include:
|
26
|
+
- ruby: '2.7'
|
27
|
+
experimental: true
|
19
28
|
steps:
|
20
29
|
- uses: actions/checkout@master
|
21
30
|
- name: Use Ruby
|
22
31
|
uses: actions/setup-ruby@v1
|
23
32
|
with:
|
24
33
|
ruby-version: ${{ matrix.ruby }}
|
25
|
-
architecture: 'x64'
|
26
34
|
- name: Update gems
|
27
35
|
run: |
|
28
|
-
gem install bundler
|
36
|
+
gem install bundler
|
29
37
|
bundle install --jobs 4 --retry 3
|
30
38
|
- name: Run specs
|
31
39
|
run: |
|
32
40
|
bundle exec rake
|
41
|
+
- name: Trigger repositories
|
42
|
+
if: matrix.ruby == '2.6'
|
43
|
+
env:
|
44
|
+
GH_USERNAME: metanorma-ci
|
45
|
+
GH_ACCESS_TOKEN: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
|
46
|
+
run: |
|
47
|
+
curl -LO --retry 3 https://raw.githubusercontent.com/metanorma/metanorma-build-scripts/master/trigger-gh-actions.sh
|
48
|
+
[[ -f ".github/workflows/dependent_repos.env" ]] && source .github/workflows/dependent_repos.env
|
49
|
+
CLIENT_PAYLOAD=$(cat <<EOF
|
50
|
+
"{ "ref": "${GITHUB_REF}", "repo": "${GITHUB_REPOSITORY}" }"
|
51
|
+
EOF
|
52
|
+
)
|
53
|
+
for repo in $REPOS
|
54
|
+
do
|
55
|
+
sh trigger-gh-actions.sh $ORGANISATION $repo $GH_USERNAME $GH_ACCESS_TOKEN $GITHUB_REPOSITORY "$CLIENT_PAYLOAD"
|
56
|
+
done
|
@@ -1,34 +1,39 @@
|
|
1
|
-
# Auto-generated
|
2
|
-
#
|
1
|
+
# Auto-generated by Cimas: Do not edit it manually!
|
2
|
+
# See https://github.com/metanorma/cimas
|
3
3
|
name: windows
|
4
4
|
|
5
5
|
on:
|
6
6
|
push:
|
7
7
|
branches: [ master ]
|
8
8
|
pull_request:
|
9
|
-
|
9
|
+
paths-ignore:
|
10
|
+
- .github/workflows/macos.yml
|
11
|
+
- .github/workflows/ubuntu.yml
|
10
12
|
|
11
13
|
jobs:
|
12
14
|
test-windows:
|
13
15
|
name: Test on Ruby ${{ matrix.ruby }} Windows
|
14
16
|
runs-on: windows-latest
|
17
|
+
continue-on-error: ${{ matrix.experimental }}
|
15
18
|
strategy:
|
16
19
|
fail-fast: false
|
17
20
|
matrix:
|
18
21
|
ruby: [ '2.6', '2.5', '2.4' ]
|
22
|
+
experimental: [false]
|
23
|
+
include:
|
24
|
+
- ruby: '2.7'
|
25
|
+
experimental: true
|
19
26
|
steps:
|
20
27
|
- uses: actions/checkout@master
|
21
28
|
- name: Use Ruby
|
22
29
|
uses: actions/setup-ruby@v1
|
23
30
|
with:
|
24
31
|
ruby-version: ${{ matrix.ruby }}
|
25
|
-
architecture: 'x64'
|
26
32
|
- name: Update gems
|
27
33
|
shell: pwsh
|
28
34
|
run: |
|
29
|
-
gem install bundler
|
35
|
+
gem install bundler
|
30
36
|
bundle config --local path vendor/bundle
|
31
|
-
bundle update
|
32
37
|
bundle install --jobs 4 --retry 3
|
33
38
|
- name: Run specs
|
34
39
|
run: |
|
data/README.adoc
CHANGED
@@ -3,8 +3,9 @@
|
|
3
3
|
https://github.com/metanorma/html2doc/workflows/main/badge.svg
|
4
4
|
|
5
5
|
image:https://img.shields.io/gem/v/html2doc.svg["Gem Version", link="https://rubygems.org/gems/html2doc"]
|
6
|
-
image:https://
|
7
|
-
image:https://
|
6
|
+
image:https://github.com/metanorma/html2doc/workflows/ubuntu/badge.svg["Ubuntu Build Status", link="https://github.com/metanorma/html2doc/actions?query=workflow%3Aubuntu"]
|
7
|
+
image:https://github.com/metanorma/html2doc/workflows/macos/badge.svg["OSX Build Status", link="https://github.com/metanorma/html2doc/actions?query=workflow%3Amacos"]
|
8
|
+
image:https://github.com/metanorma/html2doc/workflows/windows/badge.svg["Windows Build Status", link="https://github.com/metanorma/html2doc/actions?query=workflow%3Awindows"]
|
8
9
|
image:https://codeclimate.com/github/metanorma/html2doc/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/html2doc"]
|
9
10
|
image:https://img.shields.io/github/issues-pr-raw/metanorma/html2doc.svg["Pull Requests", link="https://github.com/metanorma/html2doc/pulls"]
|
10
11
|
image:https://img.shields.io/github/commits-since/metanorma/html2doc/latest.svg["Commits since latest",link="https://github.com/metanorma/html2doc/releases"]
|
@@ -23,9 +24,12 @@ This work is driven by the Word document generation procedure documented in http
|
|
23
24
|
|
24
25
|
The gem currently does the following:
|
25
26
|
|
26
|
-
* Convert any AsciiMath and MathML to Word's native mathematical formatting language, OOXML. Word supports copy-pasting MathML into Word and converting it into OOXML; however the conversion is not infallible (we have found problems with `\sum`: Word claims parameters were missing, and inserting dotted squares to indicate as much), and you may need to post-edit the OOXML.
|
27
|
+
* Convert any AsciiMath and MathML to Word's native mathematical formatting language, OOXML. Word supports copy-pasting MathML into Word and converting it into OOXML; however the conversion is not infallible (we have in the past found problems with `\sum`: Word claims parameters were missing, and inserting dotted squares to indicate as much), and you may need to post-edit the OOXML.
|
27
28
|
** The gem does attempt to repair the MathML input, to bring it in line with Word's OOXML's expectations. If you find any issues with AsciiMath or MathML input, please raise an issue.
|
28
|
-
* Identify any footnotes in the document (defined as hyperlinks with attributes `class = "Footnote"` or `epub:type = "footnote"`), and render them as Microsoft Word footnotes.
|
29
|
+
* Identify any footnotes in the document (defined as hyperlinks with attributes `class = "Footnote"` or `epub:type = "footnote"`), and render them as Microsoft Word footnotes.
|
30
|
+
** The corresponding footnote content is any `div` or `aside` element with the same `@id` attribute as the footnote points to; e.g. `<a href="#ftn1" epub:type="footnote"><sup>3</sup></a></span>`, pointing to `<aside id="ftn3">`.
|
31
|
+
** By default, the footnote hyperlink contents are overwritten with the autonumbering element: `<a href="#ftn1" epub:type="footnote"><sup>1</sup></a>` is replaced with `<a style='mso-footnote-id:ftn1' href='#_ftn1' name='_ftnref1' title='' id='_ftnref1'><span class='MsoFootnoteReference'><span style='mso-special-character:footnote'/></span>`
|
32
|
+
** If the footnote hyperlink already contains (as a child) an element marked up as `<span class='MsoFootnoteReference'>`, only that span is replaced by the Microsoft autonumber element; any text surrounding it is preserved in both the footnote reference and the footnote target. For example, `<a href="#ftn1" epub:type="footnote"><span class='MsoFootnoteReference'>1</span>)</a>` will render as the footnote _1)_, both in the link and the target.
|
29
33
|
* Resize any local images in the HTML file to fit within the maximum page size. (Word will otherwise crash on reading the document.)
|
30
34
|
* Optionally apply list styles with predefined bullet and numbering from a Word CSS to the unordered and ordered lists in the document, restarting numbering for each ordered list.
|
31
35
|
* Convert all lists to native Word HTML rendering (using paragraphs with `MsoListParagraphCxSpFirst, MsoListParagraphCxSpMiddle, MsoListParagraphCxSpLast` styles)
|
data/html2doc.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_dependency "nokogiri", ">= 1.10.4"
|
32
32
|
spec.add_dependency "thread_safe"
|
33
33
|
spec.add_dependency "uuidtools"
|
34
|
-
spec.add_dependency "asciimath", "~>
|
34
|
+
spec.add_dependency "asciimath", "~> 2.0.0"
|
35
35
|
|
36
36
|
spec.add_development_dependency "byebug", "~> 9.1"
|
37
37
|
spec.add_development_dependency "equivalent-xml", "~> 0.6"
|
data/lib/html2doc/lists.rb
CHANGED
@@ -2,7 +2,7 @@ require "uuidtools"
|
|
2
2
|
require "asciimath"
|
3
3
|
require "htmlentities"
|
4
4
|
require "nokogiri"
|
5
|
-
require "
|
5
|
+
require "uuidtools"
|
6
6
|
|
7
7
|
module Html2Doc
|
8
8
|
def self.style_list(li, level, liststyle, listnumber)
|
@@ -15,13 +15,8 @@ module Html2Doc
|
|
15
15
|
li["style"] += "mso-list:#{liststyle} level#{level} lfo#{listnumber};"
|
16
16
|
end
|
17
17
|
|
18
|
-
def self.
|
19
|
-
|
20
|
-
@listnumber += 1 if level == 1
|
21
|
-
list["seen"] = true if level == 1
|
22
|
-
(list.xpath(".//li") - list.xpath(".//ol//li | .//ul//li")).each do |li|
|
23
|
-
style_list(li, level, liststyles[listtype], @listnumber)
|
24
|
-
if [:ul, :ol].include? listtype
|
18
|
+
def self.list_add1(li, liststyles, listtype, level)
|
19
|
+
if [:ul, :ol].include? listtype
|
25
20
|
list_add(li.xpath(".//ul") - li.xpath(".//ul//ul | .//ol//ul"),
|
26
21
|
liststyles, :ul, level + 1)
|
27
22
|
list_add(li.xpath(".//ol") - li.xpath(".//ul//ol | .//ol//ol"),
|
@@ -32,6 +27,20 @@ module Html2Doc
|
|
32
27
|
list_add(li.xpath(".//ol") - li.xpath(".//ul//ol | .//ol//ol"),
|
33
28
|
liststyles, listtype, level + 1)
|
34
29
|
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.list_add(xpath, liststyles, listtype, level)
|
33
|
+
xpath.each_with_index do |list, i|
|
34
|
+
@listnumber += 1 if level == 1
|
35
|
+
list["seen"] = true if level == 1
|
36
|
+
list["id"] ||= UUIDTools::UUID.random_create
|
37
|
+
(list.xpath(".//li") - list.xpath(".//ol//li | .//ul//li")).each do |li|
|
38
|
+
style_list(li, level, liststyles[listtype], @listnumber)
|
39
|
+
list_add1(li, liststyles, listtype, level)
|
40
|
+
end
|
41
|
+
list.xpath(".//ul[not(ancestor::li/ancestor::*/@id = '#{list['id']}')] | "\
|
42
|
+
".//ol[not(ancestor::li/ancestor::*/@id = '#{list['id']}')]").each do |li|
|
43
|
+
list_add1(li.parent, liststyles, listtype, level-1)
|
35
44
|
end
|
36
45
|
end
|
37
46
|
end
|
data/lib/html2doc/math.rb
CHANGED
@@ -9,7 +9,8 @@ module Html2Doc
|
|
9
9
|
encoding: "utf-8"))
|
10
10
|
|
11
11
|
def self.asciimath_to_mathml1(x)
|
12
|
-
AsciiMath.
|
12
|
+
AsciiMath::MathMLBuilder.new(:msword => true).append_expression(
|
13
|
+
AsciiMath.parse(HTMLEntities.new.decode(x)).ast).to_s.
|
13
14
|
gsub(/<math>/, "<math xmlns='http://www.w3.org/1998/Math/MathML'>")
|
14
15
|
end
|
15
16
|
|
@@ -31,6 +32,9 @@ module Html2Doc
|
|
31
32
|
next unless x.next_element && x.next_element != "mrow"
|
32
33
|
x.next_element.wrap("<mrow/>")
|
33
34
|
end
|
35
|
+
m.xpath(".//xmlns:mtext", docnamespaces).each do |x|
|
36
|
+
x.children = x.children.to_xml.gsub(/^\s/, " ").gsub(/\s$/, " ")
|
37
|
+
end
|
34
38
|
m.add_namespace(nil, "http://www.w3.org/1998/Math/MathML")
|
35
39
|
m
|
36
40
|
end
|
data/lib/html2doc/mime.rb
CHANGED
@@ -68,6 +68,7 @@ module Html2Doc
|
|
68
68
|
realSize = ImageSize.path(path).size
|
69
69
|
s = [i["width"].to_i, i["height"].to_i]
|
70
70
|
s = realSize if s[0].zero? && s[1].zero?
|
71
|
+
return [nil, nil] if realSize[0].nil? || realSize[1].nil?
|
71
72
|
s[1] = s[0] * realSize[1] / realSize[0] if s[1].zero? && !s[0].zero?
|
72
73
|
s[0] = s[1] * realSize[0] / realSize[1] if s[0].zero? && !s[1].zero?
|
73
74
|
s = [(s[0] * maxheight / s[1]).ceil, maxheight] if s[1] > maxheight
|
data/lib/html2doc/notes.rb
CHANGED
@@ -15,7 +15,7 @@ module Html2Doc
|
|
15
15
|
body = docxml.at("//body")
|
16
16
|
list = body.add_child("<div style='mso-element:footnote-list'/>")
|
17
17
|
footnotes.each_with_index do |f, i|
|
18
|
-
fn = list.first.add_child(footnote_container(i + 1))
|
18
|
+
fn = list.first.add_child(footnote_container(docxml, i + 1))
|
19
19
|
f.parent = fn.first
|
20
20
|
footnote_div_to_p(f)
|
21
21
|
end
|
@@ -33,13 +33,16 @@ module Html2Doc
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
FN = "<span class='MsoFootnoteReference'>"\
|
37
|
+
"<span style='mso-special-character:footnote'/></span>".freeze
|
38
|
+
|
39
|
+
def self.footnote_container(docxml, i)
|
40
|
+
ref = docxml&.at("//a[@href='#_ftn#{i}']")&.children&.to_xml(indent: 0).
|
41
|
+
gsub(/>\n</, "><") || FN
|
37
42
|
<<~DIV
|
38
43
|
<div style='mso-element:footnote' id='ftn#{i}'>
|
39
44
|
<a style='mso-footnote-id:ftn#{i}' href='#_ftn#{i}'
|
40
|
-
name='_ftnref#{i}' title='' id='_ftnref#{i}'
|
41
|
-
class='MsoFootnoteReference'><span
|
42
|
-
style='mso-special-character:footnote'></span></span></div>
|
45
|
+
name='_ftnref#{i}' title='' id='_ftnref#{i}'>#{ref.strip}</a></div>
|
43
46
|
DIV
|
44
47
|
end
|
45
48
|
|
@@ -49,8 +52,17 @@ module Html2Doc
|
|
49
52
|
note = docxml.at("//*[@name = '#{href}' or @id = '#{href}']")
|
50
53
|
return false if note.nil?
|
51
54
|
set_footnote_link_attrs(a, i)
|
52
|
-
a.
|
53
|
-
|
55
|
+
if a.at("./span[@class = 'MsoFootnoteReference']")
|
56
|
+
a.children.each do |c|
|
57
|
+
if c.name == "span" and c["class"] == "MsoFootnoteReference"
|
58
|
+
c.replace(FN)
|
59
|
+
else
|
60
|
+
c.wrap("<span class='MsoFootnoteReference'></span>")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
else
|
64
|
+
a.children = FN
|
65
|
+
end
|
54
66
|
fn << transform_footnote_text(note)
|
55
67
|
end
|
56
68
|
|
data/lib/html2doc/version.rb
CHANGED
data/spec/html2doc_spec.rb
CHANGED
@@ -372,11 +372,11 @@ RSpec.describe Html2Doc do
|
|
372
372
|
expect(guid_clean(File.read("test.doc", encoding: "utf-8"))).
|
373
373
|
to match_fuzzy(<<~OUTPUT)
|
374
374
|
#{WORD_HDR} #{DEFAULT_STYLESHEET} #{WORD_HDR_END}
|
375
|
-
#{word_body(
|
375
|
+
#{word_body(%{
|
376
376
|
<div><m:oMath>
|
377
|
-
|
377
|
+
<m:nary><m:naryPr><m:chr m:val="∑"></m:chr><m:limLoc m:val="undOvr"></m:limLoc><m:grow m:val="on"></m:grow><m:subHide m:val="off"></m:subHide><m:supHide m:val="off"></m:supHide></m:naryPr><m:sub><m:r><m:t>i=1</m:t></m:r></m:sub><m:sup><m:r><m:t>n</m:t></m:r></m:sup><m:e><m:sSup><m:e><m:r><m:t>i</m:t></m:r></m:e><m:sup><m:r><m:t>3</m:t></m:r></m:sup></m:sSup></m:e></m:nary><m:r><m:t>=</m:t></m:r><m:sSup><m:e><m:d><m:dPr><m:sepChr m:val=","></m:sepChr></m:dPr><m:e><m:f><m:fPr><m:type m:val="bar"></m:type></m:fPr><m:num><m:r><m:t>n</m:t></m:r><m:d><m:dPr><m:sepChr m:val=","></m:sepChr></m:dPr><m:e><m:r><m:t>n+1</m:t></m:r></m:e></m:d></m:num><m:den><m:r><m:t>2</m:t></m:r></m:den></m:f></m:e></m:d></m:e><m:sup><m:r><m:t>2</m:t></m:r></m:sup></m:sSup><m:r><m:rPr><m:nor></m:nor></m:rPr><m:t>"integer"</m:t></m:r><m:r><m:t>)</m:t></m:r>
|
378
378
|
</m:oMath>
|
379
|
-
</div>
|
379
|
+
</div>}, '<div style="mso-element:footnote-list"/>')}
|
380
380
|
#{WORD_FTR1}
|
381
381
|
OUTPUT
|
382
382
|
end
|
@@ -388,23 +388,38 @@ RSpec.describe Html2Doc do
|
|
388
388
|
#{WORD_HDR} #{DEFAULT_STYLESHEET} #{WORD_HDR_END}
|
389
389
|
#{word_body("
|
390
390
|
<div><m:oMath>
|
391
|
-
<m:r><m:rPr><m:nor></m:nor></m:rPr><m:t>
|
391
|
+
<m:r><m:t>text</m:t></m:r><m:r><m:rPr><m:nor></m:nor></m:rPr><m:t> integer </m:t></m:r><m:r><m:t>)</m:t></m:r>
|
392
392
|
</m:oMath>
|
393
393
|
</div>", '<div style="mso-element:footnote-list"/>')}
|
394
394
|
#{WORD_FTR1}
|
395
395
|
OUTPUT
|
396
396
|
end
|
397
397
|
|
398
|
+
it "processes spaces in MathML mtext" do
|
399
|
+
Html2Doc.process(html_input("<div><math xmlns='http://www.w3.org/1998/Math/MathML'>
|
400
|
+
<mrow><mi>H</mi><mtext> original </mtext><mi>J</mi></mrow>
|
401
|
+
</math></div>"), filename: "test", asciimathdelims: ["{{", "}}"])
|
402
|
+
expect(guid_clean(File.read("test.doc", encoding: "utf-8"))).
|
403
|
+
to match_fuzzy(<<~OUTPUT)
|
404
|
+
#{WORD_HDR} #{DEFAULT_STYLESHEET} #{WORD_HDR_END}
|
405
|
+
#{word_body('<div><m:oMath>
|
406
|
+
<m:r><m:t>H</m:t></m:r><m:r><m:rPr><m:nor></m:nor></m:rPr><m:t> original </m:t></m:r><m:r><m:t>J</m:t></m:r>
|
407
|
+
</m:oMath>
|
408
|
+
</div>', '<div style="mso-element:footnote-list"/>')}
|
409
|
+
#{WORD_FTR1}
|
410
|
+
OUTPUT
|
411
|
+
end
|
412
|
+
|
398
413
|
it "left-aligns AsciiMath" do
|
399
414
|
Html2Doc.process(html_input("<div style='text-align:left;'>{{sum_(i=1)^n i^3=((n(n+1))/2)^2}}</div>"), filename: "test", asciimathdelims: ["{{", "}}"])
|
400
415
|
expect(guid_clean(File.read("test.doc", encoding: "utf-8"))).
|
401
416
|
to match_fuzzy(<<~OUTPUT)
|
402
417
|
#{WORD_HDR} #{DEFAULT_STYLESHEET} #{WORD_HDR_END}
|
403
|
-
#{word_body(
|
404
|
-
<div style
|
405
|
-
|
418
|
+
#{word_body(%{
|
419
|
+
<div style="text-align:left;"><m:oMathPara><m:oMathParaPr><m:jc m:val="left"/></m:oMathParaPr><m:oMath>
|
420
|
+
<m:nary><m:naryPr><m:chr m:val="∑"></m:chr><m:limLoc m:val="undOvr"></m:limLoc><m:grow m:val="on"></m:grow><m:subHide m:val="off"></m:subHide><m:supHide m:val="off"></m:supHide></m:naryPr><m:sub><m:r><m:t>i=1</m:t></m:r></m:sub><m:sup><m:r><m:t>n</m:t></m:r></m:sup><m:e><m:sSup><m:e><m:r><m:t>i</m:t></m:r></m:e><m:sup><m:r><m:t>3</m:t></m:r></m:sup></m:sSup></m:e></m:nary><m:r><m:t>=</m:t></m:r><m:sSup><m:e><m:d><m:dPr><m:sepChr m:val=","></m:sepChr></m:dPr><m:e><m:f><m:fPr><m:type m:val="bar"></m:type></m:fPr><m:num><m:r><m:t>n</m:t></m:r><m:d><m:dPr><m:sepChr m:val=","></m:sepChr></m:dPr><m:e><m:r><m:t>n+1</m:t></m:r></m:e></m:d></m:num><m:den><m:r><m:t>2</m:t></m:r></m:den></m:f></m:e></m:d></m:e><m:sup><m:r><m:t>2</m:t></m:r></m:sup></m:sSup>
|
406
421
|
</m:oMath>
|
407
|
-
</m:oMathPara></div>
|
422
|
+
</m:oMathPara></div>}, '<div style="mso-element:footnote-list"/>')}
|
408
423
|
#{WORD_FTR1}
|
409
424
|
OUTPUT
|
410
425
|
end
|
@@ -414,11 +429,11 @@ RSpec.describe Html2Doc do
|
|
414
429
|
expect(guid_clean(File.read("test.doc", encoding: "utf-8"))).
|
415
430
|
to match_fuzzy(<<~OUTPUT)
|
416
431
|
#{WORD_HDR} #{DEFAULT_STYLESHEET} #{WORD_HDR_END}
|
417
|
-
#{word_body(
|
418
|
-
<div style
|
419
|
-
|
432
|
+
#{word_body(%{
|
433
|
+
<div style="text-align:right;"><m:oMathPara><m:oMathParaPr><m:jc m:val="right"/></m:oMathParaPr><m:oMath>
|
434
|
+
<m:nary><m:naryPr><m:chr m:val="∑"></m:chr><m:limLoc m:val="undOvr"></m:limLoc><m:grow m:val="on"></m:grow><m:subHide m:val="off"></m:subHide><m:supHide m:val="off"></m:supHide></m:naryPr><m:sub><m:r><m:t>i=1</m:t></m:r></m:sub><m:sup><m:r><m:t>n</m:t></m:r></m:sup><m:e><m:sSup><m:e><m:r><m:t>i</m:t></m:r></m:e><m:sup><m:r><m:t>3</m:t></m:r></m:sup></m:sSup></m:e></m:nary><m:r><m:t>=</m:t></m:r><m:sSup><m:e><m:d><m:dPr><m:sepChr m:val=","></m:sepChr></m:dPr><m:e><m:f><m:fPr><m:type m:val="bar"></m:type></m:fPr><m:num><m:r><m:t>n</m:t></m:r><m:d><m:dPr><m:sepChr m:val=","></m:sepChr></m:dPr><m:e><m:r><m:t>n+1</m:t></m:r></m:e></m:d></m:num><m:den><m:r><m:t>2</m:t></m:r></m:den></m:f></m:e></m:d></m:e><m:sup><m:r><m:t>2</m:t></m:r></m:sup></m:sSup>
|
420
435
|
</m:oMath>
|
421
|
-
</m:oMathPara></div>
|
436
|
+
</m:oMathPara></div>}, '<div style="mso-element:footnote-list"/>')}
|
422
437
|
#{WORD_FTR1}
|
423
438
|
OUTPUT
|
424
439
|
end
|
@@ -613,6 +628,26 @@ RSpec.describe Html2Doc do
|
|
613
628
|
OUTPUT
|
614
629
|
end
|
615
630
|
|
631
|
+
it "processes footnotes with text wrapping the footnote reference" do
|
632
|
+
simple_body = '<div>This is a very simple
|
633
|
+
document<a class="footnote" href="#a1">(<span class="MsoFootnoteReference">1</span>)</a> allegedly<a class="footnote" href="#a2">2</a></div>
|
634
|
+
<aside id="a1">Footnote</aside>
|
635
|
+
<aside id="a2">Other Footnote</aside>'
|
636
|
+
Html2Doc.process(html_input(simple_body), filename: "test")
|
637
|
+
expect(guid_clean(File.read("test.doc", encoding: "utf-8"))).
|
638
|
+
to match_fuzzy(<<~OUTPUT)
|
639
|
+
#{WORD_HDR} #{DEFAULT_STYLESHEET} #{WORD_HDR_END}
|
640
|
+
#{word_body('<div>This is a very simple
|
641
|
+
document<a class="footnote" href="#_ftn1" style="mso-footnote-id:ftn1" name="_ftnref1" title="" id="_ftnref1"><span class="MsoFootnoteReference">(</span><span class="MsoFootnoteReference"><span style="mso-special-character:footnote"></span></span><span class="MsoFootnoteReference">)</span></a> allegedly<a class="footnote" href="#_ftn2" style="mso-footnote-id:ftn2" name="_ftnref2" title="" id="_ftnref2"><span class="MsoFootnoteReference"><span style="mso-special-character:footnote"></span></span></a></div>',
|
642
|
+
'<div style="mso-element:footnote-list"><div style="mso-element:footnote" id="ftn1">
|
643
|
+
<p id="" class="MsoFootnoteText"><a style="mso-footnote-id:ftn1" href="#_ftn1" name="_ftnref1" title="" id="_ftnref1"><span class="MsoFootnoteReference">(</span><span class="MsoFootnoteReference"><span style="mso-special-character:footnote"></span></span><span class="MsoFootnoteReference">)</span></a>Footnote</p></div>
|
644
|
+
<div style="mso-element:footnote" id="ftn2">
|
645
|
+
<p id="" class="MsoFootnoteText"><a style="mso-footnote-id:ftn2" href="#_ftn2" name="_ftnref2" title="" id="_ftnref2"><span class="MsoFootnoteReference"><span style="mso-special-character:footnote"></span></span></a>Other Footnote</p></div>
|
646
|
+
</div>')}
|
647
|
+
#{WORD_FTR1}
|
648
|
+
OUTPUT
|
649
|
+
end
|
650
|
+
|
616
651
|
it "extracts paragraphs from footnotes" do
|
617
652
|
simple_body = '<div>This is a very simple
|
618
653
|
document<a class="footnote" href="#a1">1</a> allegedly<a class="footnote" href="#a2">2</a></div>
|
@@ -635,15 +670,16 @@ RSpec.describe Html2Doc do
|
|
635
670
|
|
636
671
|
it "labels lists with list styles" do
|
637
672
|
simple_body = <<~BODY
|
638
|
-
<div><ul>
|
639
|
-
<li><div><p><ol><li><ul><li><p><ol><li><ol><li>A</li><li><p>B</p><p>B2</p></li><li>C</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ul></div>
|
673
|
+
<div><ul id="0">
|
674
|
+
<li><div><p><ol id="1"><li><ul id="2"><li><p><ol id="3"><li><ol id="4"><li>A</li><li><p>B</p><p>B2</p></li><li>C</li></ol></li></ol></p></li></ul></li></ol></p></div></li><div><ul id="5"><li>C</li></ul></div>
|
640
675
|
BODY
|
641
676
|
Html2Doc.process(html_input(simple_body), filename: "test", liststyles: {ul: "l1", ol: "l2"})
|
642
677
|
expect(guid_clean(File.read("test.doc", encoding: "utf-8"))).
|
643
678
|
to match_fuzzy(<<~OUTPUT)
|
644
679
|
#{WORD_HDR} #{DEFAULT_STYLESHEET} #{WORD_HDR_END}
|
645
680
|
#{word_body('<div>
|
646
|
-
<p style="mso-list:l1 level1 lfo1;" class="MsoListParagraphCxSpFirst"><div><p class="MsoNormal"><p style="mso-list:l2 level2 lfo1;" class="MsoListParagraphCxSpFirst"><p style="mso-list:l2 level4 lfo1;" class="MsoListParagraphCxSpFirst"><p style="mso-list:l2 level5 lfo1;" class="MsoListParagraphCxSpFirst">A</p><p style="mso-list:l2 level5 lfo1;" class="MsoListParagraphCxSpMiddle">B<p class="MsoListParagraphCxSpMiddle">B2</p></p><p style="mso-list:l2 level5 lfo1;" class="MsoListParagraphCxSpLast">C</p></p></p></p></div></p></div>
|
681
|
+
<p style="mso-list:l1 level1 lfo1;" class="MsoListParagraphCxSpFirst"><div><p class="MsoNormal"><p style="mso-list:l2 level2 lfo1;" class="MsoListParagraphCxSpFirst"><p style="mso-list:l2 level4 lfo1;" class="MsoListParagraphCxSpFirst"><p style="mso-list:l2 level5 lfo1;" class="MsoListParagraphCxSpFirst">A</p><p style="mso-list:l2 level5 lfo1;" class="MsoListParagraphCxSpMiddle">B<p class="MsoListParagraphCxSpMiddle">B2</p></p><p style="mso-list:l2 level5 lfo1;" class="MsoListParagraphCxSpLast">C</p></p></p></p></div></p><div><p style="mso-list:l1 level1 lfo2;" class="MsoListParagraphCxSpFirst">C</p></div>
|
682
|
+
</div>',
|
647
683
|
'<div style="mso-element:footnote-list"/>')}
|
648
684
|
#{WORD_FTR1}
|
649
685
|
OUTPUT
|
@@ -653,8 +689,8 @@ RSpec.describe Html2Doc do
|
|
653
689
|
it "restarts numbering of lists with list styles" do
|
654
690
|
simple_body = <<~BODY
|
655
691
|
<div>
|
656
|
-
<ol><li><div><p><ol><li><ul><li><p><ol><li><ol><li>A</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ol>
|
657
|
-
<ol><li><div><p><ol><li><ul><li><p><ol><li><ol><li>A</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ol></div>
|
692
|
+
<ol id="1"><li><div><p><ol id="2"><li><ul id="3"><li><p><ol id="4"><li><ol id="5"><li>A</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ol>
|
693
|
+
<ol id="6"><li><div><p><ol id="7"><li><ul id="8"><li><p><ol id="9"><li><ol id="10"><li>A</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ol></div>
|
658
694
|
BODY
|
659
695
|
Html2Doc.process(html_input(simple_body), filename: "test", liststyles: {ul: "l1", ol: "l2"})
|
660
696
|
expect(guid_clean(File.read("test.doc", encoding: "utf-8"))).
|
@@ -670,12 +706,12 @@ RSpec.describe Html2Doc do
|
|
670
706
|
|
671
707
|
it "labels lists with multiple list styles" do
|
672
708
|
simple_body = <<~BODY
|
673
|
-
<div><ul class="steps">
|
674
|
-
<li><div><p><ol><li><ul><li><p><ol><li><ol><li>A</li><li><p>B</p><p>B2</p></li><li>C</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ul></div>
|
675
|
-
<div><ul>
|
676
|
-
<li><div><p><ol><li><ul><li><p><ol><li><ol><li>A</li><li><p>B</p><p>B2</p></li><li>C</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ul></div>
|
677
|
-
<div><ul class="other">
|
678
|
-
<li><div><p><ol><li><ul><li><p><ol><li><ol><li>A</li><li><p>B</p><p>B2</p></li><li>C</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ul></div>
|
709
|
+
<div><ul class="steps" id="0">
|
710
|
+
<li><div><p><ol id="1"><li><ul id="2"><li><p><ol id="3"><li><ol id="4"><li>A</li><li><p>B</p><p>B2</p></li><li>C</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ul></div>
|
711
|
+
<div><ul id="5">
|
712
|
+
<li><div><p><ol id="6"><li><ul id="7"><li><p><ol id="8"><li><ol id="9"><li>A</li><li><p>B</p><p>B2</p></li><li>C</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ul></div>
|
713
|
+
<div><ul class="other" id="10">
|
714
|
+
<li><div><p><ol id="11"><li><ul id="12"><li><p><ol id="13"><li><ol id="14"><li>A</li><li><p>B</p><p>B2</p></li><li>C</li></ol></li></ol></p></li></ul></li></ol></p></div></li></ul></div>
|
679
715
|
BODY
|
680
716
|
Html2Doc.process(html_input(simple_body), filename: "test", liststyles: {ul: "l1", ol: "l2", steps: "l3"})
|
681
717
|
expect(guid_clean(File.read("test.doc", encoding: "utf-8"))).
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: html2doc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: htmlentities
|
@@ -100,14 +100,14 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
103
|
+
version: 2.0.0
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
110
|
+
version: 2.0.0
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: byebug
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -309,7 +309,7 @@ licenses:
|
|
309
309
|
- CC-BY-SA-3.0
|
310
310
|
- BSD-2-Clause
|
311
311
|
metadata: {}
|
312
|
-
post_install_message:
|
312
|
+
post_install_message:
|
313
313
|
rdoc_options: []
|
314
314
|
require_paths:
|
315
315
|
- lib
|
@@ -324,9 +324,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
324
324
|
- !ruby/object:Gem::Version
|
325
325
|
version: '0'
|
326
326
|
requirements: []
|
327
|
-
|
328
|
-
|
329
|
-
signing_key:
|
327
|
+
rubygems_version: 3.0.3
|
328
|
+
signing_key:
|
330
329
|
specification_version: 4
|
331
330
|
summary: Convert HTML document to Microsoft Word document
|
332
331
|
test_files: []
|