diff --git a/Makefile b/Makefile index 7f98e9142..45d52e6ab 100644 --- a/Makefile +++ b/Makefile @@ -100,6 +100,8 @@ generate-page: repo/assets sed -i 's/_nsprefix_ = None/_nsprefix_ = "pc"/' $(GDS_PAGE) # hack to ensure child nodes also have pc: prefix... sed -i 's/.*_nsprefix_ = child_.prefix$$//' $(GDS_PAGE) + # hack to get #698: auto-inheritance of attributes and TextStyle + patch -p1 < ocrd_models/ocrd_page_generateds.build.inherited.patch # # Repos diff --git a/ocrd_models/ocrd_models/ocrd_page_generateds.py b/ocrd_models/ocrd_models/ocrd_page_generateds.py index 08857445f..78d2c3419 100644 --- a/ocrd_models/ocrd_models/ocrd_page_generateds.py +++ b/ocrd_models/ocrd_models/ocrd_page_generateds.py @@ -27,6 +27,7 @@ from six.moves import zip_longest import os import sys +import copy import re as re_ import base64 import datetime as datetime_ @@ -3898,27 +3899,27 @@ def buildAttributes(self, node, attrs, already_processed): if value is not None and 'id' not in already_processed: already_processed.add('id') self.id = value - value = find_attr_value_('primaryLanguage', node) + value = find_attr_value_('primaryLanguage', node) or self.parent_object_.primaryLanguage if value is not None and 'primaryLanguage' not in already_processed: already_processed.add('primaryLanguage') self.primaryLanguage = value self.validate_LanguageSimpleType(self.primaryLanguage) # validate type LanguageSimpleType - value = find_attr_value_('primaryScript', node) + value = find_attr_value_('primaryScript', node) or self.parent_object_.primaryScript if value is not None and 'primaryScript' not in already_processed: already_processed.add('primaryScript') self.primaryScript = value self.validate_ScriptSimpleType(self.primaryScript) # validate type ScriptSimpleType - value = find_attr_value_('secondaryScript', node) + value = find_attr_value_('secondaryScript', node) or self.parent_object_.secondaryScript if value is not None and 'secondaryScript' not in already_processed: already_processed.add('secondaryScript') self.secondaryScript = value self.validate_ScriptSimpleType(self.secondaryScript) # validate type ScriptSimpleType - value = find_attr_value_('readingDirection', node) + value = find_attr_value_('readingDirection', node) or self.parent_object_.readingDirection if value is not None and 'readingDirection' not in already_processed: already_processed.add('readingDirection') self.readingDirection = value self.validate_ReadingDirectionSimpleType(self.readingDirection) # validate type ReadingDirectionSimpleType - value = find_attr_value_('production', node) + value = find_attr_value_('production', node) or self.parent_object_.production if value is not None and 'production' not in already_processed: already_processed.add('production') self.production = value @@ -4399,27 +4400,27 @@ def buildAttributes(self, node, attrs, already_processed): if value is not None and 'id' not in already_processed: already_processed.add('id') self.id = value - value = find_attr_value_('language', node) + value = find_attr_value_('language', node) or self.parent_object_.primaryLanguage if value is not None and 'language' not in already_processed: already_processed.add('language') self.language = value self.validate_LanguageSimpleType(self.language) # validate type LanguageSimpleType - value = find_attr_value_('primaryScript', node) + value = find_attr_value_('primaryScript', node) or self.parent_object_.primaryScript if value is not None and 'primaryScript' not in already_processed: already_processed.add('primaryScript') self.primaryScript = value self.validate_ScriptSimpleType(self.primaryScript) # validate type ScriptSimpleType - value = find_attr_value_('secondaryScript', node) + value = find_attr_value_('secondaryScript', node) or self.parent_object_.secondaryScript if value is not None and 'secondaryScript' not in already_processed: already_processed.add('secondaryScript') self.secondaryScript = value self.validate_ScriptSimpleType(self.secondaryScript) # validate type ScriptSimpleType - value = find_attr_value_('readingDirection', node) + value = find_attr_value_('readingDirection', node) or self.parent_object_.readingDirection if value is not None and 'readingDirection' not in already_processed: already_processed.add('readingDirection') self.readingDirection = value self.validate_ReadingDirectionSimpleType(self.readingDirection) # validate type ReadingDirectionSimpleType - value = find_attr_value_('production', node) + value = find_attr_value_('production', node) or self.parent_object_.production if value is not None and 'production' not in already_processed: already_processed.add('production') self.production = value @@ -4858,12 +4859,12 @@ def buildAttributes(self, node, attrs, already_processed): self.symbol = False else: raise_parse_error(node, 'Bad boolean attribute') - value = find_attr_value_('script', node) + value = find_attr_value_('script', node) or self.parent_object_.primaryScript if value is not None and 'script' not in already_processed: already_processed.add('script') self.script = value self.validate_ScriptSimpleType(self.script) # validate type ScriptSimpleType - value = find_attr_value_('production', node) + value = find_attr_value_('production', node) or self.parent_object_.production if value is not None and 'production' not in already_processed: already_processed.add('production') self.production = value @@ -13918,6 +13919,22 @@ def build(self, node, gds_collector_=None): for child in node: nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] self.buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) + if not self.TextStyle and self.parent_object_.TextStyle: + self.TextStyle = copy.copy(self.parent_object_.TextStyle) + self.TextStyle.parent_object_ = self + if self.TextStyle: + for line in self.TextLine: + if not line.TextStyle: + line.TextStyle = copy.copy(self.TextStyle) + line.TextStyle.parent_object_ = line + for word in line.Word: + if not word.TextStyle: + word.TextStyle = copy.copy(self.TextStyle) + word.TextStyle.parent_object_ = word + for glyph in word.Glyph: + if not glyph.TextStyle: + glyph.TextStyle = copy.copy(self.TextStyle) + glyph.TextStyle.parent_object_ = glyph return self def buildAttributes(self, node, attrs, already_processed): value = find_attr_value_('orientation', node) @@ -13934,12 +13951,12 @@ def buildAttributes(self, node, attrs, already_processed): if value is not None and 'leading' not in already_processed: already_processed.add('leading') self.leading = self.gds_parse_integer(value, node, 'leading') - value = find_attr_value_('readingDirection', node) + value = find_attr_value_('readingDirection', node) or self.parent_object_.readingDirection if value is not None and 'readingDirection' not in already_processed: already_processed.add('readingDirection') self.readingDirection = value self.validate_ReadingDirectionSimpleType(self.readingDirection) # validate type ReadingDirectionSimpleType - value = find_attr_value_('textLineOrder', node) + value = find_attr_value_('textLineOrder', node) or self.parent_object_.textLineOrder if value is not None and 'textLineOrder' not in already_processed: already_processed.add('textLineOrder') self.textLineOrder = value @@ -13963,22 +13980,22 @@ def buildAttributes(self, node, attrs, already_processed): already_processed.add('align') self.align = value self.validate_AlignSimpleType(self.align) # validate type AlignSimpleType - value = find_attr_value_('primaryLanguage', node) + value = find_attr_value_('primaryLanguage', node) or self.parent_object_.primaryLanguage if value is not None and 'primaryLanguage' not in already_processed: already_processed.add('primaryLanguage') self.primaryLanguage = value self.validate_LanguageSimpleType(self.primaryLanguage) # validate type LanguageSimpleType - value = find_attr_value_('secondaryLanguage', node) + value = find_attr_value_('secondaryLanguage', node) or self.parent_object_.secondaryLanguage if value is not None and 'secondaryLanguage' not in already_processed: already_processed.add('secondaryLanguage') self.secondaryLanguage = value self.validate_LanguageSimpleType(self.secondaryLanguage) # validate type LanguageSimpleType - value = find_attr_value_('primaryScript', node) + value = find_attr_value_('primaryScript', node) or self.parent_object_.primaryScript if value is not None and 'primaryScript' not in already_processed: already_processed.add('primaryScript') self.primaryScript = value self.validate_ScriptSimpleType(self.primaryScript) # validate type ScriptSimpleType - value = find_attr_value_('secondaryScript', node) + value = find_attr_value_('secondaryScript', node) or self.parent_object_.secondaryScript if value is not None and 'secondaryScript' not in already_processed: already_processed.add('secondaryScript') self.secondaryScript = value diff --git a/ocrd_models/ocrd_page_generateds.build.inherited.patch b/ocrd_models/ocrd_page_generateds.build.inherited.patch new file mode 100644 index 000000000..afdf438d7 --- /dev/null +++ b/ocrd_models/ocrd_page_generateds.build.inherited.patch @@ -0,0 +1,158 @@ +diff --git a/ocrd_models/ocrd_models/ocrd_page_generateds.py b/ocrd_models/ocrd_models/ocrd_page_generateds.py +index 98111b0c..2ad8e9e4 100644 +--- a/ocrd_models/ocrd_models/ocrd_page_generateds.py ++++ b/ocrd_models/ocrd_models/ocrd_page_generateds.py +@@ -27,6 +27,7 @@ + from six.moves import zip_longest + import os + import sys ++import copy + import re as re_ + import base64 + import datetime as datetime_ +@@ -3944,27 +3945,27 @@ class TextLineType(GeneratedsSuper): + if value is not None and 'id' not in already_processed: + already_processed.add('id') + self.id = value +- value = find_attr_value_('primaryLanguage', node) ++ value = find_attr_value_('primaryLanguage', node) or self.parent_object_.primaryLanguage + if value is not None and 'primaryLanguage' not in already_processed: + already_processed.add('primaryLanguage') + self.primaryLanguage = value + self.validate_LanguageSimpleType(self.primaryLanguage) # validate type LanguageSimpleType +- value = find_attr_value_('primaryScript', node) ++ value = find_attr_value_('primaryScript', node) or self.parent_object_.primaryScript + if value is not None and 'primaryScript' not in already_processed: + already_processed.add('primaryScript') + self.primaryScript = value + self.validate_ScriptSimpleType(self.primaryScript) # validate type ScriptSimpleType +- value = find_attr_value_('secondaryScript', node) ++ value = find_attr_value_('secondaryScript', node) or self.parent_object_.secondaryScript + if value is not None and 'secondaryScript' not in already_processed: + already_processed.add('secondaryScript') + self.secondaryScript = value + self.validate_ScriptSimpleType(self.secondaryScript) # validate type ScriptSimpleType +- value = find_attr_value_('readingDirection', node) ++ value = find_attr_value_('readingDirection', node) or self.parent_object_.readingDirection + if value is not None and 'readingDirection' not in already_processed: + already_processed.add('readingDirection') + self.readingDirection = value + self.validate_ReadingDirectionSimpleType(self.readingDirection) # validate type ReadingDirectionSimpleType +- value = find_attr_value_('production', node) ++ value = find_attr_value_('production', node) or self.parent_object_.production + if value is not None and 'production' not in already_processed: + already_processed.add('production') + self.production = value +@@ -4453,27 +4454,27 @@ class WordType(GeneratedsSuper): + if value is not None and 'id' not in already_processed: + already_processed.add('id') + self.id = value +- value = find_attr_value_('language', node) ++ value = find_attr_value_('language', node) or self.parent_object_.primaryLanguage + if value is not None and 'language' not in already_processed: + already_processed.add('language') + self.language = value + self.validate_LanguageSimpleType(self.language) # validate type LanguageSimpleType +- value = find_attr_value_('primaryScript', node) ++ value = find_attr_value_('primaryScript', node) or self.parent_object_.primaryScript + if value is not None and 'primaryScript' not in already_processed: + already_processed.add('primaryScript') + self.primaryScript = value + self.validate_ScriptSimpleType(self.primaryScript) # validate type ScriptSimpleType +- value = find_attr_value_('secondaryScript', node) ++ value = find_attr_value_('secondaryScript', node) or self.parent_object_.secondaryScript + if value is not None and 'secondaryScript' not in already_processed: + already_processed.add('secondaryScript') + self.secondaryScript = value + self.validate_ScriptSimpleType(self.secondaryScript) # validate type ScriptSimpleType +- value = find_attr_value_('readingDirection', node) ++ value = find_attr_value_('readingDirection', node) or self.parent_object_.readingDirection + if value is not None and 'readingDirection' not in already_processed: + already_processed.add('readingDirection') + self.readingDirection = value + self.validate_ReadingDirectionSimpleType(self.readingDirection) # validate type ReadingDirectionSimpleType +- value = find_attr_value_('production', node) ++ value = find_attr_value_('production', node) or self.parent_object_.production + if value is not None and 'production' not in already_processed: + already_processed.add('production') + self.production = value +@@ -4920,12 +4921,12 @@ class GlyphType(GeneratedsSuper): + self.symbol = False + else: + raise_parse_error(node, 'Bad boolean attribute') +- value = find_attr_value_('script', node) ++ value = find_attr_value_('script', node) or self.parent_object_.primaryScript + if value is not None and 'script' not in already_processed: + already_processed.add('script') + self.script = value + self.validate_ScriptSimpleType(self.script) # validate type ScriptSimpleType +- value = find_attr_value_('production', node) ++ value = find_attr_value_('production', node) or self.parent_object_.production + if value is not None and 'production' not in already_processed: + already_processed.add('production') + self.production = value +@@ -14332,6 +14333,22 @@ class TextRegionType(RegionType): + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) ++ if not self.TextStyle and self.parent_object_.TextStyle: ++ self.TextStyle = copy.copy(self.parent_object_.TextStyle) ++ self.TextStyle.parent_object_ = self ++ if self.TextStyle: ++ for line in self.TextLine: ++ if not line.TextStyle: ++ line.TextStyle = copy.copy(self.TextStyle) ++ line.TextStyle.parent_object_ = line ++ for word in line.Word: ++ if not word.TextStyle: ++ word.TextStyle = copy.copy(self.TextStyle) ++ word.TextStyle.parent_object_ = word ++ for glyph in word.Glyph: ++ if not glyph.TextStyle: ++ glyph.TextStyle = copy.copy(self.TextStyle) ++ glyph.TextStyle.parent_object_ = glyph + return self + def buildAttributes(self, node, attrs, already_processed): + value = find_attr_value_('orientation', node) +@@ -14348,12 +14365,12 @@ class TextRegionType(RegionType): + if value is not None and 'leading' not in already_processed: + already_processed.add('leading') + self.leading = self.gds_parse_integer(value, node, 'leading') +- value = find_attr_value_('readingDirection', node) ++ value = find_attr_value_('readingDirection', node) or self.parent_object_.readingDirection + if value is not None and 'readingDirection' not in already_processed: + already_processed.add('readingDirection') + self.readingDirection = value + self.validate_ReadingDirectionSimpleType(self.readingDirection) # validate type ReadingDirectionSimpleType +- value = find_attr_value_('textLineOrder', node) ++ value = find_attr_value_('textLineOrder', node) or self.parent_object_.textLineOrder + if value is not None and 'textLineOrder' not in already_processed: + already_processed.add('textLineOrder') + self.textLineOrder = value +@@ -14377,22 +14394,22 @@ class TextRegionType(RegionType): + already_processed.add('align') + self.align = value + self.validate_AlignSimpleType(self.align) # validate type AlignSimpleType +- value = find_attr_value_('primaryLanguage', node) ++ value = find_attr_value_('primaryLanguage', node) or self.parent_object_.primaryLanguage + if value is not None and 'primaryLanguage' not in already_processed: + already_processed.add('primaryLanguage') + self.primaryLanguage = value + self.validate_LanguageSimpleType(self.primaryLanguage) # validate type LanguageSimpleType +- value = find_attr_value_('secondaryLanguage', node) ++ value = find_attr_value_('secondaryLanguage', node) or self.parent_object_.secondaryLanguage + if value is not None and 'secondaryLanguage' not in already_processed: + already_processed.add('secondaryLanguage') + self.secondaryLanguage = value + self.validate_LanguageSimpleType(self.secondaryLanguage) # validate type LanguageSimpleType +- value = find_attr_value_('primaryScript', node) ++ value = find_attr_value_('primaryScript', node) or self.parent_object_.primaryScript + if value is not None and 'primaryScript' not in already_processed: + already_processed.add('primaryScript') + self.primaryScript = value + self.validate_ScriptSimpleType(self.primaryScript) # validate type ScriptSimpleType +- value = find_attr_value_('secondaryScript', node) ++ value = find_attr_value_('secondaryScript', node) or self.parent_object_.secondaryScript + if value is not None and 'secondaryScript' not in already_processed: + already_processed.add('secondaryScript') + self.secondaryScript = value