Compare commits

..

No commits in common. "gh-pages" and "main" have entirely different histories.

82 changed files with 1685 additions and 1128 deletions

12
.classpath Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="lib/BaseX945.jar"/>
<classpathentry kind="lib" path="src/main/content/thumbnailator-0.4.13.jar"/>
<classpathentry kind="output" path="build/classes"/>
</classpath>

10
.drone.yml Normal file
View file

@ -0,0 +1,10 @@
kind: pipeline
type: docker
name: default
steps:
- name: test
image: golang
commands:
- go build
- go test

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build/

29
.project Normal file
View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ex-thumbnailator</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,12 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="java" version="1.7"/>
</faceted-project>

192
LICENSE Normal file
View file

@ -0,0 +1,192 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2016 andy bunce
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

10
catalog.xml Normal file
View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE catalog PUBLIC "-//OASIS//DTD XML Catalogs V1.1//EN" "http://www.oasis-open.org/committees/entity/release/1.1/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<!-- catalog entry for all notes -->
<rewriteURI
uriStartString="expkg-zone58:image.thumbnailator/schema/"
rewritePrefix="./src/content/"/>
</catalog>

194
dist/doc/thumbnailator.xqm.xml vendored Normal file
View file

@ -0,0 +1,194 @@
<xqdoc:xqdoc xmlns:xqdoc="http://www.xqdoc.org/1.0">
<xqdoc:control>
<xqdoc:date>2021-02-16T23:01:20.669Z</xqdoc:date>
<xqdoc:version>1.1</xqdoc:version>
</xqdoc:control>
<xqdoc:module type="library">
<xqdoc:uri>expkg-zone58:image.thumbnailator</xqdoc:uri>
<xqdoc:name>thumbnailator.xqm</xqdoc:name>
<xqdoc:comment>
<xqdoc:description>Generate image thumbnails using the thumbnailator library.</xqdoc:description>
<xqdoc:see>https://github.com/coobird/thumbnailator</xqdoc:see>
<xqdoc:author>andy bunce</xqdoc:author>
<xqdoc:version>0.6</xqdoc:version>
</xqdoc:comment>
</xqdoc:module>
<xqdoc:imports>
<xqdoc:import type="library">
<xqdoc:uri>org.expkgzone58.image.Thumbs</xqdoc:uri>
</xqdoc:import>
</xqdoc:imports>
<xqdoc:namespaces>
<xqdoc:namespace prefix="thumbnails" uri="expkg-zone58:image.thumbnailator"/>
<xqdoc:namespace prefix="Thumbs" uri="org.expkgzone58.image.Thumbs"/>
</xqdoc:namespaces>
<xqdoc:variables/>
<xqdoc:functions>
<xqdoc:function arity="2">
<xqdoc:comment>
<xqdoc:description>generate scaled version of source image with maximum dimension of size</xqdoc:description>
<xqdoc:param>$source base64Binary (streamed?) e.g from `fetch:binary`</xqdoc:param>
<xqdoc:return>base64Binary for thumbnail</xqdoc:return>
</xqdoc:comment>
<xqdoc:name>thumbnails:size</xqdoc:name>
<xqdoc:signature>declare function thumbnails:size($source as xs:base64Binary , $size as xs:integer) as xs:base64Binary</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>source</xqdoc:name>
<xqdoc:type>xs:base64Binary</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>size</xqdoc:name>
<xqdoc:type>xs:integer</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type>xs:base64Binary</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
<xqdoc:function arity="3">
<xqdoc:comment>
<xqdoc:description>generate scaled version of source image with maximum dimension of size</xqdoc:description>
<xqdoc:param>$source base64Binary (streamed?) e.g from `fetch:binary`</xqdoc:param>
<xqdoc:return>base64Binary for thumbnail</xqdoc:return>
</xqdoc:comment>
<xqdoc:name>thumbnails:size</xqdoc:name>
<xqdoc:signature>declare function thumbnails:size($source as xs:base64Binary , $width as xs:integer , $height as xs:integer) as xs:base64Binary</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>source</xqdoc:name>
<xqdoc:type>xs:base64Binary</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>width</xqdoc:name>
<xqdoc:type>xs:integer</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>height</xqdoc:name>
<xqdoc:type>xs:integer</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type>xs:base64Binary</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
<xqdoc:function arity="2">
<xqdoc:comment>
<xqdoc:description>generate scaled version of source image at given factors 0-1</xqdoc:description>
<xqdoc:param>$source base64Binary (streamed?) e.g from `fetch:binary`</xqdoc:param>
<xqdoc:return>the thumbnail</xqdoc:return>
</xqdoc:comment>
<xqdoc:name>thumbnails:scale</xqdoc:name>
<xqdoc:signature>declare function thumbnails:scale($source as xs:base64Binary , $scale as xs:double) as xs:base64Binary</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>source</xqdoc:name>
<xqdoc:type>xs:base64Binary</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>scale</xqdoc:name>
<xqdoc:type>xs:double</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type>xs:base64Binary</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
<xqdoc:function arity="3">
<xqdoc:comment>
<xqdoc:description>generate scaled version of source image at given factors 0-1</xqdoc:description>
<xqdoc:param>$source base64Binary (streamed?) e.g from `fetch:binary`</xqdoc:param>
<xqdoc:return>the thumbnail</xqdoc:return>
</xqdoc:comment>
<xqdoc:name>thumbnails:scale</xqdoc:name>
<xqdoc:signature>declare function thumbnails:scale($source as xs:base64Binary , $xscale as xs:double , $yscale as xs:double) as xs:base64Binary</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>source</xqdoc:name>
<xqdoc:type>xs:base64Binary</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>xscale</xqdoc:name>
<xqdoc:type>xs:double</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>yscale</xqdoc:name>
<xqdoc:type>xs:double</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type>xs:base64Binary</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
<xqdoc:function arity="2">
<xqdoc:comment>
<xqdoc:description>generate thumbnail using parameters specified via XML</xqdoc:description>
<xqdoc:param>$source base64Binary (streamed?) e.g from `fetch:binary`</xqdoc:param>
<xqdoc:param>$task XML parameters &lt;task&gt;&lt;size width="100" ..</xqdoc:param>
<xqdoc:return>the thumbnail</xqdoc:return>
</xqdoc:comment>
<xqdoc:name>thumbnails:task</xqdoc:name>
<xqdoc:signature>declare function thumbnails:task($source as xs:base64Binary , $task as element(thumbnail)) as xs:base64Binary</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>source</xqdoc:name>
<xqdoc:type>xs:base64Binary</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>task</xqdoc:name>
<xqdoc:type>element(thumbnail)</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type>xs:base64Binary</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
<xqdoc:function arity="1">
<xqdoc:comment>
<xqdoc:description>validate task thumbnail XML against schema</xqdoc:description>
<xqdoc:param>$src XML parameters &lt;thumbnail&gt;&lt;size width="100" ..</xqdoc:param>
<xqdoc:return>empty-sequence or error</xqdoc:return>
<xqdoc:error>BXVA0001: the validation fails.</xqdoc:error>
<xqdoc:error>BXVA0002: the validation process cannot be started.</xqdoc:error>
<xqdoc:error>BXVA0003: no XML Schema validator is available.</xqdoc:error>
<xqdoc:error>BXVA0004: no validator is found for the specified version.</xqdoc:error>
</xqdoc:comment>
<xqdoc:name>thumbnails:validate</xqdoc:name>
<xqdoc:signature>declare function thumbnails:validate($src as item()*) as empty-sequence()</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>src</xqdoc:name>
<xqdoc:type occurrence="*">item()</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type>empty-sequence()</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
<xqdoc:function arity="1">
<xqdoc:comment>
<xqdoc:description>validate task thumbnail XML against schema</xqdoc:description>
<xqdoc:param>$src XML parameters &lt;thumbnail&gt;&lt;size width="100" ..</xqdoc:param>
<xqdoc:return>validation report</xqdoc:return>
</xqdoc:comment>
<xqdoc:name>thumbnails:validation-report</xqdoc:name>
<xqdoc:signature>declare function thumbnails:validation-report($src as item()*) as element(report)</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>src</xqdoc:name>
<xqdoc:type occurrence="*">item()</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type>element(report)</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
<xqdoc:function arity="0">
<xqdoc:name>thumbnails:schema-uri</xqdoc:name>
<xqdoc:signature>declare function thumbnails:schema-uri() as xs:anyURI</xqdoc:signature>
<xqdoc:return>
<xqdoc:type>xs:anyURI</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
</xqdoc:functions>
</xqdoc:xqdoc>

