WARNING: If you’re not comfortable with technical details, downloading Python scripts, and playing with XML source files, this won’t be the blog post for you.  But if you’re keen to lift the hood and fiddle under the covers of SVG files, read on!

The Brand Indicators for Message Identification (BIMI) specification requires the logo identifiers to be in SVG Tiny Portable/Secure (SVG P/S) format.  SVG P/S is a new profile of the SVG Tiny 1.2 format standardized by the W3C.

Since SVG is a vector image format saved in an XML document, and there are currently no tools that export SVG P/S compliant images, we developed a RELAX NG Compact (RNC) XML validation file for the SVG P/S profile.  So, you can take an SVG file and validate that it is compliant with the SVG P/S profile specification by running it against the SVG P/S RNC schema.

The SVG P/S profile is still being refined as it moves through the standardization process.  Please bear with us as the specification is likely to change with community feedback.

In order to run an SVG file against the SVG P/S RNC, it requires an RNC schema interpreter.  There are a number of RNC libraries available, but one that’s proven useful is the Python package called jingtrang (which is a wrapper for a common Java interpreter).

Assuming you’re running Python 3.x (and have Java installed), you should be able to run the installation command from a terminal window:

$ pip3 install jingtrang

You will also need to download the BIMI documents from the following links so that you can run and test the RNC validator:

You should now have everything you need to run the following command (modified as necessary depending on the path to the script and SVG file):

$ pyjing -c [path/to/]svg_1-2_ps.rnc [path/to/logo.svg]

If the SVG file passes SVG P/S validation, there is no output (which is kind of anti-climactic, but no news is good news, I guess).

If the SVG file fails to validate according to the SVG P/S RNC, the errors will be reported in a long list, one issue per line.  For example, the existence of extraneous ‘x=’ and ‘y=’ attributes, or a missing <title> element within the XML code will be indicated by the “error: value;” pair.

Example Output with Errors:

$ pyjing -c svg_1-2_ps.rnc /SVGs/bimi-sq.svg
/SVGs/bimi-sq.svg:3:62: error: value of attribute "version" is invalid; must be equal to "1.2"
/SVGs/bimi-sq.svg:3:62: error: value of attribute "baseProfile" is invalid; must be equal to 
/SVGs/bimi-sq.svg:3:62: error: attribute "x" not allowed here; expected attribute "about", 
"class", "color", "color-rendering", "content", "contentScriptType", "datatype", "direction", 
"display-align", "externalResourcesRequired", "fill", "fill-opacity", "fill-rule", "focusable",
"font-family", "font-size", "font-style", "font-variant", "font-weight", "height", 
"line-increment", "playbackOrder", "preserveAspectRatio", "property", "rel", "resource", "rev",
 "role", "snapshotTime", "solid-color", "solid-opacity", "stop-color", "stop-opacity", "stroke",
 "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-
miterlimit", "stroke-opacity", "stroke-width", "text-align", "text-anchor", "timelineBegin", 
"typeof", "unicode-bidi", "vector-effect", "viewBox", "width", "xml:base", "xml:lang", 
"xml:space" or "zoomAndPan"
/SVGs/bimi-sq.svg:3:62: error: attribute "y" not allowed here; expected attribute "about", 
"class", "color", "color-rendering", "content", "contentScriptType", "datatype", "direction",
"display-align", "externalResourcesRequired", "fill", "fill-opacity", "fill-rule", "focusable",
"font-family", "font-size", "font-style", "font-variant", "font-weight", "height", 
"line-increment", "playbackOrder", "preserveAspectRatio", "property", "rel", "resource", "rev", 
"role", "snapshotTime", "solid-color", "solid-opacity", "stop-color", "stop-opacity", "stroke", 
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit",
"stroke-opacity", "stroke-width", "text-align", "text-anchor", "timelineBegin", "typeof", 
"unicode-bidi", "vector-effect", "viewBox", "width", "xml:base", "xml:lang", "xml:space"
 or "zoomAndPan"
/SVGs/bimi-sq.svg:4:4: error: element "g" not allowed yet; missing required element "title"

As you can see from the example output above, each error is reported one per line.  Look for the initial “error: “ and the following statement should help track down what needs to be fixed.

Example Output That Passes Validation:

$ pyjing -c svg_1-2_ps.rnc /SVGs/bimi-sq_tiny_ps.svg

As you can see from the valid output example… well, there’s not much to see.  That’s good.

Until there is a mapping between the error strings and required actions, it takes some investigation to determine how to correct the issue.  In many cases, an early error will cause cascading issues; correcting the early errors often clear up issues reported later in the list.  It may be beneficial to iterate through changes and re-evaluate as you go.

Fortunately, given that the SVG file is in XML format, it’s simple enough to open in a text editor and modify the source, save the updated file, and run the RNC again.  It may take some trial-and-error, but starting with an SVG Tiny 1.2 file gets you 95% of the way to SVG Tiny P/S format.  All that’s left is usually some minor editing.