Skip to content

Commit 9b81674

Browse files
authored
Merge pull request #27 from nschloe/dollar-replace
Dollar replace
2 parents 1c01fba + d4c9dc9 commit 9b81674

File tree

6 files changed

+66
-26
lines changed

6 files changed

+66
-26
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
steps:
3434
- uses: actions/setup-python@v2
3535
with:
36-
python-version: "3.x"
36+
python-version: ${{ matrix.python-version }}
3737
- uses: actions/checkout@v2
3838
- name: Test with tox
3939
run: |

README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,13 @@ Because of
3333
a+b = c
3434
\]
3535
(\textit{Pythogoras}),
36-
and $y = 2^n g$ with $n = 1,\dots,10$, we have $\frac{\Gamma}{2} = 8$.
36+
and \(y = 2^n g\) with \(n = 1,\dots,10\), we have \(\frac{\Gamma}{2} = 8.\)
3737
```
3838
You can use
3939
```
4040
blacktex -i in.tex
4141
```
42-
to modify a file in-place.
43-
42+
to modify a file in-place. See `blacktex -h` for all options.
4443

4544
### Installation
4645

blacktex/cli.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def main(argv=None):
88
parser = _get_parser()
99
args = parser.parse_args(argv)
1010

11-
out = blacktex.clean(args.infile.read())
11+
out = blacktex.clean(args.infile.read(), args.keep_comments, args.keep_dollar_math)
1212

1313
if args.in_place:
1414
with open(args.infile.name, "w") as f:
@@ -41,7 +41,14 @@ def _get_parser():
4141
)
4242

4343
parser.add_argument(
44-
"-k", "--keep-comments", action="store_true", help="keep comments"
44+
"-c", "--keep-comments", action="store_true", help="keep comments"
45+
)
46+
47+
parser.add_argument(
48+
"-d",
49+
"--keep-dollar-math",
50+
action="store_true",
51+
help="keep inline math with $...$",
4552
)
4653

4754
version_text = "blacktex {}, Python {}.{}.{}".format(

blacktex/main.py

+24-5
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,25 @@ def _replace_dollar_dollar(string):
6363
return _substitute_string_ranges(string, ranges, replacements)
6464

6565

66+
def _replace_dollar(string):
67+
"""Replace $...$ by \\(...\\). See <https://tex.stackexchange.com/q/510/13262>."""
68+
# (?<!\\\\) checks there is no backslash before (negative lookbehind)
69+
# (?:\\\\{2})* matches all even numbers of backslashes
70+
p = re.compile("(?<!\\\\)(?:\\\\{2})*\\$")
71+
locations = [m.end() for m in p.finditer(string)]
72+
assert len(locations) % 2 == 0
73+
74+
k = 0
75+
ranges = []
76+
replacements = []
77+
while k < len(locations):
78+
ranges.append((locations[k] - 1, locations[k + 1]))
79+
replacements.append("\\(" + string[locations[k] : locations[k + 1] - 1] + "\\)")
80+
k += 2
81+
82+
return _substitute_string_ranges(string, ranges, replacements)
83+
84+
6685
def _replace_obsolete_text_mods(string):
6786
string = string.replace("{\\bf ", "\\textbf{")
6887
string = string.replace("{\\it ", "\\textit{")
@@ -246,9 +265,7 @@ def _replace_def_by_newcommand(string):
246265
replacements = []
247266
for m in p.finditer(string):
248267
ranges.append((m.start(), m.end()))
249-
replacements.append(
250-
"\\newcommand{{{}}}".format(string[m.start() + 4 : m.end()])
251-
)
268+
replacements.append(f"\\newcommand{{{string[m.start() + 4 : m.end()]}}}")
252269

253270
return _substitute_string_ranges(string, ranges, replacements)
254271

@@ -314,17 +331,19 @@ def _si_percentage(string):
314331
return string
315332

316333

317-
def clean(string, keep_comments=False):
334+
def clean(string, keep_comments=False, keep_dollar=False):
318335
out = string
319336
out = _remove_trailing_whitespace(out)
320337
if not keep_comments:
321338
out = _remove_comments(out)
339+
out = _replace_punctuation_outside_math(out)
322340
out = _replace_dollar_dollar(out)
341+
if not keep_dollar:
342+
out = _replace_dollar(out)
323343
out = _replace_obsolete_text_mods(out)
324344
out = _remove_whitespace_around_brackets(out)
325345
out = _add_space_after_single_subsuperscript(out)
326346
out = _replace_dots(out)
327-
out = _replace_punctuation_outside_math(out)
328347
out = _remove_whitespace_before_punctuation(out)
329348
out = _add_nbsp_before_reference(out)
330349
out = _replace_double_nbsp(out)

setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = blacktex
3-
version = 0.3.6
3+
version = 0.4.0
44
author = Nico Schlömer
55
author_email = [email protected]
66
description = Cleans up your LaTeX files

test/test_blacktex.py

+29-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33
import blacktex
44

55

6+
def test_dollar():
7+
input_string = "a $a + b = c$ b"
8+
out = blacktex.clean(input_string)
9+
assert out == r"a \(a + b = c\) b"
10+
11+
input_string = r"a \$a + b = c\$ b"
12+
out = blacktex.clean(input_string)
13+
assert out == r"a \$a + b = c\$ b"
14+
15+
input_string = r"a \\$a + b = c\\$ b"
16+
out = blacktex.clean(input_string)
17+
assert out == "a \\\\\n\\(a + b = c\\\\\n\\) b"
18+
19+
620
def test_readme():
721
input_string = (
822
"Because of $$a+b=c$$ ({\\it Pythogoras}),\n"
@@ -17,7 +31,8 @@ def test_readme():
1731
"a+b = c\n"
1832
"\\]\n"
1933
"(\\textit{Pythogoras}),\n"
20-
"and $y = 2^n g$ with $n = 1,\\dots,10$, we have $\\frac{\\Gamma}{2} = 8$."
34+
"and \\(y = 2^n g\\) with \\(n = 1,\\dots,10\\), we have "
35+
"\\(\\frac{\\Gamma}{2} = 8\\)."
2136
)
2237

2338

@@ -114,17 +129,17 @@ def test_subsuperscript_space():
114129
out = blacktex.clean(input_string)
115130
assert out == "2^n g"
116131

117-
input_string = "$1/n^3$."
132+
input_string = "1/n^3"
118133
out = blacktex.clean(input_string)
119-
assert out == "$1/n^3$."
134+
assert out == "1/n^3"
120135

121-
input_string = "${n^3}$."
136+
input_string = "n^3"
122137
out = blacktex.clean(input_string)
123-
assert out == "${n^3}$."
138+
assert out == "n^3"
124139

125-
input_string = "$(n^3)$."
140+
input_string = "(n^3)"
126141
out = blacktex.clean(input_string)
127-
assert out == "$(n^3)$."
142+
assert out == "(n^3)"
128143

129144
input_string = "n^\\alpha"
130145
out = blacktex.clean(input_string)
@@ -154,7 +169,7 @@ def test_cdots():
154169

155170
def test_punctuation_outside_math():
156171
input_string = "$a+b.$"
157-
out = blacktex.clean(input_string)
172+
out = blacktex.clean(input_string, keep_dollar=True)
158173
assert out == "$a+b$."
159174

160175

@@ -178,14 +193,14 @@ def test_double_nbsp():
178193

179194
def test_over_frac():
180195
input_string = "Some ${2\\over 3^{4+x}}$ equation ${\\pi \\over4}$."
181-
out = blacktex.clean(input_string)
196+
out = blacktex.clean(input_string, keep_dollar=True)
182197
assert out == "Some $\\frac{2}{3^{4+x}}$ equation $\\frac{\\pi}{4}$."
183198

184199

185200
def test_over_frac_warn():
186201
input_string = "Some $2\\over 3^{4+x}$."
187202
with pytest.warns(UserWarning):
188-
out = blacktex.clean(input_string)
203+
out = blacktex.clean(input_string, keep_dollar=True)
189204
assert out == "Some $2\\over 3^{4+x}$."
190205

191206

@@ -197,7 +212,7 @@ def test_overline_warn():
197212

198213
def test_linebreak_after_double_backslash():
199214
input_string = "Some $2\\\\3 4\\\\\n6\\\\[2mm]7$."
200-
out = blacktex.clean(input_string)
215+
out = blacktex.clean(input_string, keep_dollar=True)
201216
assert out == "Some $2\\\\\n3 4\\\\\n6\\\\\n[2mm]7$."
202217

203218

@@ -209,13 +224,13 @@ def test_nbsp_space():
209224

210225
def test_keywords_without_backslash():
211226
input_string = "maximum and logarithm $max_x log(x)$"
212-
out = blacktex.clean(input_string)
227+
out = blacktex.clean(input_string, keep_dollar=True)
213228
assert out == "maximum and logarithm $\\max_x \\log(x)$"
214229

215230

216231
def test_curly_around_round_with_exponent():
217232
input_string = "$(a+b)^n \\left(a+b\\right)^{n+1}$"
218-
out = blacktex.clean(input_string)
233+
out = blacktex.clean(input_string, keep_dollar=True)
219234
assert out == "${(a+b)}^n {\\left(a+b\\right)}^{n+1}$"
220235

221236

@@ -338,4 +353,4 @@ def test_escaped_percentage_sign():
338353

339354

340355
if __name__ == "__main__":
341-
test_si_percentage()
356+
test_dollar()

0 commit comments

Comments
 (0)