BIN
dist/thumbnailator-7.0.1.xar vendored Normal file

Binary file not shown.

BIN
dist/thumbnailator-8.0.1.xar vendored Normal file

Binary file not shown.

BIN
dist/thumbnailator.zar vendored

Binary file not shown.

108
dist/xqdoc.xml vendored
View file

@ -1,108 +0,0 @@
<xqdoc:xqdoc xmlns:xqdoc="http://www.xqdoc.org/1.0">
<xqdoc:control>
<xqdoc:date>2013-08-04T23:31:57.796+01:00</xqdoc:date>
<xqdoc:version>1.1</xqdoc:version>
</xqdoc:control>
<xqdoc:module type="library">
<xqdoc:uri>apb.image.thumbnailator</xqdoc:uri>
<xqdoc:name>thumbnailator.xqm</xqdoc:name>
<xqdoc:comment>
<xqdoc:description>Generate thumbnails using http://code.google.com/p/thumbnailator/</xqdoc:description>
<xqdoc:author>andy bunce</xqdoc:author>
</xqdoc:comment>
</xqdoc:module>
<xqdoc:namespaces>
<xqdoc:namespace prefix="thumbnails" uri="apb.image.thumbnailator"/>
<xqdoc:namespace prefix="File" uri="java:java.io.File"/>
<xqdoc:namespace prefix="Thumbnailator" uri="java:net.coobird.thumbnailator.Thumbnailator"/>
<xqdoc:namespace prefix="BufferedImageBuilder" uri="java:net.coobird.thumbnailator.builders.BufferedImageBuilder"/>
<xqdoc:namespace prefix="Builder" uri="java:net.coobird.thumbnailator.Thumbnails$Builder"/>
</xqdoc:namespaces>
<xqdoc:imports/>
<xqdoc:variables/>
<xqdoc:functions>
<xqdoc:function arity="1">
<xqdoc:name>fromFilenames</xqdoc:name>
<xqdoc:signature>declare function fromFilenames($file as xs:string)</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>file</xqdoc:name>
<xqdoc:type>xs:string</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type occurrence="*">item()</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
<xqdoc:function arity="4">
<xqdoc:name>sourceRegion</xqdoc:name>
<xqdoc:signature>declare function sourceRegion($x as xs:integer, $y as xs:integer, $width as xs:integer, $height as xs:integer)</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>x</xqdoc:name>
<xqdoc:type>xs:integer</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>y</xqdoc:name>
<xqdoc:type>xs:integer</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>width</xqdoc:name>
<xqdoc:type>xs:integer</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>height</xqdoc:name>
<xqdoc:type>xs:integer</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type occurrence="*">item()</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
<xqdoc:function arity="3">
<xqdoc:name>size</xqdoc:name>
<xqdoc:signature>declare function size($builder, $width as xs:int, $height as xs:int)</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>builder</xqdoc:name>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>width</xqdoc:name>
<xqdoc:type>xs:int</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>height</xqdoc:name>
<xqdoc:type>xs:int</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type occurrence="*">item()</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
<xqdoc:function arity="4">
<xqdoc:name>make</xqdoc:name>
<xqdoc:signature>declare function make($src as xs:string, $dest as xs:string, $width as xs:integer, $height as xs:integer)</xqdoc:signature>
<xqdoc:parameters>
<xqdoc:parameter>
<xqdoc:name>src</xqdoc:name>
<xqdoc:type>xs:string</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>dest</xqdoc:name>
<xqdoc:type>xs:string</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>width</xqdoc:name>
<xqdoc:type>xs:integer</xqdoc:type>
</xqdoc:parameter>
<xqdoc:parameter>
<xqdoc:name>height</xqdoc:name>
<xqdoc:type>xs:integer</xqdoc:type>
</xqdoc:parameter>
</xqdoc:parameters>
<xqdoc:return>
<xqdoc:type occurrence="*">item()</xqdoc:type>
</xqdoc:return>
</xqdoc:function>
</xqdoc:functions>
</xqdoc:xqdoc>

BIN
doc/constrain/A17057.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

View file

@ -0,0 +1,29 @@
(:~
:examples of constrain use
:)
import module namespace t="expkg-zone58:image.thumbnailator";
declare variable $file-base:=file:parent(static-base-uri());
declare variable $src:=file:resolve-path("A17057.jpg",$file-base);
declare function local:wi($data as xs:base64Binary,$filename as xs:string)
{
file:write-binary(file:resolve-path($filename,$file-base),$data)
};
declare function local:constrain($aspect as xs:boolean,$fit as xs:boolean,$exif as xs:boolean)
{
<thumbnail>
<size width="60" height="200"/>
<constrain aspect="{$aspect}" fit="{$fit}" exif="{$exif}"/>
</thumbnail>
};
let $s:=function($b){if($b) then ".+" else ".-"}
let $img:= fetch:binary($src)
let $ft:=(false(),true())
for $fit in $ft,$aspect in $ft,$exif in $ft
let $file:=("out.",
$s($aspect) , "aspect",
$s($fit), "fit",
$s($exif), "exif",
".jpg")=>string-join("")
let $task:=local:constrain($aspect,$fit,$exif)
return t:task($img,$task) => local:wi($file)

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
doc/filters-schema.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

32
doc/readme.md Normal file
View file

@ -0,0 +1,32 @@
# expkg-zone58:image.thumbnailator
The schema is [task.xsd](../src/main/content/task.xsd)
## thumbnail node
![root](thumbnail-schema.png "thumbnail node")
Either `size` or `scale` must be specified. Everything else is optional
`output` can be used to change the output image format.
```
<output format="gif"/>
```
## Filters
![filter definition](filters-schema.png "Available filters")
## Exif
Image handling is effected by the presence of the
[exif-orientation](http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/) tag.
In particular:
* `size` and `fit` are changed
* the `flip` filter is ignored
To prevent this set constrain @exif=false
```
<constrain exif="false"/>
```

BIN
doc/thumbnail-schema.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 735 B

View file

@ -1,76 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<link href='https://fonts.googleapis.com/css?family=Chivo:900' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/pygment_trac.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/print.css" media="print">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<title>Thumbnailator by expkg-zone58</title>
</head>
<body>
<div id="container">
<div class="inner">
<header>
<h1>Thumbnailator</h1>
<h2>An XQuery interface to the thumbnail generator library [thumbnailator](https://github.com/coobird/thumbnailator </h2>
</header>
<section id="downloads" class="clearfix">
<a href="https://github.com/expkg-zone58/ex-thumbnailator/zipball/master" id="download-zip" class="button"><span>Download .zip</span></a>
<a href="https://github.com/expkg-zone58/ex-thumbnailator/tarball/master" id="download-tar-gz" class="button"><span>Download .tar.gz</span></a>
<a href="https://github.com/expkg-zone58/ex-thumbnailator" id="view-on-github" class="button"><span>View on GitHub</span></a>
</section>
<hr>
<section id="main_content">
<h1>
<a id="installation" class="anchor" href="#installation" aria-hidden="true"><span class="octicon octicon-link"></span></a>Installation</h1>
<p>The library is packaged in the <a href="http://expath.org/spec/pkg">EXpath</a> xar format with
the thumbnailator jar included. It can be installed into the BaseX repository by
executing the command:</p>
<pre><code>repo:install('http://apb2006.github.io/thumbnailator/dist/thumbnailator.zar')
</code></pre>
<h1>
<a id="usage" class="anchor" href="#usage" aria-hidden="true"><span class="octicon octicon-link"></span></a>Usage</h1>
<pre><code>import module namespace t="apb.image.thumbnailator";
t:make("/tmp/pic.jpg","/tmp/small.jpg",120,120)
</code></pre>
<h1>
<a id="tests" class="anchor" href="#tests" aria-hidden="true"><span class="octicon octicon-link"></span></a>Tests</h1>
<p>The <code>test.xq</code> script uses the BaseX <a href="http://docs.basex.org/wiki/Unit_Module">Unit module</a></p>
</section>
<footer>
Thumbnailator is maintained by <a href="https://github.com/expkg-zone58">expkg-zone58</a><br>
This page was generated by <a href="https://pages.github.com">GitHub Pages</a>. Tactile theme by <a href="https://twitter.com/jasonlong">Jason Long</a>.
</footer>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-2241947-7");
pageTracker._trackPageview();
} catch(err) {}
</script>
</div>
</div>
</body>
</html>

