diff options
| author | Michael Williamson <mike@zwobble.org> | 2020-11-05 19:43:01 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2020-11-05 19:43:01 +0000 |
| commit | 8fde170b06becb51d2650b60dd28e23eaf862e25 (patch) | |
| tree | 3e804a680218dabe24470ea71b7cdadb6e0d3fb3 | |
| parent | fd10b8d93b361e80bb1fc5b19f19465fc51d9b77 (diff) | |
Add style mapping for all caps
| -rw-r--r-- | NEWS | 4 | ||||
| -rw-r--r-- | README.md | 11 | ||||
| -rw-r--r-- | mammoth/conversion.py | 4 | ||||
| -rw-r--r-- | mammoth/document_matchers.py | 10 | ||||
| -rw-r--r-- | mammoth/documents.py | 3 | ||||
| -rw-r--r-- | mammoth/docx/body_xml.py | 2 | ||||
| -rw-r--r-- | mammoth/styles/parser/document_matcher_parser.py | 21 | ||||
| -rw-r--r-- | tests/conversion_tests.py | 19 | ||||
| -rw-r--r-- | tests/docx/body_xml_tests.py | 1 | ||||
| -rw-r--r-- | tests/styles/parser/document_matcher_parser_tests.py | 9 |
10 files changed, 70 insertions, 14 deletions
@@ -1,3 +1,7 @@ +# 1.4.13 + +* Add style mapping for all caps. + # 1.4.12 * Handle underline elements where w:val is "none". @@ -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))) |
