Skip to content

Commit

Permalink
Merge 440f6a5 into 5b67c7a
Browse files Browse the repository at this point in the history
  • Loading branch information
colinmford committed Aug 6, 2020
2 parents 5b67c7a + 440f6a5 commit 73ffd53
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 2 deletions.
63 changes: 61 additions & 2 deletions src/ufonormalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import time
import os
import re
import shutil
from xml.etree import cElementTree as ET
import plistlib
Expand Down Expand Up @@ -158,11 +159,9 @@ def tounicode(s, encoding='ascii', errors='strict'):
class UFONormalizerError(Exception):
pass


DEFAULT_FLOAT_PRECISION = 10
FLOAT_FORMAT = "%%.%df" % DEFAULT_FLOAT_PRECISION


def normalizeUFO(ufoPath, outputPath=None, onlyModified=True,
floatPrecision=DEFAULT_FLOAT_PRECISION, writeModTimes=True):
global FLOAT_FORMAT
Expand Down Expand Up @@ -1178,6 +1177,8 @@ def data(self, text):
self.raw(line)

def text(self, text):
text = text.strip("\n")
text = dedent_tabs(text)
text = text.strip()
text = xmlEscapeText(text)
paragraphs = []
Expand Down Expand Up @@ -1358,6 +1359,64 @@ def xmlConvertFloat(value):
def xmlConvertInt(value):
return str(value)


# ---------------
# Text Operations
# ---------------

WHITESPACE_ONLY_RE = re.compile('^[\s\t]+$', re.MULTILINE)
LEADING_WHITESPACE_RE = re.compile('(^(?:\s{4}|\t)*)(?:[^\t\n])', re.MULTILINE)

def dedent_tabs(text):
"""
Based on `textwrap.dedent`, but modified to only work on tabs and 4-space indents
Remove any common leading tabs from every line in `text`.
This can be used to make triple-quoted strings line up with the left
edge of the display, while still presenting them in the source code
in indented form.
Entirely blank lines are normalized to a newline character.
"""
# Look for the longest leading string of spaces and tabs common to
# all lines.
margin = None
text = WHITESPACE_ONLY_RE.sub('', text)
indents = LEADING_WHITESPACE_RE.findall(text)
for indent in indents:
if margin is None:
margin = indent

# Current line more deeply indented than previous winner:
# no change (previous winner is still on top).
elif indent.startswith(margin):
pass

# Current line consistent with and no deeper than previous winner:
# it's the new winner.
elif margin.startswith(indent):
margin = indent

# Find the largest common whitespace between current line and previous
# winner.
else:
for i, (x, y) in enumerate(zip(margin, indent)):
if x != y:
margin = margin[:i]
break

# sanity check (testing/debugging only)
if 0 and margin:
for line in text.split("\n"):
assert not line or line.startswith(margin), \
"line = %r, margin = %r" % (line, margin)

if margin:
text = re.sub(r'(?m)^' + margin, '', text)
return text



# ---------------
# Path Operations
# ---------------
Expand Down
47 changes: 47 additions & 0 deletions tests/test_ufonormalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,53 @@ def test_normalizeGLIF_note_defined(self):
writer.getText(),
"<note>\n\tLine1\n\t\n\t Line3\n</note>")

# Normalizer should not indent Line2 and Line3 more than already indented
element = ET.fromstring(
"<note>\n\tLine1\n\tLine2\n\tLine3\n</note>")
writer = XMLWriter(declaration=None)
_normalizeGlifNote(element, writer)
self.assertEqual(
writer.getText(),
"<note>\n\tLine1\n\tLine2\n\tLine3\n</note>")

# Normalizer should keep the extra tab in line 2
element = ET.fromstring(
"<note>\n\tLine1\n\t\tLine2\n\tLine3\n</note>")
writer = XMLWriter(declaration=None)
_normalizeGlifNote(element, writer)
self.assertEqual(
writer.getText(),
"<note>\n\tLine1\n\t\tLine2\n\tLine3\n</note>")

# Normalizer should keep the extra spaces on line 2
element = ET.fromstring(
"<note>\n\tLine1\n\t Line2\n\tLine3\n</note>")
writer = XMLWriter(declaration=None)
_normalizeGlifNote(element, writer)
self.assertEqual(
writer.getText(),
"<note>\n\tLine1\n\t Line2\n\tLine3\n</note>")

# Normalizer should remove the extra tab all lines have in common,
# but leave the additional tab on line 2
element = ET.fromstring(
"<note>\n\t\tLine1\n\t\t\tLine2\n\t\tLine3\n</note>")
writer = XMLWriter(declaration=None)
_normalizeGlifNote(element, writer)
self.assertEqual(
writer.getText(),
"<note>\n\tLine1\n\t\tLine2\n\tLine3\n</note>")

# Normalizer should remove the extra 4-space all lines have in common,
# but leave the additional 4-space on line 2
element = ET.fromstring(
"<note>\n Line1\n Line2\n Line3\n</note>")
writer = XMLWriter(declaration=None)
_normalizeGlifNote(element, writer)
self.assertEqual(
writer.getText(),
"<note>\n\tLine1\n\t Line2\n\tLine3\n</note>")

def test_normalizeGLIF_note_undefined(self):
element = ET.fromstring("<note></note>")
writer = XMLWriter(declaration=None)
Expand Down

0 comments on commit 73ffd53

Please sign in to comment.