pyDiffTools 0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pydifftools/__init__.py +11 -0
- pydifftools/check_numbers.py +70 -0
- pydifftools/command_line.py +747 -0
- pydifftools/command_registry.py +65 -0
- pydifftools/comment_functions.py +39 -0
- pydifftools/continuous.py +194 -0
- pydifftools/copy_files.py +75 -0
- pydifftools/diff-doc.js +193 -0
- pydifftools/doc_contents.py +147 -0
- pydifftools/flowchart/__init__.py +15 -0
- pydifftools/flowchart/dot_to_yaml.py +114 -0
- pydifftools/flowchart/graph.py +620 -0
- pydifftools/flowchart/watch_graph.py +168 -0
- pydifftools/html_comments.py +33 -0
- pydifftools/html_uncomments.py +524 -0
- pydifftools/match_spaces.py +235 -0
- pydifftools/notebook/__init__.py +0 -0
- pydifftools/notebook/fast_build.py +1502 -0
- pydifftools/notebook/tex_to_qmd.py +319 -0
- pydifftools/onewordify.py +149 -0
- pydifftools/onewordify_undo.py +54 -0
- pydifftools/outline.py +173 -0
- pydifftools/rearrange_tex.py +188 -0
- pydifftools/searchacro.py +80 -0
- pydifftools/separate_comments.py +73 -0
- pydifftools/split_conflict.py +213 -0
- pydifftools/unseparate_comments.py +69 -0
- pydifftools/update_check.py +31 -0
- pydifftools/wrap_sentences.py +501 -0
- pydifftools/xml2xlsx.vbs +33 -0
- pydifftools-0.1.8.dist-info/METADATA +146 -0
- pydifftools-0.1.8.dist-info/RECORD +36 -0
- pydifftools-0.1.8.dist-info/WHEEL +5 -0
- pydifftools-0.1.8.dist-info/entry_points.txt +2 -0
- pydifftools-0.1.8.dist-info/licenses/LICENSE.md +28 -0
- pydifftools-0.1.8.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import inspect
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class CommandRegistrationError(Exception):
|
|
6
|
+
"""Exception raised when attempting to register a duplicate subcommand."""
|
|
7
|
+
|
|
8
|
+
# Registry that stores all subcommands made available to the CLI dispatcher.
|
|
9
|
+
_COMMAND_SPECS = {}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def register_command(help_text, description=None, help=None):
|
|
13
|
+
"""Register a command handler for the CLI dispatcher."""
|
|
14
|
+
|
|
15
|
+
def decorator(func):
|
|
16
|
+
name = func.__name__.replace("_", "-")
|
|
17
|
+
if name in _COMMAND_SPECS:
|
|
18
|
+
raise CommandRegistrationError(
|
|
19
|
+
f"Command '{name}' already registered"
|
|
20
|
+
)
|
|
21
|
+
_COMMAND_SPECS[name] = {
|
|
22
|
+
"handler": func,
|
|
23
|
+
"help": help_text.strip(),
|
|
24
|
+
"description": (
|
|
25
|
+
description if description is not None else help_text
|
|
26
|
+
).strip(),
|
|
27
|
+
"arguments": [],
|
|
28
|
+
}
|
|
29
|
+
signature = inspect.signature(func)
|
|
30
|
+
argument_help = help if help is not None else {}
|
|
31
|
+
for parameter in signature.parameters.values():
|
|
32
|
+
if parameter.kind in [
|
|
33
|
+
inspect.Parameter.VAR_POSITIONAL,
|
|
34
|
+
inspect.Parameter.VAR_KEYWORD,
|
|
35
|
+
]:
|
|
36
|
+
continue
|
|
37
|
+
flags = []
|
|
38
|
+
kwargs = {}
|
|
39
|
+
if parameter.default is inspect._empty:
|
|
40
|
+
flags.append(parameter.name)
|
|
41
|
+
if parameter.name == "arguments":
|
|
42
|
+
# Most commands accept a raw list of trailing arguments.
|
|
43
|
+
kwargs["nargs"] = argparse.REMAINDER
|
|
44
|
+
kwargs["help"] = argparse.SUPPRESS
|
|
45
|
+
else:
|
|
46
|
+
# Single-letter keywords use a short flag; everything else uses
|
|
47
|
+
# the long two-dash style expected by the CLI.
|
|
48
|
+
dash_prefix = "-" if len(parameter.name) == 1 else "--"
|
|
49
|
+
flags.append(dash_prefix + parameter.name.replace("_", "-"))
|
|
50
|
+
kwargs["default"] = parameter.default
|
|
51
|
+
if isinstance(parameter.default, bool):
|
|
52
|
+
# Boolean flags toggle on or off without needing a value.
|
|
53
|
+
kwargs["action"] = (
|
|
54
|
+
"store_false" if parameter.default else "store_true"
|
|
55
|
+
)
|
|
56
|
+
elif parameter.default is not None:
|
|
57
|
+
kwargs["type"] = type(parameter.default)
|
|
58
|
+
if parameter.name in argument_help:
|
|
59
|
+
kwargs["help"] = argument_help[parameter.name].strip()
|
|
60
|
+
_COMMAND_SPECS[name]["arguments"].append(
|
|
61
|
+
{"flags": flags, "kwargs": kwargs}
|
|
62
|
+
)
|
|
63
|
+
return func
|
|
64
|
+
|
|
65
|
+
return decorator
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
def comment_definition(commandname, name, comment_text):
|
|
2
|
+
return r"\newcommand{\%s}{%s}" % (commandname, comment_text) + "\n"
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def generate_alphabetnumber(x):
|
|
6
|
+
if x < 26:
|
|
7
|
+
return chr(ord("a") + x)
|
|
8
|
+
else:
|
|
9
|
+
higher_places = x // 26
|
|
10
|
+
return generate_alphabetnumber(
|
|
11
|
+
higher_places - 1
|
|
12
|
+
) + generate_alphabetnumber(x - higher_places * 26)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def matchingbrackets(content, startpoint, bracket_type):
|
|
16
|
+
if bracket_type == "(":
|
|
17
|
+
opening = "("
|
|
18
|
+
closing = ")"
|
|
19
|
+
elif bracket_type == "[":
|
|
20
|
+
opening = "["
|
|
21
|
+
closing = "]"
|
|
22
|
+
elif bracket_type == "{":
|
|
23
|
+
opening = "{"
|
|
24
|
+
closing = "}"
|
|
25
|
+
else:
|
|
26
|
+
raise ValueError("I didn't understand the type of bracket!")
|
|
27
|
+
first = (
|
|
28
|
+
False # of course, don't want to break until we've found at least one
|
|
29
|
+
)
|
|
30
|
+
level = 0
|
|
31
|
+
for j in range(startpoint, len(content)):
|
|
32
|
+
if content[j] == opening:
|
|
33
|
+
if level == 0:
|
|
34
|
+
first = j
|
|
35
|
+
level += 1
|
|
36
|
+
if content[j] == closing:
|
|
37
|
+
level -= 1
|
|
38
|
+
if level == 0 and first:
|
|
39
|
+
return first, j
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Continuous Pandoc build utility that requires geckodriver."""
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
import subprocess
|
|
5
|
+
import sys
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
import shutil
|
|
9
|
+
from watchdog.events import FileSystemEventHandler
|
|
10
|
+
from watchdog.observers import Observer
|
|
11
|
+
from .command_registry import register_command
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def run_pandoc(filename, html_file):
|
|
15
|
+
# Pandoc and pandoc-crossref must be installed for HTML rendering.
|
|
16
|
+
if shutil.which("pandoc") is None:
|
|
17
|
+
raise RuntimeError(
|
|
18
|
+
"Pandoc must be installed to render HTML output. Install pandoc"
|
|
19
|
+
" so the 'pandoc' executable is available on your PATH."
|
|
20
|
+
)
|
|
21
|
+
if shutil.which("pandoc-crossref") is None:
|
|
22
|
+
raise RuntimeError(
|
|
23
|
+
"Pandoc-crossref must be installed to render HTML output. Install"
|
|
24
|
+
" pandoc-crossref so the 'pandoc-crossref' executable is available"
|
|
25
|
+
" on your PATH."
|
|
26
|
+
)
|
|
27
|
+
if os.path.exists("MathJax-3.1.2"):
|
|
28
|
+
has_local_jax = True
|
|
29
|
+
else:
|
|
30
|
+
has_local_jax = False
|
|
31
|
+
print("you don't have a local copy of mathjax. You could get it with")
|
|
32
|
+
print(
|
|
33
|
+
"wget https://github.com/mathjax/MathJax/archive/"
|
|
34
|
+
+ "refs/tags/3.1.2.zip"
|
|
35
|
+
)
|
|
36
|
+
print("and then unzip")
|
|
37
|
+
current_dir = os.getcwd()
|
|
38
|
+
localfiles = {}
|
|
39
|
+
for k in ["csl", "bib"]:
|
|
40
|
+
localfiles[k] = [
|
|
41
|
+
f for f in os.listdir(current_dir) if f.endswith("." + k)
|
|
42
|
+
]
|
|
43
|
+
if len(localfiles[k]) == 1:
|
|
44
|
+
localfiles[k] = localfiles[k][0]
|
|
45
|
+
else:
|
|
46
|
+
raise ValueError(
|
|
47
|
+
f"You have more than one (or no) {k} file in this directory!"
|
|
48
|
+
" Get rid of all but one! of "
|
|
49
|
+
+ "and".join(localfiles[k])
|
|
50
|
+
)
|
|
51
|
+
command = [
|
|
52
|
+
"pandoc",
|
|
53
|
+
"--bibliography",
|
|
54
|
+
localfiles["bib"],
|
|
55
|
+
f"--csl={localfiles['csl']}",
|
|
56
|
+
"--filter",
|
|
57
|
+
"pandoc-crossref",
|
|
58
|
+
"--citeproc",
|
|
59
|
+
"--mathjax",
|
|
60
|
+
"--number-sections",
|
|
61
|
+
"--toc",
|
|
62
|
+
"-s",
|
|
63
|
+
"-o",
|
|
64
|
+
html_file,
|
|
65
|
+
filename,
|
|
66
|
+
]
|
|
67
|
+
# command = ['pandoc', '-s', '--mathjax', '-o', html_file, filename]
|
|
68
|
+
print("running:", " ".join(command))
|
|
69
|
+
subprocess.run(
|
|
70
|
+
command,
|
|
71
|
+
)
|
|
72
|
+
print("running:\n", command)
|
|
73
|
+
if has_local_jax:
|
|
74
|
+
# {{{ for slow internet connection, remove remote files
|
|
75
|
+
with open(html_file, encoding="utf-8") as fp:
|
|
76
|
+
text = fp.read()
|
|
77
|
+
patterns = [
|
|
78
|
+
r"<script.{0,20}?cdn\.jsdeli.{0,20}?mathjax.{0,60}?script>",
|
|
79
|
+
r"<script.{0,20}?https...polyfill.{0,60}?script>",
|
|
80
|
+
]
|
|
81
|
+
for j in patterns:
|
|
82
|
+
text = re.sub(j, "", text, flags=re.DOTALL)
|
|
83
|
+
with open(html_file, "w", encoding="utf-8") as fp:
|
|
84
|
+
fp.write(text)
|
|
85
|
+
# }}}
|
|
86
|
+
with open(html_file, encoding="utf-8") as fp:
|
|
87
|
+
text = fp.read()
|
|
88
|
+
style_block = (
|
|
89
|
+
'\n<style id="pydifftools-hide-low-headers">\n'
|
|
90
|
+
"h5, h6 { display: none; }\n"
|
|
91
|
+
"</style>\n"
|
|
92
|
+
)
|
|
93
|
+
if style_block not in text:
|
|
94
|
+
# hide organizational headers while keeping higher levels visible
|
|
95
|
+
if "</head>" in text:
|
|
96
|
+
text = text.replace("</head>", style_block + "</head>", 1)
|
|
97
|
+
else:
|
|
98
|
+
text = style_block + text
|
|
99
|
+
with open(html_file, "w", encoding="utf-8") as fp:
|
|
100
|
+
fp.write(text)
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class Handler(FileSystemEventHandler):
|
|
105
|
+
def __init__(self, filename, observer):
|
|
106
|
+
self.observer = observer
|
|
107
|
+
self.filename = filename
|
|
108
|
+
self.html_file = filename.rsplit(".", 1)[0] + ".html"
|
|
109
|
+
self.init_firefox()
|
|
110
|
+
|
|
111
|
+
def init_firefox(self):
|
|
112
|
+
# apparently, selenium breaks stdin/out for tests, so it must be
|
|
113
|
+
# imported here
|
|
114
|
+
from selenium import webdriver
|
|
115
|
+
|
|
116
|
+
self.firefox = webdriver.Chrome()
|
|
117
|
+
run_pandoc(self.filename, self.html_file)
|
|
118
|
+
if not os.path.exists(self.html_file):
|
|
119
|
+
print("html doesn't exist")
|
|
120
|
+
self.append_autorefresh()
|
|
121
|
+
self.firefox.get("file://" + os.path.abspath(self.html_file))
|
|
122
|
+
|
|
123
|
+
def on_modified(self, event):
|
|
124
|
+
from selenium.common.exceptions import WebDriverException
|
|
125
|
+
|
|
126
|
+
if os.path.normpath(
|
|
127
|
+
os.path.abspath(event.src_path)
|
|
128
|
+
) == os.path.normpath(os.path.abspath(self.filename)):
|
|
129
|
+
run_pandoc(self.filename, self.html_file)
|
|
130
|
+
self.append_autorefresh()
|
|
131
|
+
try:
|
|
132
|
+
self.firefox.refresh()
|
|
133
|
+
except WebDriverException:
|
|
134
|
+
print(
|
|
135
|
+
"I'm quitting!! You probably suspended the computer, which"
|
|
136
|
+
" seems to freak selenium out. Just restart"
|
|
137
|
+
)
|
|
138
|
+
self.firefox.quit()
|
|
139
|
+
self.init_firefox()
|
|
140
|
+
|
|
141
|
+
def append_autorefresh(self):
|
|
142
|
+
with open(self.html_file, "r", encoding="utf-8") as fp:
|
|
143
|
+
all_data = fp.read()
|
|
144
|
+
all_data = all_data.replace(
|
|
145
|
+
"</head>",
|
|
146
|
+
"""
|
|
147
|
+
<script id="MathJax-script" async src="MathJax-3.1.2/es5/tex-mml-chtml.js"\
|
|
148
|
+
></script>
|
|
149
|
+
<script>
|
|
150
|
+
// When the page is about to be unloaded, save the current scroll\
|
|
151
|
+
position
|
|
152
|
+
window.addEventListener('beforeunload', function() {
|
|
153
|
+
sessionStorage.setItem('scrollPosition', window.scrollY);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// When the page has loaded, scroll to the previous scroll position
|
|
157
|
+
window.addEventListener('load', function() {
|
|
158
|
+
var scrollPosition = sessionStorage.getItem('scrollPosition');
|
|
159
|
+
if (scrollPosition) {
|
|
160
|
+
window.scrollTo(0, scrollPosition);
|
|
161
|
+
sessionStorage.removeItem('scrollPosition');
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
</script>
|
|
165
|
+
</head>
|
|
166
|
+
""",
|
|
167
|
+
)
|
|
168
|
+
with open(self.html_file, "w", encoding="utf-8") as fp:
|
|
169
|
+
fp.write(all_data)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
@register_command(
|
|
173
|
+
"continuous pandoc build. Like latexmk, but for markdown!",
|
|
174
|
+
help={"filename": "Markdown or TeX file to watch for changes"},
|
|
175
|
+
)
|
|
176
|
+
def cpb(filename):
|
|
177
|
+
observer = Observer()
|
|
178
|
+
event_handler = Handler(filename, observer)
|
|
179
|
+
observer.schedule(event_handler, path=".", recursive=False)
|
|
180
|
+
observer.start()
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
while True:
|
|
184
|
+
time.sleep(1)
|
|
185
|
+
except KeyboardInterrupt:
|
|
186
|
+
observer.stop()
|
|
187
|
+
|
|
188
|
+
observer.join()
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
if __name__ == "__main__":
|
|
192
|
+
filename = sys.argv[1]
|
|
193
|
+
cpb(filename)
|
|
194
|
+
# Open the HTML file in the default web browser
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# from https://tex.stackexchange.com/questions/24542/create-list-of-all-external-files-used-by-master-latex-document
|
|
2
|
+
"""Copy figures used by document."""
|
|
3
|
+
import os
|
|
4
|
+
import shutil
|
|
5
|
+
from pathlib import Path, PurePosixPath
|
|
6
|
+
import subprocess
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def copy_image_files(ROOT_TEX, project_name, TARGET_DIR, include_suppinfo):
|
|
11
|
+
all_files = []
|
|
12
|
+
with open(ROOT_TEX + ".tex", "r") as fp:
|
|
13
|
+
alltext = fp.read()
|
|
14
|
+
if r"\RequirePackage{snapshot}" not in alltext:
|
|
15
|
+
raise RuntimeError(
|
|
16
|
+
"You haven't called \\RequirePackage{snapshot} in the root tex file. I can't do my thing without that!"
|
|
17
|
+
)
|
|
18
|
+
with open(ROOT_TEX + ".dep", "r") as f:
|
|
19
|
+
for line in f:
|
|
20
|
+
if "*{file}" in line:
|
|
21
|
+
value = line.split("{")[2].split("}")
|
|
22
|
+
source = value[0]
|
|
23
|
+
_, e = os.path.splitext(source)
|
|
24
|
+
if len(e) == 0 and os.path.exists(source + ".tex"):
|
|
25
|
+
all_files.append(source + ".tex")
|
|
26
|
+
print("found", source + ".tex")
|
|
27
|
+
elif os.path.exists(source):
|
|
28
|
+
all_files.append(source)
|
|
29
|
+
elif "*{package}" in line:
|
|
30
|
+
value = line.split("{")[2].split("}")
|
|
31
|
+
source = value[0]
|
|
32
|
+
_, e = os.path.splitext(source)
|
|
33
|
+
if len(e) == 0 and os.path.exists(source + ".sty"):
|
|
34
|
+
all_files.append(source + ".sty")
|
|
35
|
+
print("found", source + ".sty")
|
|
36
|
+
elif os.path.exists(source):
|
|
37
|
+
all_files.append(source)
|
|
38
|
+
else:
|
|
39
|
+
continue
|
|
40
|
+
os.makedirs(TARGET_DIR, exist_ok=True)
|
|
41
|
+
if include_suppinfo:
|
|
42
|
+
all_files.append("suppinfo.pdf")
|
|
43
|
+
all_files.append("suppinfo.aux")
|
|
44
|
+
for source in all_files:
|
|
45
|
+
d, f = os.path.split(source)
|
|
46
|
+
b, _ = os.path.splitext(source)
|
|
47
|
+
if b == ROOT_TEX:
|
|
48
|
+
f = f.replace(ROOT_TEX, "ms")
|
|
49
|
+
newpath = TARGET_DIR / d / f
|
|
50
|
+
print("copying", source, PurePosixPath(newpath))
|
|
51
|
+
if len(d) > 0:
|
|
52
|
+
print("going to make", newpath.parents[0])
|
|
53
|
+
os.makedirs(newpath.parents[0], exist_ok=True)
|
|
54
|
+
shutil.copy(source, PurePosixPath(newpath))
|
|
55
|
+
shutil.copy(ROOT_TEX + ".tex", os.path.join(TARGET_DIR, "ms.tex"))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
if __name__ == "__main__":
|
|
59
|
+
copy_image_files()
|
|
60
|
+
os.chdir(Path.cwd().parent)
|
|
61
|
+
output_filename = f"{project_name}_forarxiv.tgz"
|
|
62
|
+
# create tar process
|
|
63
|
+
tar = subprocess.Popen(
|
|
64
|
+
["tar", "cf", "-", TARGET_DIR.name], stdout=subprocess.PIPE
|
|
65
|
+
)
|
|
66
|
+
# create gzip process, using tar's stdout as its stdin
|
|
67
|
+
gzip = subprocess.Popen(
|
|
68
|
+
["gzip", "-9"], stdin=tar.stdout, stdout=subprocess.PIPE
|
|
69
|
+
)
|
|
70
|
+
# close tar's stdout so it doesn't hang around waiting for input
|
|
71
|
+
tar.stdout.close()
|
|
72
|
+
# write gzip's stdout to a file
|
|
73
|
+
with open(output_filename, "wb") as fp:
|
|
74
|
+
shutil.copyfileobj(gzip.stdout, fp)
|
|
75
|
+
gzip.stdout.close()
|
pydifftools/diff-doc.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
//
|
|
2
|
+
// TortoiseSVN Diff script for Word Doc files
|
|
3
|
+
//
|
|
4
|
+
// Copyright (C) 2004-2008 the TortoiseSVN team
|
|
5
|
+
// This file is distributed under the same license as TortoiseSVN
|
|
6
|
+
//
|
|
7
|
+
// Last commit by:
|
|
8
|
+
// $Author$
|
|
9
|
+
// $Date$
|
|
10
|
+
// $Rev$
|
|
11
|
+
//
|
|
12
|
+
// Authors:
|
|
13
|
+
// Jared Silva, 2008
|
|
14
|
+
// Davide Orlandi and Hans-Emil Skogh, 2005
|
|
15
|
+
//
|
|
16
|
+
|
|
17
|
+
var objArgs,num,sBaseDoc,sNewDoc,sTempDoc,objScript,word,destination;
|
|
18
|
+
// Microsoft Office versions for Microsoft Windows OS
|
|
19
|
+
var vOffice2000 = 9;
|
|
20
|
+
var vOffice2002 = 10;
|
|
21
|
+
var vOffice2003 = 11;
|
|
22
|
+
var vOffice2007 = 12;
|
|
23
|
+
// WdCompareTarget
|
|
24
|
+
var wdCompareTargetSelected = 0;
|
|
25
|
+
var wdCompareTargetCurrent = 1;
|
|
26
|
+
var wdCompareTargetNew = 2;
|
|
27
|
+
// WdViewType
|
|
28
|
+
var wdMasterView = 5;
|
|
29
|
+
var wdNormalView = 1;
|
|
30
|
+
var wdOutlineView = 2;
|
|
31
|
+
// WdSaveOptions
|
|
32
|
+
var wdDoNotSaveChanges = 0;
|
|
33
|
+
var wdPromptToSaveChanges = -2;
|
|
34
|
+
var wdSaveChanges = -1;
|
|
35
|
+
|
|
36
|
+
objArgs = WScript.Arguments;
|
|
37
|
+
num = objArgs.length;
|
|
38
|
+
if (num < 2)
|
|
39
|
+
{
|
|
40
|
+
WScript.Echo("Usage: [CScript | WScript] diff-doc.js base.doc new.doc");
|
|
41
|
+
WScript.Quit(1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
sBaseDoc = objArgs(0);
|
|
45
|
+
sNewDoc = objArgs(1);
|
|
46
|
+
|
|
47
|
+
objScript = new ActiveXObject("Scripting.FileSystemObject");
|
|
48
|
+
if ( ! objScript.FileExists(sBaseDoc))
|
|
49
|
+
{
|
|
50
|
+
WScript.Echo("File " + sBaseDoc + " does not exist. Cannot compare the documents.");
|
|
51
|
+
WScript.Quit(1);
|
|
52
|
+
}
|
|
53
|
+
if ( ! objScript.FileExists(sNewDoc))
|
|
54
|
+
{
|
|
55
|
+
WScript.Echo("File " + sNewDoc + " does not exist. Cannot compare the documents.");
|
|
56
|
+
WScript.Quit(1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try
|
|
60
|
+
{
|
|
61
|
+
word = WScript.CreateObject("Word.Application");
|
|
62
|
+
}
|
|
63
|
+
catch(e)
|
|
64
|
+
{
|
|
65
|
+
// before giving up, try with OpenOffice
|
|
66
|
+
try
|
|
67
|
+
{
|
|
68
|
+
var OO;
|
|
69
|
+
OO = WScript.CreateObject("com.sun.star.ServiceManager");
|
|
70
|
+
}
|
|
71
|
+
catch(e)
|
|
72
|
+
{
|
|
73
|
+
WScript.Echo("You must have Microsoft Word or OpenOffice installed to perform this operation.");
|
|
74
|
+
WScript.Quit(1);
|
|
75
|
+
}
|
|
76
|
+
// yes, OO is installed - do the diff with that one instead
|
|
77
|
+
var objFile = objScript.GetFile(sNewDoc);
|
|
78
|
+
if ((objFile.Attributes & 1)==1)
|
|
79
|
+
{
|
|
80
|
+
// reset the readonly attribute
|
|
81
|
+
objFile.Attributes = objFile.Attributes & (~1);
|
|
82
|
+
}
|
|
83
|
+
//Create the DesktopSet
|
|
84
|
+
var objDesktop = OO.createInstance("com.sun.star.frame.Desktop");
|
|
85
|
+
var objUriTranslator = OO.createInstance("com.sun.star.uri.ExternalUriReferenceTranslator");
|
|
86
|
+
//Adjust the paths for OO
|
|
87
|
+
sBaseDoc = sBaseDoc.replace(/\\/g, "/");
|
|
88
|
+
sBaseDoc = sBaseDoc.replace(/:/g, "|");
|
|
89
|
+
sBaseDoc = sBaseDoc.replace(/ /g, "%20");
|
|
90
|
+
sBaseDoc="file:///" + sBaseDoc;
|
|
91
|
+
sBaseDoc=objUriTranslator.translateToInternal(sBaseDoc);
|
|
92
|
+
sNewDoc = sNewDoc.replace(/\\/g, "/");
|
|
93
|
+
sNewDoc = sNewDoc.replace(/:/g, "|");
|
|
94
|
+
sNewDoc = sNewDoc.replace(/ /g, "%20");
|
|
95
|
+
sNewDoc="file:///" + sNewDoc;
|
|
96
|
+
sNewDoc=objUriTranslator.translateToInternal(sNewDoc);
|
|
97
|
+
|
|
98
|
+
//Open the %base document
|
|
99
|
+
var oPropertyValue = new Array();
|
|
100
|
+
oPropertyValue[0] = OO.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
|
|
101
|
+
oPropertyValue[0].Name = "ShowTrackedChanges";
|
|
102
|
+
oPropertyValue[0].Value = true;
|
|
103
|
+
var objDocument=objDesktop.loadComponentFromURL(sNewDoc,"_blank", 0, oPropertyValue);
|
|
104
|
+
|
|
105
|
+
//Set the frame
|
|
106
|
+
var Frame = objDesktop.getCurrentFrame();
|
|
107
|
+
|
|
108
|
+
var dispatcher=OO.CreateInstance("com.sun.star.frame.DispatchHelper");
|
|
109
|
+
|
|
110
|
+
//Execute the comparison
|
|
111
|
+
dispatcher.executeDispatch(Frame, ".uno:ShowTrackedChanges", "", 0, oPropertyValue);
|
|
112
|
+
oPropertyValue[0].Name = "URL";
|
|
113
|
+
oPropertyValue[0].Value = sBaseDoc;
|
|
114
|
+
dispatcher.executeDispatch(Frame, ".uno:CompareDocuments", "", 0, oPropertyValue);
|
|
115
|
+
WScript.Quit(0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (parseInt(word.Version) >= vOffice2007)
|
|
119
|
+
{
|
|
120
|
+
sTempDoc = sNewDoc;
|
|
121
|
+
sNewDoc = sBaseDoc;
|
|
122
|
+
sBaseDoc = sTempDoc;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
objScript = null;
|
|
126
|
+
|
|
127
|
+
word.visible = true;
|
|
128
|
+
|
|
129
|
+
// Open the new document
|
|
130
|
+
try
|
|
131
|
+
{
|
|
132
|
+
destination = word.Documents.Open(sNewDoc, true, true);
|
|
133
|
+
}
|
|
134
|
+
catch(e)
|
|
135
|
+
{
|
|
136
|
+
WScript.Echo("Error opening " + sNewDoc);
|
|
137
|
+
// Quit
|
|
138
|
+
WScript.Quit(1);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// If the Type property returns either wdOutlineView or wdMasterView and the Count property returns zero, the current document is an outline.
|
|
142
|
+
if (((destination.ActiveWindow.View.Type == wdOutlineView) || (destination.ActiveWindow.View.Type == wdMasterView)) && (destination.Subdocuments.Count == 0))
|
|
143
|
+
{
|
|
144
|
+
// Change the Type property of the current document to normal
|
|
145
|
+
destination.ActiveWindow.View.Type = wdNormalView;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Compare to the base document
|
|
149
|
+
if (parseInt(word.Version) <= vOffice2000)
|
|
150
|
+
{
|
|
151
|
+
// Compare for Office 2000 and earlier
|
|
152
|
+
try
|
|
153
|
+
{
|
|
154
|
+
destination.Compare(sBaseDoc);
|
|
155
|
+
}
|
|
156
|
+
catch(e)
|
|
157
|
+
{
|
|
158
|
+
WScript.Echo("Error comparing " + sBaseDoc + " and " + sNewDoc);
|
|
159
|
+
// Quit
|
|
160
|
+
WScript.Quit(1);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else
|
|
164
|
+
{
|
|
165
|
+
// Compare for Office XP (2002) and later
|
|
166
|
+
try
|
|
167
|
+
{
|
|
168
|
+
destination.Compare(sBaseDoc, "Comparison", wdCompareTargetNew, true, true);
|
|
169
|
+
}
|
|
170
|
+
catch(e)
|
|
171
|
+
{
|
|
172
|
+
WScript.Echo("Error comparing " + sBaseDoc + " and " + sNewDoc);
|
|
173
|
+
// Close the first document and quit
|
|
174
|
+
destination.Close(wdDoNotSaveChanges);
|
|
175
|
+
WScript.Quit(1);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Show the comparison result
|
|
180
|
+
if (parseInt(word.Version) < vOffice2007)
|
|
181
|
+
{
|
|
182
|
+
word.ActiveDocument.Windows(1).Visible = 1;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Mark the comparison document as saved to prevent the annoying
|
|
186
|
+
// "Save as" dialog from appearing.
|
|
187
|
+
word.ActiveDocument.Saved = 1;
|
|
188
|
+
|
|
189
|
+
// Close the first document
|
|
190
|
+
if (parseInt(word.Version) >= vOffice2002)
|
|
191
|
+
{
|
|
192
|
+
destination.Close(wdDoNotSaveChanges);
|
|
193
|
+
}
|