summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2020-11-05 19:43:01 +0000
committerMichael Williamson <mike@zwobble.org>2020-11-05 19:43:01 +0000
commit8fde170b06becb51d2650b60dd28e23eaf862e25 (patch)
tree3e804a680218dabe24470ea71b7cdadb6e0d3fb3
parentfd10b8d93b361e80bb1fc5b19f19465fc51d9b77 (diff)
Add style mapping for all caps
-rw-r--r--NEWS4
-rw-r--r--README.md11
-rw-r--r--mammoth/conversion.py4
-rw-r--r--mammoth/document_matchers.py10
-rw-r--r--mammoth/documents.py3
-rw-r--r--mammoth/docx/body_xml.py2
-rw-r--r--mammoth/styles/parser/document_matcher_parser.py21
-rw-r--r--tests/conversion_tests.py19
-rw-r--r--tests/docx/body_xml_tests.py1
-rw-r--r--tests/styles/parser/document_matcher_parser_tests.py9
10 files changed, 70 insertions, 14 deletions
diff --git a/NEWS b/NEWS
index 4bca755..bbe5300 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+# 1.4.13
+
+* Add style mapping for all caps.
+
# 1.4.12
* Handle underline elements where w:val is "none".
diff --git a/README.md b/README.md
index 795971b..9b142c6 100644
--- a/README.md
+++ b/README.md
@@ -596,6 +596,17 @@ strike
Note that this matches text that has had strikethrough explicitly applied to it.
It will not match any text that is struckthrough because of its paragraph or run style.
+#### All caps
+
+Match explicitly all caps text:
+
+```
+all-caps
+```
+
+Note that this matches text that has had all caps explicitly applied to it.
+It will not match any text that is all caps because of its paragraph or run style.
+
#### Small caps
Match explicitly small caps text:
diff --git a/mammoth/conversion.py b/mammoth/conversion.py
index d463116..bdc8687 100644
--- a/mammoth/conversion.py
+++ b/mammoth/conversion.py
@@ -111,6 +111,8 @@ class _DocumentConverter(documents.element_visitor(args=1)):
paths = []
if run.is_small_caps:
paths.append(self._find_style_for_run_property("small_caps"))
+ if run.is_all_caps:
+ paths.append(self._find_style_for_run_property("all_caps"))
if run.is_strikethrough:
paths.append(self._find_style_for_run_property("strikethrough", default="s"))
if run.is_underline:
@@ -353,7 +355,7 @@ class _DocumentConverter(documents.element_visitor(args=1)):
def _document_matcher_matches(matcher, element, element_type):
- if matcher.element_type in ["underline", "strikethrough", "small_caps", "bold", "italic", "comment_reference"]:
+ if matcher.element_type in ["underline", "strikethrough", "all_caps", "small_caps", "bold", "italic", "comment_reference"]:
return matcher.element_type == element_type
elif matcher.element_type == "break":
return (
diff --git a/mammoth/document_matchers.py b/mammoth/document_matchers.py
index 91adf3f..f831b8a 100644
--- a/mammoth/document_matchers.py
+++ b/mammoth/document_matchers.py
@@ -43,6 +43,10 @@ class strikethrough(object):
element_type = "strikethrough"
+class all_caps(object):
+ element_type = "all_caps"
+
+
class small_caps(object):
element_type = "small_caps"
@@ -66,8 +70,8 @@ def equal_to(value):
def _operator_equal_to(first, second):
return first.upper() == second.upper()
-
-
+
+
def starts_with(value):
return StringMatcher(_operator_starts_with, value)
@@ -79,6 +83,6 @@ def _operator_starts_with(first, second):
class StringMatcher(object):
operator = cobble.field()
value = cobble.field()
-
+
def matches(self, other):
return self.operator(self.value, other)
diff --git a/mammoth/documents.py b/mammoth/documents.py
index e1e1e58..7559d40 100644
--- a/mammoth/documents.py
+++ b/mammoth/documents.py
@@ -48,6 +48,7 @@ class Run(HasChildren):
is_italic = cobble.field()
is_underline = cobble.field()
is_strikethrough = cobble.field()
+ is_all_caps = cobble.field()
is_small_caps = cobble.field()
vertical_alignment = cobble.field()
font = cobble.field()
@@ -122,6 +123,7 @@ def run(
is_italic=None,
is_underline=None,
is_strikethrough=None,
+ is_all_caps=None,
is_small_caps=None,
vertical_alignment=None,
font=None,
@@ -137,6 +139,7 @@ def run(
is_italic=bool(is_italic),
is_underline=bool(is_underline),
is_strikethrough=bool(is_strikethrough),
+ is_all_caps=bool(is_all_caps),
is_small_caps=bool(is_small_caps),
vertical_alignment=vertical_alignment,
font=font,
diff --git a/mammoth/docx/body_xml.py b/mammoth/docx/body_xml.py
index dcc704b..17cf31b 100644
--- a/mammoth/docx/body_xml.py
+++ b/mammoth/docx/body_xml.py
@@ -91,6 +91,7 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f
is_italic = read_boolean_element(properties.find_child("w:i"))
is_underline = read_underline_element(properties.find_child("w:u"))
is_strikethrough = read_boolean_element(properties.find_child("w:strike"))
+ is_all_caps = read_boolean_element(properties.find_child("w:caps"))
is_small_caps = read_boolean_element(properties.find_child("w:smallCaps"))
def add_complex_field_hyperlink(children):
@@ -111,6 +112,7 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f
is_italic=is_italic,
is_underline=is_underline,
is_strikethrough=is_strikethrough,
+ is_all_caps=is_all_caps,
is_small_caps=is_small_caps,
vertical_alignment=vertical_alignment,
font=font,
diff --git a/mammoth/styles/parser/document_matcher_parser.py b/mammoth/styles/parser/document_matcher_parser.py
index b9e09f3..9891e4b 100644
--- a/mammoth/styles/parser/document_matcher_parser.py
+++ b/mammoth/styles/parser/document_matcher_parser.py
@@ -9,17 +9,17 @@ def parse_document_matcher(tokens):
style_id = try_parse_class_name(tokens)
style_name = _parse_style_name(tokens)
numbering = _parse_numbering(tokens)
-
+
return document_matchers.paragraph(
style_id=style_id,
style_name=style_name,
numbering=numbering,
)
-
+
elif tokens.try_skip(TokenType.IDENTIFIER, "r"):
style_id = try_parse_class_name(tokens)
style_name = _parse_style_name(tokens)
-
+
return document_matchers.run(
style_id=style_id,
style_name=style_name,
@@ -36,19 +36,22 @@ def parse_document_matcher(tokens):
elif tokens.try_skip(TokenType.IDENTIFIER, "b"):
return document_matchers.bold
-
+
elif tokens.try_skip(TokenType.IDENTIFIER, "i"):
return document_matchers.italic
-
+
elif tokens.try_skip(TokenType.IDENTIFIER, "u"):
return document_matchers.underline
-
+
elif tokens.try_skip(TokenType.IDENTIFIER, "strike"):
return document_matchers.strikethrough
-
+
+ elif tokens.try_skip(TokenType.IDENTIFIER, "all-caps"):
+ return document_matchers.all_caps
+
elif tokens.try_skip(TokenType.IDENTIFIER, "small-caps"):
return document_matchers.small_caps
-
+
elif tokens.try_skip(TokenType.IDENTIFIER, "comment-reference"):
return document_matchers.comment_reference
@@ -101,7 +104,7 @@ def _parse_break(tokens):
tokens.skip(TokenType.SYMBOL, "=")
type_name = parse_string(tokens)
tokens.skip(TokenType.SYMBOL, "]");
-
+
if type_name == "line":
return document_matchers.line_break
elif type_name == "page":
diff --git a/tests/conversion_tests.py b/tests/conversion_tests.py
index 878c804..c4e667f 100644
--- a/tests/conversion_tests.py
+++ b/tests/conversion_tests.py
@@ -231,6 +231,25 @@ def strikethrough_runs_can_be_configured_with_style_mapping():
@istest
+def sml_caps_runs_are_ignored_by_default():
+ result = convert_document_element_to_html(
+ documents.run(children=[documents.text("Hello")], is_all_caps=True),
+ )
+ assert_equal("Hello", result.value)
+
+
+@istest
+def all_caps_runs_can_be_mapped_using_style_mapping():
+ result = convert_document_element_to_html(
+ documents.run(children=[documents.text("Hello")], is_all_caps=True),
+ style_map=[
+ _style_mapping("all-caps => span")
+ ]
+ )
+ assert_equal("<span>Hello</span>", result.value)
+
+
+@istest
def small_caps_runs_are_ignored_by_default():
result = convert_document_element_to_html(
documents.run(children=[documents.text("Hello")], is_small_caps=True),
diff --git a/tests/docx/body_xml_tests.py b/tests/docx/body_xml_tests.py
index 746259c..20f89a9 100644
--- a/tests/docx/body_xml_tests.py
+++ b/tests/docx/body_xml_tests.py
@@ -301,6 +301,7 @@ class RunTests(object):
param(attr_name="is_underline", tag_name="w:u"),
param(attr_name="is_italic", tag_name="w:i"),
param(attr_name="is_strikethrough", tag_name="w:strike"),
+ param(attr_name="is_all_caps", tag_name="w:caps"),
param(attr_name="is_small_caps", tag_name="w:smallCaps"),
])(istest(func))
diff --git a/tests/styles/parser/document_matcher_parser_tests.py b/tests/styles/parser/document_matcher_parser_tests.py
index dc93941..18233d2 100644
--- a/tests/styles/parser/document_matcher_parser_tests.py
+++ b/tests/styles/parser/document_matcher_parser_tests.py
@@ -151,6 +151,13 @@ def reads_strikethrough():
)
@istest
+def reads_all_caps():
+ assert_equal(
+ document_matchers.all_caps,
+ read_document_matcher("all-caps")
+ )
+
+@istest
def reads_small_caps():
assert_equal(
document_matchers.small_caps,
@@ -190,7 +197,7 @@ def reads_column_breaks():
def unrecognised_break_type_raises_error():
error = assert_raises(LineParseError, lambda: read_document_matcher("br[type='unknownBreakType']"))
assert_equal("Unrecognised break type: unknownBreakType", str(error))
-
+
def read_document_matcher(string):
return parse_document_matcher(TokenIterator(tokenise(string)))