View file

@ -1 +0,0 @@
console.log('This would be the main JS file.');

View file

@ -1,17 +0,0 @@
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i=0; i<metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
}
}
document.addEventListener("gesturestart", gestureStart, false);
}
function gestureStart() {
for (i=0; i<metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
}
}
}

BIN
lib/BaseX924.jar Normal file

Binary file not shown.

BIN
lib/BaseX945.jar Normal file

Binary file not shown.

16
makejar.jardesc Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?>
<jardesc>
<jar path="ex-thumbnailator/src/main/content/thumbhelper-8.0.0.jar"/>
<options buildIfNeeded="true" compress="true" descriptionLocation="/ex-thumbnailator/makejar.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
<selectedProjects/>
<manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
<sealing sealJar="false">
<packagesToSeal/>
<packagesToUnSeal/>
</sealing>
</manifest>
<selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false">
<javaElement handleIdentifier="=ex-thumbnailator/src\/java"/>
</selectedElements>
</jardesc>

71
package.xml Normal file
View file

@ -0,0 +1,71 @@
<!-- @see http://cxan.org/faq#add-pkg -->
<repo abbrev="ex-thumbnailator">
<pkg abbrev="ex-thumbnailator" id="https://github.com/expkg-zone58/ex-thumbnailator">
<name>https://github.com/expkg-zone58/ex-thumbnailator</name>
<abstract>Create a thumbnail from a file path.</abstract>
<author id="coobird">coobird</author>
<maintainer id="abunce">Andy Bunce</maintainer>
<home>https://github.com/coobird/thumbnailator</home>
<category id="libs">Library</category>
<tag>image</tag>
<tag>resize</tag>
<tag>graphic</tag>
<version num="4.1.4">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="4.1.5">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.0">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.1">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.2">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.3">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.4">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.5">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.7">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.8">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.9">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.10">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="5.0.11">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="6.0.0">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="6.0.1">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="6.0.2">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="7.0.0">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="7.0.1">
<!-- generated: {fn:current-dateTime()} -->
</version>
<version num="8.0.1">
<!-- generated: {fn:current-dateTime()} -->
</version>
</pkg>
</repo>

View file

@ -1 +0,0 @@
{"name":"Thumbnailator","tagline":"An XQuery interface to the thumbnail generator library [thumbnailator](https://github.com/coobird/thumbnailator ","body":"# Installation\r\nThe library is packaged in the [EXpath](http://expath.org/spec/pkg) xar format with \r\nthe thumbnailator jar included. It can be installed into the BaseX repository by \r\nexecuting the command:\r\n````\r\nrepo:install('http://apb2006.github.io/thumbnailator/dist/thumbnailator.zar')\r\n````\r\n# Usage\r\n````\r\nimport module namespace t=\"apb.image.thumbnailator\";\r\nt:make(\"/tmp/pic.jpg\",\"/tmp/small.jpg\",120,120)\r\n````\r\n# Tests\r\nThe `test.xq` script uses the BaseX [Unit module](http://docs.basex.org/wiki/Unit_Module)\r\n","google":"UA-2241947-7","note":"Don't delete this file! It's used internally to help with page regeneration."}

71
readme.md Normal file
View file

