-
Notifications
You must be signed in to change notification settings - Fork 24
Implementar validações de <graphic> e <inline-graphic> conforme SPS 1.10 #1095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
49e3e00
4580b4f
18d742c
09b420f
63f2228
1d1513c
7b2e4b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,4 +42,6 @@ nosetests.xml | |
| .venv | ||
|
|
||
| .idea | ||
| src/scielo-scholarly-data | ||
|
|
||
| # Source packages | ||
| src/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,123 @@ | ||
| import os | ||
| from packtools.sps.validation.visual_resource_base import VisualResourceBaseValidation | ||
| from packtools.sps.validation.utils import build_response | ||
| from packtools.sps.models.graphic import XmlGraphic | ||
|
|
||
|
|
||
| class GraphicValidation(VisualResourceBaseValidation): | ||
| ... | ||
| """ | ||
| Validation class for <graphic> and <inline-graphic> elements according to SPS 1.10. | ||
|
|
||
| Validates: | ||
| - @id attribute (required for both <graphic> and <inline-graphic>) | ||
| - @xlink:href attribute (required) | ||
| - File extensions (.jpg, .jpeg, .png, .tif, .tiff, .svg) | ||
| - .svg only allowed inside <alternatives> | ||
|
|
||
| Note: Accessibility validation (<alt-text>, <long-desc>) is handled separately | ||
| by XMLAccessibilityDataValidation in the validation pipeline to avoid duplicates. | ||
| """ | ||
|
|
||
| def validate(self): | ||
| """Execute all validations for graphic/inline-graphic elements.""" | ||
| yield self.validate_id() | ||
| yield self.validate_xlink_href() | ||
| yield from self.validate_svg_in_alternatives() | ||
| # Note: Accessibility validation is handled by the dedicated XMLAccessibilityDataValidation | ||
| # in the pipeline to avoid duplicate validation entries in reports | ||
|
|
||
| def validate_id(self): | ||
| """ | ||
| Validate @id attribute is present in <graphic> and <inline-graphic>. | ||
|
|
||
| Per SPS 1.10 specification, @id is required for both <graphic> and <inline-graphic> elements. | ||
| This overrides the base class behavior which exempts inline-* elements. | ||
| """ | ||
| xml = self.data.get("xml") | ||
| tag = self.data.get("tag") | ||
| id_value = self.data.get("id") | ||
|
|
||
| valid = bool(id_value) | ||
| elem = xml[:xml.find(">")+1] if xml else None | ||
| expected = f"id for {elem}" if not valid else None | ||
|
|
||
|
Comment on lines
+40
to
+43
|
||
| return build_response( | ||
| title="@id", | ||
| parent=self.data, | ||
| item=tag, | ||
| sub_item=None, | ||
| is_valid=valid, | ||
| validation_type="exist", | ||
| expected=expected, | ||
| obtained=id_value, | ||
| advice=f'Add id="" to {xml}' if not valid else None, | ||
| error_level=self.params["media_attributes_error_level"], | ||
| data=self.data, | ||
| ) | ||
|
|
||
| def validate_svg_in_alternatives(self): | ||
| """ | ||
| Validate that .svg extension is only used when <graphic> is inside <alternatives>. | ||
|
|
||
| Per SPS 1.10 specification: | ||
| - .svg files are only allowed when the graphic is inside <alternatives> | ||
| - Other formats (.jpg, .jpeg, .png, .tif, .tiff) can be used anywhere | ||
|
|
||
| Yields: | ||
| dict: Validation response | ||
| """ | ||
| xlink_href = self.data.get("xlink_href") | ||
| parent_tag = self.data.get("parent_tag") | ||
|
|
||
| if not xlink_href: | ||
| return | ||
|
|
||
| # Get file extension | ||
| _, ext = os.path.splitext(xlink_href) | ||
| ext = ext.lower() | ||
|
|
||
| # Check if it's an SVG file | ||
| if ext == ".svg": | ||
| # SVG is only valid inside <alternatives> | ||
| is_valid = parent_tag == "alternatives" | ||
|
|
||
| yield build_response( | ||
| title="SVG in alternatives", | ||
| parent=self.data, | ||
| item=self.data.get("tag"), | ||
| sub_item="xlink_href", | ||
| is_valid=is_valid, | ||
| validation_type="format", | ||
| expected="<graphic> with .svg extension inside <alternatives>", | ||
| obtained=f"{self.data.get('tag')} with .svg inside <{parent_tag}>", | ||
| advice=( | ||
| f"SVG files are only allowed inside <alternatives>. " | ||
| f"The file '{xlink_href}' is currently in <{parent_tag}>. " | ||
| f"Either move this <graphic> inside <alternatives> or use a different format (.jpg, .png, .tif)." | ||
| ) if not is_valid else None, | ||
| error_level=self.params.get("svg_error_level", "ERROR"), | ||
| data=self.data, | ||
| ) | ||
|
|
||
|
|
||
| class XMLGraphicValidation: | ||
| """ | ||
| Validates all <graphic> and <inline-graphic> elements in an XML document. | ||
|
|
||
| This class follows the same pattern as XMLMediaValidation and XMLAccessibilityDataValidation. | ||
| It iterates through all graphic elements found in the document and validates each one. | ||
| """ | ||
|
|
||
| def __init__(self, xmltree, params): | ||
| self.params = params | ||
| self.xml_graphic = XmlGraphic(xmltree) | ||
|
|
||
| def validate(self): | ||
| """ | ||
| Validate all graphic and inline-graphic elements in the document. | ||
|
|
||
| Yields validation results for each graphic element found. | ||
| """ | ||
| for data in self.xml_graphic.data: | ||
| validator = GraphicValidation(data, self.params) | ||
| yield from validator.validate() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,7 @@ | |
|
|
||
| from packtools.sps.validation.supplementary_material import XmlSupplementaryMaterialValidation | ||
| from packtools.sps.validation.ext_link import ExtLinkValidation | ||
| from packtools.sps.validation.graphic import XMLGraphicValidation | ||
|
|
||
|
|
||
| def validate_affiliations(xmltree, params): | ||
|
|
@@ -325,3 +326,19 @@ def validate_ext_links(xmltree, params): | |
| yield from validator.validate_ext_link_type_value() | ||
| yield from validator.validate_descriptive_text() | ||
| yield from validator.validate_xlink_title_when_generic() | ||
|
|
||
|
|
||
| def validate_graphics(xmltree, params): | ||
| """ | ||
| Validates <graphic> and <inline-graphic> elements according to SPS 1.10 specification. | ||
|
|
||
| Validates: | ||
| - @id attribute (required for both <graphic> and <inline-graphic>) | ||
| - @xlink:href attribute (required) | ||
| - File extensions (.jpg, .jpeg, .png, .tif, .tiff, .svg) | ||
| - .svg only allowed inside <alternatives> | ||
| - Accessibility elements (<alt-text>, <long-desc>) | ||
| """ | ||
|
Comment on lines
+332
to
+341
|
||
| graphic_rules = params["graphic_rules"] | ||
| validator = XMLGraphicValidation(xmltree, graphic_rules) | ||
| yield from validator.validate() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| { | ||
| "graphic_rules": { | ||
| "media_attributes_error_level": "CRITICAL", | ||
| "xlink_href_error_level": "ERROR", | ||
| "valid_extension": ["jpg", "jpeg", "png", "tif", "tiff", "svg"], | ||
| "svg_error_level": "ERROR", | ||
| "alt_text_exist_error_level": "WARNING", | ||
| "alt_text_content_error_level": "CRITICAL", | ||
| "alt_text_media_restriction_error_level": "ERROR", | ||
| "alt_text_duplication_error_level": "WARNING", | ||
| "decorative_alt_text_error_level": "INFO", | ||
| "long_desc_exist_error_level": "WARNING", | ||
| "long_desc_content_error_level": "CRITICAL", | ||
| "long_desc_minimum_length_error_level": "ERROR", | ||
| "long_desc_media_restriction_error_level": "ERROR", | ||
| "long_desc_duplication_error_level": "WARNING", | ||
| "long_desc_occurrence_error_level": "ERROR", | ||
| "long_desc_null_incompatibility_error_level": "WARNING", | ||
| "xref_transcript_error_level": "WARNING", | ||
| "transcript_error_level": "WARNING", | ||
| "content_type_error_level": "CRITICAL", | ||
| "speaker_speech_error_level": "WARNING", | ||
| "structure_error_level": "CRITICAL", | ||
| "content_types": ["machine-generated"] | ||
|
Comment on lines
+2
to
+24
|
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GraphicValidation.validate()calls the inheritedvalidate_xlink_href(), butVisualResourceBaseValidation.validate_xlink_href()usesos.path.splitext(xlink_href)without guarding for missing@xlink:href. Ifxlink_hrefisNone(attribute absent), this will raiseTypeErrorand break the whole validation pipeline instead of reporting a CRITICAL/ERROR result. Consider overridingvalidate_xlink_href()inGraphicValidation(or fixing the base method) to (1) validate presence of@xlink:hrefand (2) only run extension validation when a value exists.