<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" xmlns:px="http://www.daisy.org/ns/pipeline/xproc" xmlns:pxi="http://www.daisy.org/ns/pipeline/xproc/internal" xmlns:pe="http://www.daisy.org/ns/pipeline/errors" xmlns:c="http://www.w3.org/ns/xproc-step" xmlns:cx="http://xmlcalabash.com/ns/extensions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tmp="http://www.daisy.org/ns/pipeline/tmp" xmlns:svrl="http://purl.oclc.org/dsdl/svrl" xmlns:d="http://www.daisy.org/ns/pipeline/data" xmlns:l="http://xproc.org/library" xmlns:m="http://www.w3.org/1998/Math/MathML" version="1.0" type="px:dtbook-validate" name="main" exclude-inline-prefixes="#all"> <p:documentation xmlns="http://www.w3.org/1999/xhtml"> <h1>DTBook Validator</h1> <p>Validates DTBook documents. Supports inclusion of MathML.</p> <address> Authors: <dl px:role="author"> <dt>Name:</dt> <dd px:role="name">Marisa DeMeglio</dd> <dt>E-mail:</dt> <dd><a href="mailto:marisa.demeglio@gmail.com">marisa.demeglio@gmail.com</a></dd> <dt>Organization:</dt> <dd px:role="organization">DAISY Consortium</dd> </dl> </address> </p:documentation> <p:input port="source.fileset" primary="true"/> <p:input port="source.in-memory" sequence="true"> <p:documentation xmlns="http://www.w3.org/1999/xhtml"> <p>Input fileset</p> <p>Should contain a single DTBook file.</p> <p>May contain referenced images, but if it doesn't and images are stored on disk the validator will find them too.</p> </p:documentation> <p:empty/> </p:input> <p:output port="result" primary="true"> <p:documentation xmlns="http://www.w3.org/1999/xhtml"> <h1>The DTBook document, or a dummy <code>tmp:error</code> document if the input does not contain a DTBook or it is not well-formed.</h1> </p:documentation> <p:pipe step="if-dtbook-wellformed" port="result"/> </p:output> <p:option name="report-method" cx:type="port|log|error" select="'port'"> <p:documentation xmlns="http://www.w3.org/1999/xhtml"> <p>Select the method used for reporting validation issues:</p> <dl> <dt>port</dt> <dd>Issues are reported only on the xml-report and html-report output ports.</dd> <dt>log</dt> <dd>In addition to the xml-report and html-report output ports, issues are also reported through warning messages.</dd> <dt>error</dt> <dd>Issues are reported through error messages and also trigger an XProc error. (Note that an error is always thrown when a DTBook has an unexpected version.)</dd> </dl> </p:documentation> </p:option> <p:output port="xml-report"> <p:documentation xmlns="http://www.w3.org/1999/xhtml"> <h1>XML Reports</h1> <p>Raw output from all types of validation used (RelaxNG, Schematron, custom).</p> </p:documentation> <p:pipe step="if-dtbook-wellformed" port="xml-report"/> </p:output> <p:output port="html-report" px:media-type="application/vnd.pipeline.report+xml"> <p:documentation xmlns="http://www.w3.org/1999/xhtml"> <h1>HTML Report</h1> <p>A single HTML-formatted version of the validation report.</p> </p:documentation> <p:pipe step="html-report" port="result"/> </p:output> <p:output port="validation-status" px:media-type="application/vnd.pipeline.status+xml"> <p:documentation xmlns="http://www.w3.org/1999/xhtml"> <h1>Validation status</h1> <p>Validation status (http://daisy.github.io/pipeline/StatusXML).</p> </p:documentation> <p:pipe step="validation-status" port="result"/> </p:output> <p:option name="mathml-version" select="'3.0'" cx:type="3.0|2.0"> <p:documentation> <p>Version of MathML in the DTBook file</p> </p:documentation> </p:option> <p:option name="check-images" select="false()" cx:as="xs:boolean"> <p:documentation> <p>Check to see that referenced images exist on disk</p> </p:documentation> </p:option> <p:option name="nimas" select="false()" cx:as="xs:boolean"> <p:documentation> <p>Validate against NIMAS 1.1</p> </p:documentation> </p:option> <p:option name="skip-schematron" select="false()" cx:as="xs:boolean"> <p:documentation> <p>Skip Schematron validation</p> <p>Should not be set when <code>nimas</code> is also set as NIMAS validation happens with Schematron.</p> </p:documentation> </p:option> <p:option name="allow-aural-css-attributes" select="false()" cx:as="xs:boolean"> <p:documentation> <p>Whether the input contains aural CSS attributes (attributes with namespace "http://www.daisy.org/ns/pipeline/tts").</p> </p:documentation> </p:option> <p:import href="http://www.daisy.org/pipeline/modules/common-utils/library.xpl"> <p:documentation> px:message </p:documentation> </p:import> <p:import href="http://www.daisy.org/pipeline/modules/fileset-utils/library.xpl"> <p:documentation> px:fileset-rebase px:fileset-load </p:documentation> </p:import> <p:import href="http://www.daisy.org/pipeline/modules/validation-utils/library.xpl"> <p:documentation> l:relax-ng-report px:report-errors px:check-files-wellformed px:combine-validation-reports px:validation-status px:validation-report-to-html </p:documentation> </p:import> <p:import href="http://www.daisy.org/pipeline/modules/css-utils/library.xpl"> <p:documentation> px:css-speech-clean </p:documentation> </p:import> <p:import href="dtbook-validator.check-images.xpl"> <p:documentation> pxi:dtbook-validator.check-images </p:documentation> </p:import> <p:import href="dtbook-validator.select-schema.xpl"> <p:documentation> px:dtbook-validator.select-schema </p:documentation> </p:import> <p:variable name="base-uri" select="/*/d:file[@media-type='application/x-dtbook+xml']/resolve-uri(@href,base-uri(.))"/> <px:fileset-rebase> <p:with-option name="new-base" select="$base-uri"/> </px:fileset-rebase> <px:fileset-filter media-types="application/x-dtbook+xml"/> <px:check-files-wellformed px:message="Checking that DTBook document exists and is well-formed" name="check-dtbook-wellformed"> <p:input port="source.in-memory"> <p:pipe step="main" port="source.in-memory"/> </p:input> </px:check-files-wellformed> <p:identity> <p:input port="source"> <p:pipe step="check-dtbook-wellformed" port="validation-status"/> </p:input> </p:identity> <p:choose name="if-dtbook-wellformed"> <p:when test="d:validation-status/@result = 'ok'"> <p:output port="result"> <p:pipe step="load-dtbook-doc" port="result"/> </p:output> <p:output port="xml-report" primary="true"/> <px:fileset-load media-types="application/x-dtbook+xml" name="load-dtbook-doc"> <p:input port="fileset"> <p:pipe step="main" port="source.fileset"/> </p:input> <p:input port="in-memory"> <p:pipe step="main" port="source.in-memory"/> <p:pipe step="check-dtbook-wellformed" port="result.in-memory"/> </p:input> </px:fileset-load> <p:choose> <p:when test="$allow-aural-css-attributes"> <px:css-speech-clean> <p:documentation>Remove aural CSS attributes before validation</p:documentation> </px:css-speech-clean> </p:when> <p:otherwise> <p:identity/> </p:otherwise> </p:choose> <p:identity name="wellformed-dtbook"/> <p:group> <p:output port="xml-report" primary="true"/> <p:variable name="dtbook-version" select="*/@version"/> <p:variable name="filename" select="tokenize($base-uri, '/')[last()]"/> <p:variable name="mathml" select="if (count(//m:math) > 0) then 'mathml' else ''"/> <p:variable name="document-type" select="if (count(//m:math) > 0) then concat('DTBook ', $dtbook-version, ' with MathML ', $mathml-version) else concat('DTBook ', $dtbook-version)"/> <px:assert error-code="pe:DTB001" message="DTBook is missing required 'version' attribute"> <p:with-option name="test" select="exists(*/@version)"/> </px:assert> <px:assert error-code="pe:DTB001" message="DTBook version must be one of '2005-1', '2005-2', '2005-3' or '1.1.0', but got '$1'"> <p:with-option name="test" select="$dtbook-version=('2005-1','2005-2','2005-3','1.1.0')"/> <p:with-option name="param1" select="$dtbook-version"/> </px:assert> <p:identity px:message="Validating document: {$base-uri}"/> <px:dtbook-validator.select-schema name="select-rng-schema"> <p:with-option name="dtbook-version" select="$dtbook-version"/> <p:with-option name="mathml-version" select="$mathml-version"/> </px:dtbook-validator.select-schema> <p:sink/> <p:group name="validate-against-relaxng"> <p:output port="result" primary="true"/> <l:relax-ng-report name="run-relaxng-validation" assert-valid="false"> <p:input port="schema"> <p:pipe port="result" step="select-rng-schema"/> </p:input> <p:input port="source"> <p:pipe step="wellformed-dtbook" port="result"/> </p:input> </l:relax-ng-report> <p:sink/> <p:count limit="1"> <p:documentation>RelaxNG validation doesn't always produce a report, so this serves as a test to see if there was a document produced.</p:documentation> <p:input port="source"> <p:pipe port="report" step="run-relaxng-validation"/> </p:input> </p:count> <p:choose> <p:when test="/c:result=0"> <p:identity/> </p:when> <p:when test="$report-method=('log','error')"> <px:report-errors> <p:input port="report"> <p:pipe step="run-relaxng-validation" port="report"/> </p:input> <p:with-option name="method" select="$report-method"/> </px:report-errors> </p:when> <p:otherwise> <p:identity/> </p:otherwise> </p:choose> <p:choose name="get-relaxng-report"> <p:when test="/c:result=0"> <p:sink/> <p:identity> <p:input port="source"> <p:inline><c:errors/></p:inline> </p:input> </p:identity> </p:when> <p:otherwise> <p:sink/> <p:identity> <p:input port="source"> <p:pipe port="report" step="run-relaxng-validation"/> </p:input> </p:identity> </p:otherwise> </p:choose> </p:group> <p:sink/> <p:group name="validate-against-schematron"> <p:output port="report" sequence="true"/> <p:choose> <p:when test="$skip-schematron"> <p:output port="report" sequence="true"/> <p:identity> <p:input port="source"> <p:empty/> </p:input> </p:identity> </p:when> <p:otherwise> <p:output port="report" sequence="true"/> <p:choose name="choose-schematron"> <p:when test="$nimas"> <p:output port="result"/> <p:identity name="use-nimas-schematron"> <p:input port="source"> <p:document href="http://www.daisy.org/pipeline/modules/dtbook-utils/schema/dtbook.mathml.nimas.sch"/> </p:input> </p:identity> </p:when> <p:otherwise> <p:output port="result"/> <p:identity name="use-default-schematron"> <p:input port="source"> <p:document href="http://www.daisy.org/pipeline/modules/dtbook-utils/schema/dtbook.mathml.sch"/> </p:input> </p:identity> </p:otherwise> </p:choose> <p:sink/> <p:validate-with-schematron assert-valid="false" name="run-schematron-validation"> <p:input port="schema"> <p:pipe port="result" step="choose-schematron"/> </p:input> <p:input port="source"> <p:pipe step="wellformed-dtbook" port="result"/> </p:input> <p:input port="parameters"> <p:empty/> </p:input> </p:validate-with-schematron> <p:sink/> <p:identity> <p:input port="source"> <p:pipe step="run-schematron-validation" port="report"/> </p:input> </p:identity> <p:choose> <p:xpath-context> <p:empty/> </p:xpath-context> <p:when test="$report-method=('log','error')"> <p:variable name="errors" select="collection()//(svrl:failed-assert|svrl:successful-report)"/> <p:choose> <p:xpath-context> <p:empty/> </p:xpath-context> <p:when test="count($errors)=0"> <p:identity/> </p:when> <p:otherwise> <p:sink/> <p:xslt template-name="main" name="errors"> <p:input port="stylesheet"> <p:inline> <xsl:stylesheet version="2.0" xpath-default-namespace="http://purl.oclc.org/dsdl/svrl"> <xsl:param name="errors" as="element()*"/> <xsl:template name="main"> <c:errors> <xsl:for-each select="$errors"> <c:error> <xsl:sequence select="normalize-space(string(text))"/> </c:error> </xsl:for-each> </c:errors> </xsl:template> </xsl:stylesheet> </p:inline> </p:input> <p:with-param port="parameters" name="errors" select="$errors"/> <p:input port="source"> <p:empty/> </p:input> </p:xslt> <px:report-errors> <p:input port="report"> <p:pipe step="errors" port="result"/> </p:input> <p:with-option name="method" select="$report-method"/> </px:report-errors> </p:otherwise> </p:choose> </p:when> <p:otherwise> <p:identity/> </p:otherwise> </p:choose> </p:otherwise> </p:choose> </p:group> <p:sink/> <p:group name="check-images-exist"> <p:output port="result"/> <p:choose> <p:when test="$check-images"> <pxi:dtbook-validator.check-images name="run-images-check"> <p:input port="source.fileset"> <p:pipe step="load-dtbook-doc" port="unfiltered.fileset"/> </p:input> <p:input port="source.in-memory"> <p:pipe step="load-dtbook-doc" port="unfiltered.in-memory"/> </p:input> </pxi:dtbook-validator.check-images> <p:choose> <p:when test="$report-method=('log','error')"> <p:xslt name="errors"> <p:input port="stylesheet"> <p:inline> <xsl:stylesheet version="2.0" xpath-default-namespace="http://www.daisy.org/ns/pipeline/data"> <xsl:template match="/*"> <c:errors> <xsl:for-each select="error"> <c:error> <xsl:value-of select="normalize-space(string(desc))"/> <xsl:text>: </xsl:text> <xsl:value-of select="normalize-space(string(file))"/> </c:error> </xsl:for-each> </c:errors> </xsl:template> </xsl:stylesheet> </p:inline> </p:input> <p:input port="parameters"> <p:empty/> </p:input> </p:xslt> <p:sink/> <px:report-errors> <p:input port="source"> <p:pipe step="run-images-check" port="result"/> </p:input> <p:input port="report"> <p:pipe step="errors" port="result"/> </p:input> <p:with-option name="method" select="$report-method"/> </px:report-errors> </p:when> <p:otherwise> <p:identity/> </p:otherwise> </p:choose> </p:when> <p:otherwise> <p:identity> <p:input port="source"> <p:inline><d:errors/></p:inline> </p:input> </p:identity> </p:otherwise> </p:choose> </p:group> <p:sink/> <px:combine-validation-reports> <p:with-option name="document-type" select="$document-type"/> <p:with-option name="document-name" select="$filename"/> <p:with-option name="document-path" select="$base-uri"/> <p:with-option name="internal-info" select="$mathml"/> <p:input port="source"> <p:pipe port="result" step="validate-against-relaxng"/> <p:pipe port="report" step="validate-against-schematron"/> <p:pipe port="result" step="check-images-exist"/> </p:input> </px:combine-validation-reports> </p:group> </p:when> <p:otherwise> <p:output port="result"> <p:inline><tmp:error/></p:inline> </p:output> <p:output port="xml-report" primary="true"/> <p:identity> <p:input port="source"> <p:pipe step="check-dtbook-wellformed" port="report"/> </p:input> </p:identity> <p:choose> <p:when test="$report-method=('log','error')"> <p:xslt name="errors"> <p:input port="stylesheet"> <p:inline> <xsl:stylesheet version="2.0" xpath-default-namespace="http://www.daisy.org/ns/pipeline/data"> <xsl:template match="/*"> <c:errors> <xsl:for-each select="error"> <c:error> <xsl:value-of select="normalize-space(string(desc))"/> <xsl:text>: </xsl:text> <xsl:value-of select="normalize-space(string(file))"/> </c:error> </xsl:for-each> </c:errors> </xsl:template> </xsl:stylesheet> </p:inline> </p:input> <p:input port="parameters"> <p:empty/> </p:input> </p:xslt> <p:sink/> <px:report-errors> <p:input port="source"> <p:pipe step="check-dtbook-wellformed" port="report"/> </p:input> <p:input port="report"> <p:pipe step="errors" port="result"/> </p:input> <p:with-option name="method" select="$report-method"/> </px:report-errors> </p:when> <p:otherwise> <p:identity/> </p:otherwise> </p:choose> <px:message message="DTBook document is missing or not well-formed"/> <p:identity name="check-dtbook-wellformed-report"/> <p:sink/> <px:combine-validation-reports> <p:with-option name="document-name" select="tokenize($base-uri, '/')[last()]"/> <p:with-option name="document-type" select="'N/A'"/> <p:with-option name="document-path" select="$base-uri"/> <p:input port="source"> <p:pipe step="check-dtbook-wellformed-report" port="result"/> </p:input> </px:combine-validation-reports> </p:otherwise> </p:choose> <px:validation-status name="validation-status"/> <p:sink/> <px:validation-report-to-html name="html-report"> <p:input port="source"> <p:pipe step="if-dtbook-wellformed" port="xml-report"/> </p:input> </px:validation-report-to-html> <p:sink/> </p:declare-step>