@ -0,0 +1,71 @@
# expkg-zone58:image.thumbnailator
An XQuery interface to the image thumbnail generator library
[thumbnailator](https://github.com/coobird/thumbnailator) for BaseX 9.4.5+.
Features size, scale, caption, rotate, flip, colorize, watermark. More details at [doc](doc/readme.md)
## Versions
* `ex-thumbnailator` 8 requires Basex 9.4.5+
* uses `thumbnailator` 4.13
## Usage
Images are input and output as `xs:base64Binary` items. Inputs typically come from `fetch:binary`
which allows for file and http sources. Outputs may be saved with `file:write-binary` or `db:store`
### Simple
Create a thumbnail of given size
```xquery
import module namespace t="expkg-zone58:image.thumbnailator";
fetch:binary("http://images.metmuseum.org/CRDImages/ep/original/DT46.jpg")
=>t:size(80)
```
or scale to a fraction of the original
```xquery
import module namespace t="expkg-zone58:image.thumbnailator";
fetch:binary("file:///Z:/recordings/radio/Book%20of%20the%20Week/image.png")
=>t:scale(0.25)
```
### Tasks
This function takes an XML description of the operations to apply to generate the thumbnail.
```xquery
import module namespace t="expkg-zone58:image.thumbnailator";
declare variable $watermark:="C:\Users\andy\git\ex-thumbnailator\src\test\resources\icon.jpg";
let $task:=
<thumbnail>
<size width="100" height="100"/>
<filters>
<colorize color="green" alpha=".5"/>
<caption position="CENTER">Some Text here</caption>
<rotate angle="15"/>
<canvas height="500" width="500" position="TOP_LEFT" color="black"/>
<watermark src="{$watermark}" alpha=".5" position="TOP_LEFT"/>
</filters>
</thumbnail>
return fetch:binary("http://images.metmuseum.org/CRDImages/ep/original/DT46.jpg")
=>t:task($task)
```
The schema for this XML is available at [task.xsd](./src/main/content/task.xsd)
## Installation
The library is packaged in the [EXpath](http://expath.org/spec/pkg) xar format with
the thumbnailator jar included. See [releases](../../releases) for installation instructions.
# Tests
`test.xqm` script uses the BaseX [Unit module](http://docs.basex.org/wiki/Unit_Module)
## License
* ex-thumbnailator Copyright (c) 2013-2017, Andy Bunce. (Apache 2 License).
* thumbnailator Copyright (c) Chris Kroells (MIT License).

View file

@ -0,0 +1,266 @@
package org.expkgzone58.image;
import static org.basex.query.QueryError.IOERR_X;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import org.basex.data.Data;
import org.basex.io.IOContent;
import org.basex.query.QueryException;
import org.basex.query.QueryModule;
//import org.basex.query.func.fn.FnTrace;
import org.basex.query.value.item.B64Lazy;
import org.basex.query.value.node.ANode;
import org.basex.util.Token;
import net.coobird.thumbnailator.ThumbnailParameter;
import net.coobird.thumbnailator.Thumbnailator;
import net.coobird.thumbnailator.builders.ThumbnailParameterBuilder;
import net.coobird.thumbnailator.filters.Canvas;
import net.coobird.thumbnailator.filters.Caption;
import net.coobird.thumbnailator.filters.Colorize;
import net.coobird.thumbnailator.filters.Flip;
import net.coobird.thumbnailator.filters.ImageFilter;
import net.coobird.thumbnailator.filters.Pipeline;
import net.coobird.thumbnailator.filters.Rotation;
import net.coobird.thumbnailator.filters.Watermark;
import net.coobird.thumbnailator.geometry.AbsoluteSize;
import net.coobird.thumbnailator.geometry.Position;
import net.coobird.thumbnailator.geometry.Positions;
import net.coobird.thumbnailator.geometry.Region;
import net.coobird.thumbnailator.tasks.StreamThumbnailTask;
/*
* BaseX Thumbnailator interface
* @author andy bunce
* @copyright Quodatum Ltd
* @date 2017
* @licence Apache 2
*/
public class Thumbs extends QueryModule{
public B64Lazy size(final B64Lazy inputStream, final int width, final int height)
throws IOException, QueryException {
ByteArrayInputStream is = new ByteArrayInputStream(inputStream.binary(null));
ByteArrayOutputStream os = new ByteArrayOutputStream();
ThumbnailParameterBuilder builder = new ThumbnailParameterBuilder();
builder.size(width, height);
StreamThumbnailTask task = new StreamThumbnailTask(builder.build(), is, os);
Thumbnailator.createThumbnail(task);
return new B64Lazy(new IOContent(os.toByteArray()), IOERR_X);
}
public B64Lazy scale(final B64Lazy inputStream,
final double xscale, final double yscale)
throws IOException, QueryException {
ByteArrayInputStream is = new ByteArrayInputStream(inputStream.binary(null));
ByteArrayOutputStream os = new ByteArrayOutputStream();
ThumbnailParameterBuilder builder = new ThumbnailParameterBuilder();
builder.scale(xscale, yscale);
StreamThumbnailTask task = new StreamThumbnailTask(builder.build(), is, os);
Thumbnailator.createThumbnail(task);
return new B64Lazy(new IOContent(os.toByteArray()), IOERR_X);
}
public B64Lazy task(final B64Lazy inputStream, final ANode thumbnail)
throws IOException, QueryException {
ByteArrayInputStream is = new ByteArrayInputStream(inputStream.binary(null));
ByteArrayOutputStream os = new ByteArrayOutputStream();
ThumbnailParameter param = fromNode(thumbnail);
StreamThumbnailTask task = new StreamThumbnailTask(param, is, os);
Thumbnailator.createThumbnail(task);
return new B64Lazy(new IOContent(os.toByteArray()), IOERR_X);
}
// build parameters from XML
ThumbnailParameter fromNode(final ANode node) throws QueryException, IOException {
ThumbnailParameterBuilder builder = new ThumbnailParameterBuilder();
for(final ANode element : node.childIter()) {
if (element.kind() == Data.ELEM) {
String name = Token.string(element.name());
// FnTrace.trace(name.getBytes(), "element: ".getBytes(), queryContext);
switch (name) {
case "size":
size(builder, element);
break;
case "scale":
scale(builder, element);
break;
case "region":
region(builder, element);
break;
case "constrain":
constrain(builder, element);
break;
case "filters":
List<ImageFilter> filters = filters(element);
builder.filters(filters);
break;
case "output":
String format = Utils.attrib(element, "format",
ThumbnailParameter.ORIGINAL_FORMAT);
builder.format(format);
break;
default:
break;
}
}
}
return builder.build();
}
void region(final ThumbnailParameterBuilder builder, final ANode node)
throws QueryException {
int width = Utils.attrib(node,"width", 80);
int height = Utils.attrib(node,"height", 80);
Dimension d = new Dimension(width, height);
Position pos = Utils.position(node, "position", Positions.CENTER);
Region r = new Region(pos, new AbsoluteSize(d));
builder.region(r);
}
void constrain(final ThumbnailParameterBuilder builder, final ANode node)
throws QueryException {
boolean aspect = Utils.attrib(node, "aspect", true);
builder.keepAspectRatio(aspect);
// FnTrace.trace(Boolean.toString(aspect).getBytes(), "constrain: ".getBytes(), queryContext);
boolean exif = Utils.attrib(node, "exif", true);
builder.useExifOrientation(exif);
boolean fit = Utils.attrib(node, "fit", true);
builder.fitWithinDimensions(fit);
}
void size(final ThumbnailParameterBuilder builder, final ANode node)
throws QueryException {
int width = Utils.attrib(node, "width", 80);
int height = Utils.attrib(node, "height", 80);
builder.size(width, height);
}
void scale(final ThumbnailParameterBuilder builder, final ANode node)
throws QueryException {
double x = Utils.attrib(node, "x", 0.5f);
double y = Utils.attrib(node, "y", 0.5f);
builder.scale(x, y);
}
List<ImageFilter> filters(final ANode filters) throws QueryException, IOException {
Pipeline pipeline = new Pipeline();
for(final ANode node : filters.childIter()) {
if (node.kind() == Data.ELEM) {
switch (Token.string(node.name())) {
case "canvas": // @width @height @color @position
canvas(pipeline, node);
break;
case "caption": //@color @position text()
caption(pipeline, node);
break;
case "colorize": //@color @alpha
colorize(pipeline, node);
break;
case "flip": //@axis
flip(pipeline, node);
break;
case "rotate": //@angle
rotate(pipeline, node);
break;
case "watermark": //@src @alpha @position
watermark(pipeline, node);
break;
default:
break;
}
}
}
return pipeline.getFilters();
}
private void watermark(final Pipeline pipeline, final ANode node)
throws IOException, QueryException {
ImageFilter filter;
Position pos;
String src = Utils.attrib(node, "src", "");
pos = Utils.position(node, "position", Positions.BOTTOM_RIGHT);
BufferedImage watermarkImg = ImageIO.read(new File(src));
filter = new Watermark(pos, watermarkImg, Utils.attrib(node, "alpha", 0.5f));
pipeline.add(filter);
}
private void rotate(final Pipeline pipeline, final ANode node)
throws QueryException {
double angle = (double) Utils.attrib(node, "angle", 0);
pipeline.add(Rotation.newRotator(angle));
}
private void flip(final Pipeline pipeline, final ANode node) throws QueryException {
ImageFilter filter;
String axis = Utils.attrib(node, "axis", "vertical");
// FnTrace.trace(axis.getBytes(), "FLIP: ".getBytes(), queryContext);
filter = axis.equalsIgnoreCase("vertical") ? Flip.VERTICAL : Flip.HORIZONTAL;
pipeline.add(filter);
}
private void colorize(final Pipeline pipeline, final ANode node) throws QueryException {
ImageFilter filter;
String color;
color = Utils.attrib(node, "color", "black");
filter = new Colorize(Utils.stringToColor(color),
Utils.attrib(node, "alpha", 0.0f));
pipeline.add(filter);
}
private void canvas(final Pipeline pipeline, final ANode node) throws QueryException {
ImageFilter filter;
String color;
Position pos;
int width = Utils.attrib(node, "width", 80);
int height = Utils.attrib(node, "height", 80);
color = Utils.attrib(node, "color", "black");
pos = Utils.position(node, "position", Positions.CENTER);
filter = new Canvas(width, height, pos, false, Utils.stringToColor(color));
pipeline.add(filter);
}
private void caption(final Pipeline pipeline, final ANode node) throws QueryException {
ImageFilter filter;
String color;
Position pos;
String text = Token.string(node.string());
color = Utils.attrib(node, "color", "black");
pos = Utils.position(node, "position", Positions.TOP_CENTER);
String fontName = Utils.attrib(node, "font", "SansSerif");
int size = Utils.attrib(node, "size", 14);
int insets = Utils.attrib(node, "insets", 0);
Font font = new Font(fontName, Font.PLAIN, size);
filter = new Caption(text, font , Utils.stringToColor(color),
pos, insets);
pipeline.add(filter);
}
}

View file

@ -0,0 +1,73 @@
package org.expkgzone58.image;
import java.awt.Color;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import org.basex.query.QueryException;
import org.basex.query.value.item.Bln;
import org.basex.query.value.item.Dbl;
import org.basex.query.value.item.Int;
import org.basex.query.value.item.Item;
import org.basex.query.value.node.ANode;
import org.basex.util.Token;
import net.coobird.thumbnailator.geometry.Position;
import net.coobird.thumbnailator.geometry.Positions;
public final class Utils {
private Utils() {
};
// get value from attribute with default
public static String attrib(final ANode element, final String name, final String def)
throws QueryException {
byte[] at = element.attribute(name.getBytes(StandardCharsets.UTF_8));
return (at == null) ? def : Token.string(at);
}
public static float attrib(final ANode element, final String name, final float def)
throws QueryException {
byte[] at = element.attribute(name.getBytes(StandardCharsets.UTF_8));
return (at == null) ? def : (float) Dbl.parse(at, null);
}
public static int attrib(final ANode element, final String name, final int def)
throws QueryException {
byte[] at = element.attribute(name.getBytes(StandardCharsets.UTF_8));
return (at == null) ? def : Token.toInt(at);
}
public static boolean attrib(final ANode element, final String name, final boolean def)
throws QueryException {
byte[] at = element.attribute(name.getBytes(StandardCharsets.UTF_8));
return (boolean) ((at == null) ? def : Bln.parse(at));
}
// e.g. TOP_LEFT
public static Position position(final ANode element, final String name, final Position def) {
byte[] at = element.attribute(name.getBytes(StandardCharsets.UTF_8));
return (at == null) ? def : Positions.valueOf(Token.string(at));
}
public static Color stringToColor(final String value) {
if (value == null) {
return Color.black;
}
try {
// get color by hex or octal value
return Color.decode(value);
} catch (NumberFormatException nfe) {
// if we can't decode lets try to get it by name
try {
// try to get a color by name using reflection
final Field f = Color.class.getField(value);
return (Color) f.get(null);
} catch (Exception ce) {
// if we can't get any color return black
return Color.black;
}
}
}
}

5
src/main/basex.xml Normal file
View file

@ -0,0 +1,5 @@
<package xmlns="http://www.basex.org/modules/pkg">
<jar>thumbhelper-8.0.0.jar</jar>
<jar>thumbnailator-0.4.13.jar</jar>
<class>org.expkgzone58.image.Thumbs</class>
</package>

262
src/main/content/task.xsd Normal file
View file

@ -0,0 +1,262 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- thumbnail schema apb apr 2017 -->
<xs:element name="thumbnail">
<xs:annotation>
<xs:documentation>Root container</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element ref="size" />
<xs:element ref="scale" />
</xs:choice>
<xs:element ref="region" minOccurs="0" />
<xs:element ref="constrain" minOccurs="0" />
<xs:element ref="filters" minOccurs="0" />
<xs:element ref="output" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="size">
<xs:annotation>
<xs:documentation>size of thumbnail to create</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="width" type="PxType" />
<xs:attribute name="height" type="PxType" />
</xs:complexType>
</xs:element>
<xs:element name="scale">
<xs:annotation>
<xs:documentation>scale thumbnail from source size</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="x" type="ScaleType" />
<xs:attribute name="y" type="ScaleType" />
</xs:complexType>
</xs:element>
<xs:element name="region">
<xs:annotation>
<xs:documentation>region of source image to use for thumbnail.
default all
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="height" type="PxType" />
<xs:attribute name="width" type="PxType" />
<xs:attribute name="position" type="PositionType" />
</xs:complexType>
</xs:element>
<xs:element name="filters">
<xs:annotation>
<xs:documentation>contain for filters to be applied to thumbnail
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element ref="canvas" minOccurs="0" />
<xs:element ref="caption" minOccurs="0" />
<xs:element ref="colorize" minOccurs="0" />
<xs:element ref="flip" minOccurs="0" />
<xs:element ref="rotate" minOccurs="0" />
<xs:element ref="watermark" minOccurs="0" />
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="canvas">
<xs:annotation>
<xs:documentation>create a filled enclosing background for thumbnail
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="height" type="PxType" />
<xs:attribute name="width" type="PxType" />
<xs:attribute name="color" type="ColorType" />
<xs:attribute name="position" type="PositionType" />
</xs:complexType>
</xs:element>
<xs:element name="colorize">
<xs:annotation>
<xs:documentation>tint thumbnail</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="color" type="ColorType" />
<xs:attribute name="alpha" type="AlphaType" />
</xs:complexType>
</xs:element>
<xs:element name="caption">
<xs:annotation>
<xs:documentation>add text to thumbnail</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="size" type="xs:int" />
<xs:attribute name="font" type="xs:string" />
<xs:attribute name="color" type="ColorType" />
<xs:attribute name="position" type="PositionType" />
<xs:attribute name="insets"
type="xs:int">
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="flip">
<xs:annotation>
<xs:documentation>flip thumbnail horizontally or vertically.
**Ignored if exif-orientation is true **
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="axis" type="AxisType" />
</xs:complexType>
</xs:element>
<xs:element name="rotate">
<xs:annotation>
<xs:documentation>rotate the thumbnail</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="angle" type="xs:float" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="watermark">
<xs:annotation>
<xs:documentation>Add image to thumbnail as a watermark
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="src" type="xs:string" />
<xs:attribute name="position" type="PositionType" />
<xs:attribute name="alpha" type="AlphaType" />
</xs:complexType>
</xs:element>
<xs:simpleType name="AxisType">
<xs:annotation>
<xs:documentation>Axis of flip</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="horizontal" />
<xs:enumeration value="vertical" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PositionType">
<xs:annotation>
<xs:documentation>Region of image to use</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="TOP_LEFT" />
<xs:enumeration value="TOP_CENTER" />
<xs:enumeration value="TOP_RIGHT" />
<xs:enumeration value="MIDDLE_LEFT" />
<xs:enumeration value="CENTER" />
<xs:enumeration value="MIDDLE_RIGHT" />
<xs:enumeration value="BOTTOM_LEFT" />
<xs:enumeration value="BOTTOM_CENTER" />
<xs:enumeration value="BOTTOM_RIGHT" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PxType">
<xs:annotation>
<xs:documentation>A size in pixels</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:int">
<xs:minInclusive value="0"></xs:minInclusive>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ScaleType">
<xs:restriction base="xs:double">
<xs:minExclusive value="0"></xs:minExclusive>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AlphaType">
<xs:annotation>
<xs:documentation>Transparency alpha value</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:double">
<xs:minInclusive value="0"></xs:minInclusive>
<xs:maxInclusive value="1"></xs:maxInclusive>
</xs:restriction>
</xs:simpleType>
<xs:element name="constrain">
<xs:annotation>
<xs:documentation>constraints on thumbnail</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="exif" type="xs:boolean" default="true">
<xs:annotation>
<xs:documentation> true if the Exif metadata should be used to
determine the orientation of the thumbnail,
false otherwise.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="fit" type="xs:boolean" use="optional"
default="true">
<xs:annotation>
<xs:documentation>fit - true if the thumbnail should be sized to
fit within the specified dimensions,
if the thumbnail is going to
exceed those dimensions.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="aspect" type="xs:boolean" use="optional"
default="true">
<xs:annotation>
<xs:documentation>keep aspect ratio</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:simpleType name="ColorType">
<xs:annotation>
<xs:documentation>Java colour name e.g. "red"
or Color.decode(value)
decimal, octal, or hexidecimal integer e.g
"#FF0096"
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string"></xs:restriction>
</xs:simpleType>
<xs:element name="output" >
<xs:annotation>
<xs:documentation>Serialization details for output</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="format" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Output image format (JPEG, PNG, GIF, BMP and
WBMP). defaults to source format</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,94 @@
xquery version "3.1" encoding "UTF-8";
(:~ Generate image thumbnails using the thumbnailator library.
: @see https://github.com/coobird/thumbnailator
: @author andy bunce
: @version 0.6
:)
module namespace thumbnails = 'expkg-zone58:image.thumbnailator';
import module namespace Thumbs = "org.expkgzone58.image.Thumbs";
(:~
: generate scaled version of source image with maximum dimension of size
: @param $source base64Binary (streamed?) e.g from `fetch:binary`
: @return base64Binary for thumbnail
:)
declare function thumbnails:size($source as xs:base64Binary,$size as xs:integer)
as xs:base64Binary
{
Thumbs:size($source,xs:int($size),xs:int($size))
};
(:~
: generate scaled version of source image with maximum dimension of size
: @param $source base64Binary (streamed?) e.g from `fetch:binary`
: @return base64Binary for thumbnail
:)
declare function thumbnails:size($source as xs:base64Binary,$width as xs:integer,$height as xs:integer)
as xs:base64Binary
{
Thumbs:size($source,xs:int($width),xs:int($height))
};
(:~
: generate scaled version of source image at given factors 0-1
: @param $source base64Binary (streamed?) e.g from `fetch:binary`
: @return the thumbnail
:)
declare function thumbnails:scale($source as xs:base64Binary,$scale as xs:double)
as xs:base64Binary
{
Thumbs:scale($source,$scale,$scale)
};
(:~
: generate scaled version of source image at given factors 0-1
: @param $source base64Binary (streamed?) e.g from `fetch:binary`
: @return the thumbnail
:)
declare function thumbnails:scale($source as xs:base64Binary,$xscale as xs:double,$yscale as xs:double)
as xs:base64Binary
{
Thumbs:scale($source,$xscale,$yscale)
};
(:~
: generate thumbnail using parameters specified via XML
: @param $source base64Binary (streamed?) e.g from `fetch:binary`
: @param $task XML parameters <task><size width="100" ..
: @return the thumbnail
:)
declare function thumbnails:task($source as xs:base64Binary,
$task as element(thumbnail))
as xs:base64Binary
{
Thumbs:task($source,$task)
};
(:~
: validate task thumbnail XML against schema
: @param $src XML parameters <thumbnail><size width="100" ..
: @return empty-sequence or error
: @error BXVA0001: the validation fails.
: @error BXVA0002: the validation process cannot be started.
: @error BXVA0003: no XML Schema validator is available.
: @error BXVA0004: no validator is found for the specified version.
:)
declare function thumbnails:validate($src)
as empty-sequence()
{
validate:xsd($src,"task.xsd")
};
(:~
: validate task thumbnail XML against schema
: @param $src XML parameters <thumbnail><size width="100" ..
: @return validation report
:)
declare function thumbnails:validation-report($src)
as element(report)
{
validate:xsd-report($src,"task.xsd")
};
declare function thumbnails:schema-uri()
as xs:anyURI
{
resolve-uri("task.xsd")
};

10
src/main/cxan.xml Normal file
View file

@ -0,0 +1,10 @@
<package xmlns="http://cxan.org/ns/package" id="thumbnailator">
<abstract>XQuery interface to the thumbnail generator library: thumbnailator</abstract>
<author id="coobird">coobird</author>
<maintainer id="abunce">Andy Bunce</maintainer>
<home>https://github.com/coobird/thumbnailator</home>
<category id="libs">Library</category>
<tag>image</tag>
<tag>resize</tag>
<tag>graphic</tag>
</package>

14
src/main/expath-pkg.xml Normal file
View file

@ -0,0 +1,14 @@
<package xmlns="http://expath.org/ns/pkg" name="https://github.com/expkg-zone58/ex-thumbnailator"
abbrev="thumbnailator" version="8.0.1" spec="1.0">
<title>An XQuery interface to thumbnailator the thumbnail generator library.</title>
<xquery>
<namespace>expkg-zone58:image.thumbnailator</namespace>
<file>thumbnailator.xqm</file>
</xquery>
<xsd>
<import-uri>expkg-zone58:image.thumbnailator/schema/task.xsd</import-uri>
<file>task.xsd</file>
</xsd>
</package>

38
src/test/aspect.xq Normal file
View file

@ -0,0 +1,38 @@
(:~
:examples of constrain use
: generate 8 files showing all perms of aspect,fit,exif
:)
import module namespace t="expkg-zone58:image.thumbnailator";
declare variable $file-base:=file:parent(static-base-uri());
declare variable $watermark:="C:\Users\andy\git\ex-thumbnailator\src\test\resources\icon.gif";
declare variable $src:=file:resolve-path("resources/A34283.jpg",$file-base);
declare function local:wi($data as xs:base64Binary,$filename as xs:string)
{
file:write-binary(file:resolve-path($filename,$file-base),$data)
};
declare function local:constrain($aspect as xs:boolean,$fit as xs:boolean,$exif as xs:boolean)
{
<constrain aspect="{$aspect}" fit="{$fit}" exif="{$exif}"/>
};
let $s:=function($b){if($b) then ".+" else ".-"}
let $img:= fetch:binary($src)
let $ft:=(false(),true())
for $fit in $ft,$aspect in $ft,$exif in $ft
let $file:=("out",
$s($aspect) , "aspect",
$s($fit), "fit",
$s($exif), "exif")=>string-join("")
let $task:=<thumbnail>
<size width="250" height="250"/>
{local:constrain($aspect,$fit,$exif)}
<filters>
<canvas height="300" width="300" color="lightGray" position="CENTER"/>
<caption size="20" color="black" position="TOP_CENTER">{$file}</caption>
<watermark src="{$watermark}" alpha="1" position="BOTTOM_RIGHT"/>
</filters>
<output format="gif"/>
</thumbnail>
return t:task($img,$task) => local:wi("resources/" || $file || ".gif")

18
src/test/builder.xml Normal file
View file

@ -0,0 +1,18 @@
<thumbnail>
<!-- http://programtalk.com/java-api-usage-examples/net.coobird.thumbnailator.tasks.io.InputStreamImageSource/
ThumbnailParameterBuilder p=new ThumbnailParameterBuilder(); switch (element)
{ case "size": p.size(); break; .... ThumbnailParameter tp=p.build() } -->
<size x="200" y="89" />
<scale x="1" y="1" />
<sourceRegion x="0" y="0" width="100" height="100" />
<filters>
<canvas width="300" height="400" position=">?" crop="true"
fillColor="red" />
<caption >some text</caption>
<flip axis="vertical"/>
<colorize/>
<rotate angle="45" />
<watermark src="aa"/>
</filters>
</thumbnail>

37
src/test/inset.xq Normal file
View file

@ -0,0 +1,37 @@
(:~
:examples of inset use
:)
import module namespace t="expkg-zone58:image.thumbnailator";
declare variable $watermark:=local:path("resources\icon.gif");
declare variable $src:=local:path("resources/A34283.jpg");
declare function local:path($name){
file:resolve-path($name,file:base-dir())
};
declare function local:save($data as xs:base64Binary,$filename as xs:string)
{
file:write-binary(local:path($filename),$data)
};
let $img:= fetch:binary($src)
let $task:=<thumbnail>
<size width="300" height="300"/>
<constrain fit="true"/>
<filters>
<rotate angle="45"/>
<caption size="60" color="white" position="CENTER">DRAFT</caption>
<rotate angle="-45"/>
<canvas height="300" width="300" color="lightGray" position="CENTER"/>
<caption size="30" color="black" insets="10"
position="TOP_CENTER">Caption insets = 10</caption>
<watermark src="{$watermark}" alpha="1" position="BOTTOM_RIGHT"/>
<caption size="30" color="black" insets="-3"
position="BOTTOM_LEFT">BOTTOM_LEFT -3</caption>
</filters>
<output format="gif"/>
</thumbnail>
return t:task($img,$task) => local:save("resources/" || "inset.gif")

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/test/resources/icon.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
src/test/resources/icon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

9
src/test/rotate.xml Normal file
View file

@ -0,0 +1,9 @@
<thumbnail xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="expkg-zone58:image.thumbnailator/schema/task.xsd">
<size width="200" height="200" />
<constrain fit="true" aspect="true" exif="true"/>
<filters>
<rotate angle="251" />
<rotate angle="1" />
</filters>
</thumbnail>

12
src/test/sample-task.xml Normal file
View file

@ -0,0 +1,12 @@
<thumbnail xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="expkg-zone58:image.thumbnailator/schema/task.xsd">
<size width="500" height="500" />
<filters>
<colorize color="#FF0096" alpha=".4" />
<caption position="CENTER" color="white" size="30" font="SansSerif">Some Text here</caption>
<rotate angle="15" />
<canvas height="500" width="500" position="TOP_LEFT" color="black" />
<watermark src="{$watermark}" alpha=".8" position="TOP_LEFT" />
</filters>
</thumbnail>

22
src/test/sample.xq Normal file
View file

@ -0,0 +1,22 @@
import module namespace t="expkg-zone58:image.thumbnailator" at "../main/content/thumbnailator.xqm";
declare variable $pic1:=resolve-uri("resources/simple.jpg");
declare variable $picr:=resolve-uri("resources/result2.jpg");
declare variable $remote:="http://images.metmuseum.org/CRDImages/ep/original/DT46.jpg";
declare variable $watermark:="C:\Users\andy\git\ex-thumbnailator\src\test\resources\icon.jpg";
let $task:=<thumbnail>
<size width="500" height="500"/>
<filters>
<colorize color="#FF0096" alpha=".4"/>
<caption position="CENTER" color="white" size="30" font="SansSerif">Some Text here</caption>
<rotate angle="15"/>
<canvas height="500" width="500" position="TOP_LEFT" color="black"/>
<watermark src="{$watermark}" alpha=".8" position="BOTTOM_LEFT"/>
</filters>
</thumbnail>
(: let $task:=doc("rotate.xml")/task :)
let $x:=fetch:binary($remote)
let $r:=t:task($x,$task)
(: let $r:=Q{java:org.expkgzone58.image.Thumbs}task($x,$task) :)
return file:write-binary($picr,$r)

40
src/test/test.xqm Normal file
View file

@ -0,0 +1,40 @@
module namespace test = 'http://basex.org/modules/xqunit-tests';
(:~
: unit tests for thumbnail module
:)
import module namespace t="expkg-zone58:image.thumbnailator" (: at "../main/content/thumbnailator.xqm" :);
declare variable $test:pic1:=resolve-uri( "resources/simple.jpg");
declare variable $test:picr:=resolve-uri( "resources/out.jpg");
declare variable $test:met:=<images>
<image src="http://images.metmuseum.org/CRDImages/rl/web-large/DT3136.jpg">
http://www.metmuseum.org/art/collection/search/459117
</image>
</images>;
(:~ make a thumbnail :)
declare
%unit:test
function test:size() {
let $r:=t:size(
fetch:binary(
$test:pic1
),60,60
)
return unit:assert(
$r instance of xs:base64Binary
)
};
(:~ validate a task :)
declare
%unit:test
function test:validate() {
let $r:=t:validation-report(doc("rotate.xml"))
return unit:assert( $r )
};

2
src/test/validate.xq Normal file
View file

@ -0,0 +1,2 @@
import module namespace t="expkg-zone58:image.thumbnailator";
t:validation-report("C:/Users/andy/git/ex-thumbnailator/src/test/sample-task.xml")

View file

@ -1,228 +0,0 @@
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
padding: 0;
margin: 0;
font: inherit;
font-size: 100%;
vertical-align: baseline;
border: 0;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-spacing: 0;
border-collapse: collapse;
}
body {
font-family: 'Helvetica Neue', Helvetica, Arial, serif;
font-size: 13px;
line-height: 1.5;
color: #000;
}
a {
font-weight: bold;
color: #d5000d;
}
header {
padding-top: 35px;
padding-bottom: 10px;
}
header h1 {
font-size: 48px;
font-weight: bold;
line-height: 1.2;
color: #303030;
letter-spacing: -1px;
}
header h2 {
font-size: 24px;
font-weight: normal;
line-height: 1.3;
color: #aaa;
letter-spacing: -1px;
}
#downloads {
display: none;
}
#main_content {
padding-top: 20px;
}
code, pre {
margin-bottom: 30px;
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal;
font-size: 12px;
color: #222;
}
code {
padding: 0 3px;
}
pre {
padding: 20px;
overflow: auto;
border: solid 1px #ddd;
}
pre code {
padding: 0;
}
ul, ol, dl {
margin-bottom: 20px;
}
/* COMMON STYLES */
table {
width: 100%;
border: 1px solid #ebebeb;
}
th {
font-weight: 500;
}
td {
font-weight: 300;
text-align: center;
border: 1px solid #ebebeb;
}
form {
padding: 20px;
background: #f2f2f2;
}
/* GENERAL ELEMENT TYPE STYLES */
h1 {
font-size: 2.8em;
}
h2 {
margin-bottom: 8px;
font-size: 22px;
font-weight: bold;
color: #303030;
}
h3 {
margin-bottom: 8px;
font-size: 18px;
font-weight: bold;
color: #d5000d;
}
h4 {
font-size: 16px;
font-weight: bold;
color: #303030;
}
h5 {
font-size: 1em;
color: #303030;
}
h6 {
font-size: .8em;
color: #303030;
}
p {
margin-bottom: 20px;
font-weight: 300;
}
a {
text-decoration: none;
}
p a {
font-weight: 400;
}
blockquote {
padding: 0 0 0 30px;
margin-bottom: 20px;
font-size: 1.6em;
border-left: 10px solid #e9e9e9;
}
ul li {
list-style-position: inside;
list-style: disc;
padding-left: 20px;
}
ol li {
list-style-position: inside;
list-style: decimal;
padding-left: 3px;
}
dl dd {
font-style: italic;
font-weight: 100;
}
footer {
padding-top: 20px;
padding-bottom: 30px;
margin-top: 40px;
font-size: 13px;
color: #aaa;
}
footer a {
color: #666;
}
/* MISC */
.clearfix:after {
display: block;
height: 0;
clear: both;
visibility: hidden;
content: '.';
}
.clearfix {display: inline-block;}
* html .clearfix {height: 1%;}
.clearfix {display: block;}

View file

@ -1,69 +0,0 @@
.highlight { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kn { font-weight: bold } /* Keyword.Namespace */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
.type-csharp .highlight .k { color: #0000FF }
.type-csharp .highlight .kt { color: #0000FF }
.type-csharp .highlight .nf { color: #000000; font-weight: normal }
.type-csharp .highlight .nc { color: #2B91AF }
.type-csharp .highlight .nn { color: #000000 }
.type-csharp .highlight .s { color: #A31515 }
.type-csharp .highlight .sc { color: #A31515 }

View file

@ -1,255 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700);
body {
padding:50px;
font:14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
color:#777;
font-weight:300;
}
h1, h2, h3, h4, h5, h6 {
color:#222;
margin:0 0 20px;
}
p, ul, ol, table, pre, dl {
margin:0 0 20px;
}
h1, h2, h3 {
line-height:1.1;
}
h1 {
font-size:28px;
}
h2 {
color:#393939;
}
h3, h4, h5, h6 {
color:#494949;
}
a {
color:#39c;
font-weight:400;
text-decoration:none;
}
a small {
font-size:11px;
color:#777;
margin-top:-0.6em;
display:block;
}
.wrapper {
width:860px;
margin:0 auto;
}
blockquote {
border-left:1px solid #e5e5e5;
margin:0;
padding:0 0 0 20px;
font-style:italic;
}
code, pre {
font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal;
color:#333;
font-size:12px;
}
pre {
padding:8px 15px;
background: #f8f8f8;
border-radius:5px;
border:1px solid #e5e5e5;
overflow-x: auto;
}
table {
width:100%;
border-collapse:collapse;
}
th, td {
text-align:left;
padding:5px 10px;
border-bottom:1px solid #e5e5e5;
}
dt {
color:#444;
font-weight:700;
}
th {
color:#444;
}
img {
max-width:100%;
}
header {
width:270px;
float:left;
position:fixed;
}
header ul {
list-style:none;
height:40px;
padding:0;
background: #eee;
background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd));
background: -webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
background: -o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
background: -ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
background: linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
border-radius:5px;
border:1px solid #d2d2d2;
box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0;
width:270px;
}
header li {
width:89px;
float:left;
border-right:1px solid #d2d2d2;
height:40px;
}
header ul a {
line-height:1;
font-size:11px;
color:#999;
display:block;
text-align:center;
padding-top:6px;
height:40px;
}
strong {
color:#222;
font-weight:700;
}
header ul li + li {
width:88px;
border-left:1px solid #fff;
}
header ul li + li + li {
border-right:none;
width:89px;
}
header ul a strong {
font-size:14px;
display:block;
color:#222;
}
section {
width:500px;
float:right;
padding-bottom:50px;
}
small {
font-size:11px;
}
hr {
border:0;
background:#e5e5e5;
height:1px;
margin:0 0 20px;
}
footer {
width:270px;
float:left;
position:fixed;
bottom:50px;
}
@media print, screen and (max-width: 960px) {
div.wrapper {
width:auto;
margin:0;
}
header, section, footer {
float:none;
position:static;
width:auto;
}
header {
padding-right:320px;
}
section {
border:1px solid #e5e5e5;
border-width:1px 0;
padding:20px 0;
margin:0 0 20px;
}
header a small {
display:inline;
}
header ul {
position:absolute;
right:50px;
top:52px;
}
}
@media print, screen and (max-width: 720px) {
body {
word-wrap:break-word;
}
header {
padding:0;
}
header ul, header p.view {
position:static;
}
pre, code {
word-wrap:normal;
}
}
@media print, screen and (max-width: 480px) {
body {
padding:15px;
}
header ul {
display:none;
}
}
@media print {
body {
padding:0.4in;
font-size:12pt;
color:#444;
}
}

View file

@ -1,373 +0,0 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
padding: 0;
margin: 0;
font: inherit;
font-size: 100%;
vertical-align: baseline;
border: 0;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-spacing: 0;
border-collapse: collapse;
}
/* LAYOUT STYLES */
body {
font-family: 'Helvetica Neue', Helvetica, Arial, serif;
font-size: 1em;
line-height: 1.5;
color: #6d6d6d;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
background: #e7e7e7 url(../images/body-bg.png) 0 0 repeat;
}
a {
color: #d5000d;
}
a:hover {
color: #c5000c;
}
header {
padding-top: 35px;
padding-bottom: 25px;
}
header h1 {
font-family: 'Chivo', 'Helvetica Neue', Helvetica, Arial, serif;
font-size: 48px; font-weight: 900;
line-height: 1.2;
color: #303030;
letter-spacing: -1px;
}
header h2 {
font-size: 24px;
font-weight: normal;
line-height: 1.3;
color: #aaa;
letter-spacing: -1px;
}
#container {
min-height: 595px;
background: transparent url(../images/highlight-bg.jpg) 50% 0 no-repeat;
}
.inner {
width: 620px;
margin: 0 auto;
}
#container .inner img {
max-width: 100%;
}
#downloads {
margin-bottom: 40px;
}
a.button {
display: block;
float: left;
width: 179px;
padding: 12px 8px 12px 8px;
margin-right: 14px;
font-size: 15px;
font-weight: bold;
line-height: 25px;
color: #303030;
background: #fdfdfd; /* Old browsers */
background: -moz-linear-gradient(top, #fdfdfd 0%, #f2f2f2 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fdfdfd), color-stop(100%,#f2f2f2)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #fdfdfd 0%,#f2f2f2 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #fdfdfd 0%,#f2f2f2 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #fdfdfd 0%,#f2f2f2 100%); /* IE10+ */
background: linear-gradient(top, #fdfdfd 0%,#f2f2f2 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fdfdfd', endColorstr='#f2f2f2',GradientType=0 ); /* IE6-9 */
border-top: solid 1px #cbcbcb;
border-right: solid 1px #b7b7b7;
border-bottom: solid 1px #b3b3b3;
border-left: solid 1px #b7b7b7;
border-radius: 30px;
-webkit-box-shadow: 10px 10px 5px #888;
-moz-box-shadow: 10px 10px 5px #888;
box-shadow: 0px 1px 5px #e8e8e8;
-moz-border-radius: 30px;
-webkit-border-radius: 30px;
}
a.button:hover {
background: #fafafa; /* Old browsers */
background: -moz-linear-gradient(top, #fdfdfd 0%, #f6f6f6 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fdfdfd), color-stop(100%,#f6f6f6)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #fdfdfd 0%,#f6f6f6 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #fdfdfd 0%,#f6f6f6 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #fdfdfd 0%,#f6f6f6 100%); /* IE10+ */
background: linear-gradient(top, #fdfdfd 0%,#f6f6f6, 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fdfdfd', endColorstr='#f6f6f6',GradientType=0 ); /* IE6-9 */
border-top: solid 1px #b7b7b7;
border-right: solid 1px #b3b3b3;
border-bottom: solid 1px #b3b3b3;
border-left: solid 1px #b3b3b3;
}
a.button span {
display: block;
height: 23px;
padding-left: 50px;
}
#download-zip span {
background: transparent url(../images/zip-icon.png) 12px 50% no-repeat;
}
#download-tar-gz span {
background: transparent url(../images/tar-gz-icon.png) 12px 50% no-repeat;
}
#view-on-github span {
background: transparent url(../images/octocat-icon.png) 12px 50% no-repeat;
}
#view-on-github {
margin-right: 0;
}
code, pre {
margin-bottom: 30px;
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal;
font-size: 14px;
color: #222;
}
code {
padding: 0 3px;
background-color: #f2f2f2;
border: solid 1px #ddd;
}
pre {
padding: 20px;
overflow: auto;
color: #f2f2f2;
text-shadow: none;
background: #303030;
}
pre code {
padding: 0;
color: #f2f2f2;
background-color: #303030;
border: none;
}
ul, ol, dl {
margin-bottom: 20px;
}
/* COMMON STYLES */
hr {
height: 1px;
padding-bottom: 1em;
margin-top: 1em;
line-height: 1px;
background: transparent url('../images/hr.png') 50% 0 no-repeat;
border: none;
}
strong {
font-weight: bold;
}
em {
font-style: italic;
}
table {
width: 100%;
border: 1px solid #ebebeb;
}
th {
font-weight: 500;
}
td {
font-weight: 300;
text-align: center;
border: 1px solid #ebebeb;
}
form {
padding: 20px;
background: #f2f2f2;
}
/* GENERAL ELEMENT TYPE STYLES */
h1 {
font-size: 32px;
}
h2 {
margin-bottom: 8px;
font-size: 22px;
font-weight: bold;
color: #303030;
}
h3 {
margin-bottom: 8px;
font-size: 18px;
font-weight: bold;
color: #d5000d;
}
h4 {
font-size: 16px;
font-weight: bold;
color: #303030;
}
h5 {
font-size: 1em;
color: #303030;
}
h6 {
font-size: .8em;
color: #303030;
}
p {
margin-bottom: 20px;
font-weight: 300;
}
a {
text-decoration: none;
}
p a {
font-weight: 400;
}
blockquote {
padding: 0 0 0 30px;
margin-bottom: 20px;
font-size: 1.6em;
border-left: 10px solid #e9e9e9;
}
ul li {
list-style-position: inside;
list-style: disc;
padding-left: 20px;
}
ol li {
list-style-position: inside;
list-style: decimal;
padding-left: 3px;
}
dl dt {
color: #303030;
}
footer {
padding-top: 20px;
padding-bottom: 30px;
margin-top: 40px;
font-size: 13px;
color: #aaa;
background: transparent url('../images/hr.png') 0 0 no-repeat;
}
footer a {
color: #666;
}
footer a:hover {
color: #444;
}
/* MISC */
.clearfix:after {
display: block;
height: 0;
clear: both;
visibility: hidden;
content: '.';
}
.clearfix {display: inline-block;}
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* #Media Queries
================================================== */
/* Smaller than standard 960 (devices and browsers) */
@media only screen and (max-width: 959px) { }
/* Tablet Portrait size to standard 960 (devices and browsers) */
@media only screen and (min-width: 768px) and (max-width: 959px) { }
/* All Mobile Sizes (devices and browser) */
@media only screen and (max-width: 767px) {
header {
padding-top: 10px;
padding-bottom: 10px;
}
#downloads {
margin-bottom: 25px;
}
#download-zip, #download-tar-gz {
display: none;
}
.inner {
width: 94%;
margin: 0 auto;
}
}
/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
@media only screen and (min-width: 480px) and (max-width: 767px) { }
/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
@media only screen and (max-width: 479px) { }

34
tools/build.xq Normal file
View file

@ -0,0 +1,34 @@
(: create o/ps
: xar package and xqdoc
:)
declare namespace pkg="http://expath.org/ns/pkg";
import module namespace build = "quodatum.utils.build" at "buildx.xqm";
declare variable $base:=resolve-uri("../");
declare variable $src:=resolve-uri("../src/main/");
declare variable $dest:=resolve-uri("../dist/");
(:~
: the package definition as a pkg:package
:)
declare variable $package as element(pkg:package) :=doc(resolve-uri("expath-pkg.xml",$src))/pkg:package;
declare variable $content:=resolve-uri("content/",$src);
declare variable $dest-doc:=resolve-uri("doc/",$dest);
let $files:=build:files($src)
let $name:= build:xar-name($package)
return (
(: save xqdoc :)
build:files($content)!build:write-xqdoc(.,$content,$dest-doc),
(: write xar file :)
file:write-binary(
resolve-uri($name,$dest),
archive:create($files,$files!file:read-binary(fn:resolve-uri(.,$src)))
),
(: update package.xml located at $cxan :)
build:publish($package,resolve-uri("package.xml",$base))
)

66
tools/buildx.xqm Normal file
View file

@ -0,0 +1,66 @@
(:~
: build utils
: @author Andy Bunce
: @copyright Quodatum Ltd
: @licence Apache 2
: @since may-2015
:)
module namespace build = 'quodatum.utils.build';
declare default function namespace 'quodatum.utils.build';
declare namespace pkg="http://expath.org/ns/pkg";
(:~
: file paths below $src
: $src typically from resolve-uri
: @return sequences of relative file paths "content/ebnf/CR-xquery-31-20141218.ebnf" "..."
:)
declare function files($src as xs:string) as xs:string*
{
fn:filter(file:list($src,fn:true()),
function ($f){($src || $f)=>fn:translate("\","/")=>file:is-file()}
)
!fn:translate(.,"\","/")
};
(:~
: write xqdoc for $src/$path to $dest
:)
declare %updating function write-xqdoc($path,$src,$dest){
let $url:=fn:resolve-uri( $path,$src)=>fn:trace()
let $type:=fetch:content-type($url)
return switch($type)
case "application/xquery"
return file:write(
fn:resolve-uri($path || ".xml",$dest),
inspect:xqdoc($url)
)
default
return ()
};
(:~
: name of dist xar file eg "fred-0.1.0.xar"
:)
declare function xar-name($package as element(pkg:package)) as xs:string
{
fn:concat($package/@abbrev , "-" ,$package/@version, ".xar")
};
(:~
: update package.xml located at $cxan to ensure has entry for package $pkg
:)
declare %updating function publish($pkg as element(pkg:package),$cxan)
{
let $doc:=copy $c:=fn:doc($cxan)
modify(
let $pack:=$c/repo/pkg[name=$pkg/@name]
let $hit:= $pack/version[@num=$pkg/@version]
let $new:=<version num="{$pkg/@version}">
<!-- generated: {fn:current-dateTime()} -->
</version>
return if($hit)then ()
else insert node $new into $pack
)
return $c
return fn:put($doc,$cxan)
};