texlive[43596] trunk: texosquery (24mar17)

commits+karl at tug.org commits+karl at tug.org
Fri Mar 24 23:42:34 CET 2017


Revision: 43596
          http://tug.org/svn/texlive?view=revision&revision=43596
Author:   karl
Date:     2017-03-24 23:42:34 +0100 (Fri, 24 Mar 2017)
Log Message:
-----------
texosquery (24mar17)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/Makefile.am
    trunk/Build/source/texk/texlive/linked_scripts/Makefile.in
    trunk/Build/source/texk/texlive/linked_scripts/scripts.lst
    trunk/Master/bin/amd64-freebsd/texosquery
    trunk/Master/bin/amd64-netbsd/texosquery
    trunk/Master/bin/armel-linux/texosquery
    trunk/Master/bin/armhf-linux/texosquery
    trunk/Master/bin/i386-cygwin/texosquery
    trunk/Master/bin/i386-freebsd/texosquery
    trunk/Master/bin/i386-linux/texosquery
    trunk/Master/bin/i386-netbsd/texosquery
    trunk/Master/bin/i386-solaris/texosquery
    trunk/Master/bin/powerpc-linux/texosquery
    trunk/Master/bin/sparc-solaris/texosquery
    trunk/Master/bin/universal-darwin/texosquery
    trunk/Master/bin/x86_64-cygwin/texosquery
    trunk/Master/bin/x86_64-darwin/texosquery
    trunk/Master/bin/x86_64-linux/texosquery
    trunk/Master/bin/x86_64-solaris/texosquery
    trunk/Master/texmf-dist/doc/support/texosquery/CHANGES
    trunk/Master/texmf-dist/doc/support/texosquery/README.md
    trunk/Master/texmf-dist/doc/support/texosquery/texosquery.pdf
    trunk/Master/texmf-dist/scripts/texosquery/texosquery.jar
    trunk/Master/texmf-dist/source/support/texosquery/texosquery.dtx
    trunk/Master/texmf-dist/source/support/texosquery/texosquery.ins
    trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.sty
    trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.tex
    trunk/Master/tlpkg/libexec/ctan2tds
    trunk/Master/tlpkg/tlpsrc/texosquery.tlpsrc

Added Paths:
-----------
    trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre5.sh
    trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre8.sh
    trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery.sh
    trunk/Master/bin/amd64-freebsd/texosquery-jre5
    trunk/Master/bin/amd64-freebsd/texosquery-jre8
    trunk/Master/bin/amd64-netbsd/texosquery-jre5
    trunk/Master/bin/amd64-netbsd/texosquery-jre8
    trunk/Master/bin/armel-linux/texosquery-jre5
    trunk/Master/bin/armel-linux/texosquery-jre8
    trunk/Master/bin/armhf-linux/texosquery-jre5
    trunk/Master/bin/armhf-linux/texosquery-jre8
    trunk/Master/bin/i386-cygwin/texosquery-jre5
    trunk/Master/bin/i386-cygwin/texosquery-jre8
    trunk/Master/bin/i386-freebsd/texosquery-jre5
    trunk/Master/bin/i386-freebsd/texosquery-jre8
    trunk/Master/bin/i386-linux/texosquery-jre5
    trunk/Master/bin/i386-linux/texosquery-jre8
    trunk/Master/bin/i386-netbsd/texosquery-jre5
    trunk/Master/bin/i386-netbsd/texosquery-jre8
    trunk/Master/bin/i386-solaris/texosquery-jre5
    trunk/Master/bin/i386-solaris/texosquery-jre8
    trunk/Master/bin/powerpc-linux/texosquery-jre5
    trunk/Master/bin/powerpc-linux/texosquery-jre8
    trunk/Master/bin/sparc-solaris/texosquery-jre5
    trunk/Master/bin/sparc-solaris/texosquery-jre8
    trunk/Master/bin/universal-darwin/texosquery-jre5
    trunk/Master/bin/universal-darwin/texosquery-jre8
    trunk/Master/bin/x86_64-cygwin/texosquery-jre5
    trunk/Master/bin/x86_64-cygwin/texosquery-jre8
    trunk/Master/bin/x86_64-darwin/texosquery-jre5
    trunk/Master/bin/x86_64-darwin/texosquery-jre8
    trunk/Master/bin/x86_64-linux/texosquery-jre5
    trunk/Master/bin/x86_64-linux/texosquery-jre8
    trunk/Master/bin/x86_64-solaris/texosquery-jre5
    trunk/Master/bin/x86_64-solaris/texosquery-jre8
    trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.jar
    trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.sh
    trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.jar
    trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.sh
    trunk/Master/texmf-dist/scripts/texosquery/texosquery.sh
    trunk/Master/texmf-dist/source/support/texosquery/java/
    trunk/Master/texmf-dist/source/support/texosquery/java/FileListType.java
    trunk/Master/texmf-dist/source/support/texosquery/java/FilePathSortComparator.java
    trunk/Master/texmf-dist/source/support/texosquery/java/FileSortComparator.java
    trunk/Master/texmf-dist/source/support/texosquery/java/FileSortType.java
    trunk/Master/texmf-dist/source/support/texosquery/java/FileWalkVisitor.java
    trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre5.txt
    trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre7.txt
    trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre8.txt
    trunk/Master/texmf-dist/source/support/texosquery/java/QueryAction.java
    trunk/Master/texmf-dist/source/support/texosquery/java/QueryActionType.java
    trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQuery.java
    trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE5.java
    trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE7.java
    trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE8.java
    trunk/Master/texmf-dist/source/support/texosquery/texosquery-jre5.batch
    trunk/Master/texmf-dist/source/support/texosquery/texosquery-jre8.batch
    trunk/Master/texmf-dist/source/support/texosquery/texosquery.batch
    trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.cfg

Removed Paths:
-------------
    trunk/Master/bin/win32/texosquery.exe
    trunk/Master/texmf-dist/doc/support/texosquery/Manifest.txt
    trunk/Master/texmf-dist/scripts/texosquery/texosquery
    trunk/Master/texmf-dist/source/support/texosquery/TeXOSQuery.java

Modified: trunk/Build/source/texk/texlive/linked_scripts/Makefile.am
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/Makefile.am	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Build/source/texk/texlive/linked_scripts/Makefile.am	2017-03-24 22:42:34 UTC (rev 43596)
@@ -79,7 +79,9 @@
 	pdfxup/pdfxup \
 	pst-pdf/ps4pdf \
 	simpdftex/simpdftex \
-	texosquery/texosquery \
+	texosquery/texosquery.sh \
+	texosquery/texosquery-jre5.sh \
+	texosquery/texosquery-jre8.sh \
 	typeoutfileinfo/typeoutfileinfo.sh
 texmf_other_scripts = \
 	a2ping/a2ping.pl \

Modified: trunk/Build/source/texk/texlive/linked_scripts/Makefile.in
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/Makefile.in	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Build/source/texk/texlive/linked_scripts/Makefile.in	2017-03-24 22:42:34 UTC (rev 43596)
@@ -293,7 +293,9 @@
 	pdfxup/pdfxup \
 	pst-pdf/ps4pdf \
 	simpdftex/simpdftex \
-	texosquery/texosquery \
+	texosquery/texosquery.sh \
+	texosquery/texosquery-jre5.sh \
+	texosquery/texosquery-jre8.sh \
 	typeoutfileinfo/typeoutfileinfo.sh
 
 texmf_other_scripts = \

Modified: trunk/Build/source/texk/texlive/linked_scripts/scripts.lst
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/scripts.lst	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Build/source/texk/texlive/linked_scripts/scripts.lst	2017-03-24 22:42:34 UTC (rev 43596)
@@ -25,7 +25,9 @@
 pdfxup/pdfxup
 pst-pdf/ps4pdf
 simpdftex/simpdftex
-texosquery/texosquery
+texosquery/texosquery.sh
+texosquery/texosquery-jre5.sh
+texosquery/texosquery-jre8.sh
 typeoutfileinfo/typeoutfileinfo.sh
 a2ping/a2ping.pl
 accfonts/mkt1font

Added: trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre5.sh
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre5.sh	                        (rev 0)
+++ trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre5.sh	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery-jre5.jar`
+java -jar "$jarpath" "$@"


Property changes on: trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre5.sh
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre8.sh
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre8.sh	                        (rev 0)
+++ trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre8.sh	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery-jre8.jar`
+java -Djava.locale.providers=CLDR,JRE -jar "$jarpath" "$@"


Property changes on: trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery-jre8.sh
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery.sh
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery.sh	                        (rev 0)
+++ trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery.sh	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery.jar`
+java -jar "$jarpath" "$@"


Property changes on: trunk/Build/source/texk/texlive/linked_scripts/texosquery/texosquery.sh
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/amd64-freebsd/texosquery
===================================================================
--- trunk/Master/bin/amd64-freebsd/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/amd64-freebsd/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/amd64-freebsd/texosquery-jre5
===================================================================
--- trunk/Master/bin/amd64-freebsd/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/amd64-freebsd/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-freebsd/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-freebsd/texosquery-jre8
===================================================================
--- trunk/Master/bin/amd64-freebsd/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/amd64-freebsd/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-freebsd/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/amd64-netbsd/texosquery
===================================================================
--- trunk/Master/bin/amd64-netbsd/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/amd64-netbsd/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/amd64-netbsd/texosquery-jre5
===================================================================
--- trunk/Master/bin/amd64-netbsd/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/amd64-netbsd/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-netbsd/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-netbsd/texosquery-jre8
===================================================================
--- trunk/Master/bin/amd64-netbsd/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/amd64-netbsd/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-netbsd/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/armel-linux/texosquery
===================================================================
--- trunk/Master/bin/armel-linux/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/armel-linux/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/armel-linux/texosquery-jre5
===================================================================
--- trunk/Master/bin/armel-linux/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/armel-linux/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/armel-linux/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/armel-linux/texosquery-jre8
===================================================================
--- trunk/Master/bin/armel-linux/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/armel-linux/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/armel-linux/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/armhf-linux/texosquery
===================================================================
--- trunk/Master/bin/armhf-linux/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/armhf-linux/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/armhf-linux/texosquery-jre5
===================================================================
--- trunk/Master/bin/armhf-linux/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/armhf-linux/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/armhf-linux/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/armhf-linux/texosquery-jre8
===================================================================
--- trunk/Master/bin/armhf-linux/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/armhf-linux/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/armhf-linux/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/i386-cygwin/texosquery
===================================================================
--- trunk/Master/bin/i386-cygwin/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/i386-cygwin/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/i386-cygwin/texosquery-jre5
===================================================================
--- trunk/Master/bin/i386-cygwin/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/i386-cygwin/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-cygwin/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-cygwin/texosquery-jre8
===================================================================
--- trunk/Master/bin/i386-cygwin/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/i386-cygwin/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-cygwin/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/i386-freebsd/texosquery
===================================================================
--- trunk/Master/bin/i386-freebsd/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/i386-freebsd/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/i386-freebsd/texosquery-jre5
===================================================================
--- trunk/Master/bin/i386-freebsd/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/i386-freebsd/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-freebsd/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-freebsd/texosquery-jre8
===================================================================
--- trunk/Master/bin/i386-freebsd/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/i386-freebsd/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-freebsd/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/i386-linux/texosquery
===================================================================
--- trunk/Master/bin/i386-linux/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/i386-linux/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/i386-linux/texosquery-jre5
===================================================================
--- trunk/Master/bin/i386-linux/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/i386-linux/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-linux/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-linux/texosquery-jre8
===================================================================
--- trunk/Master/bin/i386-linux/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/i386-linux/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-linux/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/i386-netbsd/texosquery
===================================================================
--- trunk/Master/bin/i386-netbsd/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/i386-netbsd/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/i386-netbsd/texosquery-jre5
===================================================================
--- trunk/Master/bin/i386-netbsd/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/i386-netbsd/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-netbsd/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-netbsd/texosquery-jre8
===================================================================
--- trunk/Master/bin/i386-netbsd/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/i386-netbsd/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-netbsd/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/i386-solaris/texosquery
===================================================================
--- trunk/Master/bin/i386-solaris/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/i386-solaris/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/i386-solaris/texosquery-jre5
===================================================================
--- trunk/Master/bin/i386-solaris/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/i386-solaris/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-solaris/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-solaris/texosquery-jre8
===================================================================
--- trunk/Master/bin/i386-solaris/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/i386-solaris/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-solaris/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/powerpc-linux/texosquery
===================================================================
--- trunk/Master/bin/powerpc-linux/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/powerpc-linux/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/powerpc-linux/texosquery-jre5
===================================================================
--- trunk/Master/bin/powerpc-linux/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/powerpc-linux/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/powerpc-linux/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/powerpc-linux/texosquery-jre8
===================================================================
--- trunk/Master/bin/powerpc-linux/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/powerpc-linux/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/powerpc-linux/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/sparc-solaris/texosquery
===================================================================
--- trunk/Master/bin/sparc-solaris/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/sparc-solaris/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/sparc-solaris/texosquery-jre5
===================================================================
--- trunk/Master/bin/sparc-solaris/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/sparc-solaris/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/sparc-solaris/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/sparc-solaris/texosquery-jre8
===================================================================
--- trunk/Master/bin/sparc-solaris/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/sparc-solaris/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/sparc-solaris/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/universal-darwin/texosquery
===================================================================
--- trunk/Master/bin/universal-darwin/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/universal-darwin/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/universal-darwin/texosquery-jre5
===================================================================
--- trunk/Master/bin/universal-darwin/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/universal-darwin/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/universal-darwin/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/universal-darwin/texosquery-jre8
===================================================================
--- trunk/Master/bin/universal-darwin/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/universal-darwin/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/universal-darwin/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Deleted: trunk/Master/bin/win32/texosquery.exe
===================================================================
(Binary files differ)

Modified: trunk/Master/bin/x86_64-cygwin/texosquery
===================================================================
--- trunk/Master/bin/x86_64-cygwin/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/x86_64-cygwin/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/x86_64-cygwin/texosquery-jre5
===================================================================
--- trunk/Master/bin/x86_64-cygwin/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/x86_64-cygwin/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-cygwin/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-cygwin/texosquery-jre8
===================================================================
--- trunk/Master/bin/x86_64-cygwin/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/x86_64-cygwin/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-cygwin/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/x86_64-darwin/texosquery
===================================================================
--- trunk/Master/bin/x86_64-darwin/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/x86_64-darwin/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/x86_64-darwin/texosquery-jre5
===================================================================
--- trunk/Master/bin/x86_64-darwin/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/x86_64-darwin/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-darwin/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-darwin/texosquery-jre8
===================================================================
--- trunk/Master/bin/x86_64-darwin/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/x86_64-darwin/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-darwin/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/x86_64-linux/texosquery
===================================================================
--- trunk/Master/bin/x86_64-linux/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/x86_64-linux/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/x86_64-linux/texosquery-jre5
===================================================================
--- trunk/Master/bin/x86_64-linux/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/x86_64-linux/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linux/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linux/texosquery-jre8
===================================================================
--- trunk/Master/bin/x86_64-linux/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/x86_64-linux/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linux/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/bin/x86_64-solaris/texosquery
===================================================================
--- trunk/Master/bin/x86_64-solaris/texosquery	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/bin/x86_64-solaris/texosquery	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1 +1 @@
-link ../../texmf-dist/scripts/texosquery/texosquery
\ No newline at end of file
+link ../../texmf-dist/scripts/texosquery/texosquery.sh
\ No newline at end of file

Added: trunk/Master/bin/x86_64-solaris/texosquery-jre5
===================================================================
--- trunk/Master/bin/x86_64-solaris/texosquery-jre5	                        (rev 0)
+++ trunk/Master/bin/x86_64-solaris/texosquery-jre5	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre5.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-solaris/texosquery-jre5
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-solaris/texosquery-jre8
===================================================================
--- trunk/Master/bin/x86_64-solaris/texosquery-jre8	                        (rev 0)
+++ trunk/Master/bin/x86_64-solaris/texosquery-jre8	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/texosquery/texosquery-jre8.sh
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-solaris/texosquery-jre8
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/support/texosquery/CHANGES
===================================================================
--- trunk/Master/texmf-dist/doc/support/texosquery/CHANGES	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/texmf-dist/doc/support/texosquery/CHANGES	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1,3 +1,109 @@
+1.2 (2017/03/23):
+
+ * Now has three .jar files depending on the Java installation:
+
+   - texosquery-jre8.jar
+
+     Full application. May be used with the CLDR locale provider
+     (Unicode Consortium's Common Locale Data Repository).
+     Requires at least Java 8 (use with
+     java -Djava.locale.providers=CLDR,JRE or
+     add "java.locale.providers=CLDR,JRE" to the 
+     JAVA_TOOLS_OPTIONS environment variable to access the CLDR)
+
+   - texosquery.jar
+
+     The default version of the application. Can't be used with
+     CLDR. Less locale support. Requires at least Java 7.
+
+   - texosquery-jre5.jar
+
+     Cut-down version of the application with significantly less
+     locale support. Provided for old systems that can't upgrade,
+     but not recommended. (Use of Java 5 or 6 is deprecated.)
+     Requires at least Java 5.
+
+  * Corresponding scripts that run the appropriate .jar file
+    are bundled in texosquery.dtx and extracted using:
+
+    tex texosquery.ins
+
+    - Unix-like (run `chmod +x texosquery*.sh`): 
+
+      texosquery-jre8.sh : runs texosquery-jre8.jar with
+      -Djava.locale.providers=CLDR,JRE
+
+      texosquery.sh : runs texosquery.jar
+
+      texosquery-jre5.sh : runs texosquery-jre5.jar
+
+     (I recommend the removal of the '.sh' extension
+      for more convenient invocation.)
+
+    - Windows (rename texosquery*.batch to texosquery*.bat):
+
+      texosquery-jre8.bat : runs texosquery-jre8.jar with
+      -Djava.locale.providers=CLDR,JRE
+
+      texosquery.bat : runs texosquery.jar
+
+      texosquery-jre5.bat : runs texosquery-jre5.jar
+
+    You can edit these files if additional Java settings
+    are required (e.g. -Dfile.encoding=UTF-8). Alternatively
+    set the JAVA_TOOLS_OPTIONS environment variable.
+
+  * New texosquery.cfg configuration file. Edit the definition
+    of \TeXOSInvokerName to indicate which application you
+    need to use. For example, if Java 8 is installed:
+
+    \def\TeXOSInvokerName{texosquery-jre8}
+
+  See the installation section of the manual.
+
+  * New command line switches:
+
+  Actions:
+
+  --bcp47 / -b
+  --codeset-lcs / -C
+  --locale-data / -D 
+  --numeric / -N 
+  --date-time / -M
+  --time-zones / -Z
+  --list-dir / -ld
+  --list-regular / -lr
+  --filterlist-dir / -fd
+  --filterlist-regular / -fr
+  --walk / -w
+
+  Options:
+
+  --debug [⟨n⟩]
+  --nodebug
+  --compatible ⟨n⟩ / -compat ⟨n⟩
+
+  * Actions --list (-i) and --filterlist (-f) now have an
+    optional argument to indicate the sort order.
+
+  * When accessing file information, the TEXMF openin_any
+    setting is first checked to determine if read access is 
+    permitted.
+
+  * Returned values now include some shorthand markup that's
+    internally converted when read in by \TeXOSQuery. For
+    example "texosquery -n" now returns
+
+    \pdfd \fcln 20161113161156\fpls 00\fcsq 00\fcsq 
+
+    instead of
+
+    D:20161113161156+00'00'
+
+    To restore the original behaviour use --compatible 1
+
+    See the manual for further details.
+
 1.1 (2016-07-14):
 
  * texosquery.jar:

Deleted: trunk/Master/texmf-dist/doc/support/texosquery/Manifest.txt
===================================================================
--- trunk/Master/texmf-dist/doc/support/texosquery/Manifest.txt	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/texmf-dist/doc/support/texosquery/Manifest.txt	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1,2 +0,0 @@
-Main-Class: com/dickimawbooks/texosquery/TeXOSQuery
-Class-Path: .

Modified: trunk/Master/texmf-dist/doc/support/texosquery/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/support/texosquery/README.md	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/texmf-dist/doc/support/texosquery/README.md	2017-03-24 22:42:34 UTC (rev 43596)
@@ -4,7 +4,8 @@
 
 The application can query the following:
 
- - locale and codeset
+ - locale information
+ - default file encoding
  - current working directory
  - user home directory
  - temporary directory
@@ -24,43 +25,163 @@
 All paths use a forward slash as directory divider so results
 can be used, for example, in commands like `\includegraphics`.
 
-There are files provided for easy access in TeX documents:
+There are files provided for easy access in (La)TeX documents:
 
  - `texosquery.tex` : generic TeX code
  - `texosquery.sty` : LaTeX package
 
-This provides commands to run `texosquery` using TeX's shell
-escape mechanism and capture the result in a control sequence.
-The category code of most of TeX's default special characters 
-(and some other potentially problematic characters) is temporarily 
-changed to 12 while reading the result.
+This provides the command `\TeXOSQuery` to run `texosquery` using
+TeX's shell escape mechanism and capture the result in a control
+sequence.  The category code of most of TeX's default special
+characters (and some other potentially problematic characters) is
+temporarily changed to 12 while reading the result. Some of the
+`texosquery` output contains short markup commands (such as `\wrp`)
+which are internally converted within `\TeXOSQuery`.
 
 ## Installation
 
-The actual Java application is in `texosquery.jar`.
-The `.tex` and `.sty` files can be extracted from `texosquery.dtx`
-using `tex texosquery.ins`. In the following, replace TEXMF with the
-path to your TEXMF directory.
+Installation is best done using your TeX package manager.
+Manual installation instructions are described below.
+For more detail, see the documentation.
 
- - Move `texosquery.tex` to `TEXMF/tex/generic/texosquery/`
- - Move `texosquery.sty` to `TEXMF/tex/latex/texosquery/`
- - Move `texosquery.pdf` to `TEXMF/doc/generic/texosquery/`
- - Move `texosquery.jar` to `TEXMF/scripts/texosquery/`
+### Compiling the Documentation
 
-Unix-like users: move the bash script `texosquery` to somewhere on
-your path.
+To compile the documentation:
+```bash
+pdflatex texosquery.dtx
+makeglossaries texosquery
+makeindex -s gglo.ist -t texosquery.glg -o texosquery.gls texosquery.glo
+pdflatex texosquery.dtx
+makeindex -s gind.ist texosquery.idx
+pdflatex texosquery.dtx
+pdflatex texosquery.dtx
+```
 
-Windows users: TeX Live's generic wrapper should be able to locate
-the `texosquery.jar` file, but if not or you're not using TL,
-then (untested) create a file called `texosquery.bat` that contains:
-```dos
- at ECHO OFF
-FOR /F %%I IN ('kpsewhich --progname=texosquery --format=texmfscripts texosquery.jar') DO SET JARPATH=%%I
-START javaw -jar "%JARPATH%\texosquery.jar" %*
+### Extracting the Files
+
+Except for the `.jar` files, the `texosquery` files are all
+bundled inside `texosquery.dtx` with the extraction commands
+provided in `texosquery.ins`. To extract all the files do:
+```bash
+tex texosquery.ins
 ```
-(or skip the `FOR` line and replace `%JARPATH%` with the full path name to 
-`texosquery.jar`.) Put this file on your system's path.
 
+The `.sh` files are bash scripts for Unix-like users. These will
+need to be set to executable using `chmod`. I recommend
+that you also remove the `.sh` extension. Windows users can
+deleted these files.
+
+The `.batch` files are batch scripts for Windows users. Unix-like
+users can delete these files. These files are given the extension
+`.batch` as TeX on Windows doesn't allow the creation of `.bat`
+files. The extension will need to be changed to `.bat` after the
+files have been extracted.
+
+### Installing the Application
+
+In the following, replace _TEXMF_ with the path to your TEXMF directory.
+You can find your home TEXMF directory using
+```bash
+kpsewhich -var-value=TEXMFHOME
+```
+
+There are now three Java applications provided by this package:
+
+ - `texosquery.jar` (requires at least Java 7)
+ - `texosquery-jre8.jar` (requires at least Java 8)
+ - `texosquery-jre5.jar` (requires at least Java 5)
+
+There are corresponding bash scripts for Unix-like users (the `.sh`
+extension added by `texosquery.ins` should be removed and the files
+made executable):
+
+ - `texosquery`
+ - `texosquery-jre8`
+ - `texosquery-jre5`
+
+There are also corresponding batch scripts for Windows users (the `.batch`
+extension created by the `.ins` file should be changed to `.bat`):
+
+ - `texosquery.bat`
+ - `texosquery-jre8.bat`
+ - `texosquery-jre5.bat`
+
+Each script uses `kpsewhich` to find the corresponding `.jar` file
+and runs it.
+
+Put the `.jar` files in _TEXMF_`/scripts/texosquery/` and the
+bash or `.bat` files somewhere on your path. You may or may not need
+to refresh the TeX database.
+
+To test the installation, run
+```bash
+texosquery -v
+```
+in the command prompt or terminal. (Also try with `texosquery-jre8`
+and `texosquery-jre5`.)
+
+If successful, it should show the version number.
+
+### Installing the TeX Code
+
+The `.tex`, `.cfg` and `.sty` files should all be extracted from `texosquery.dtx`
+with `tex texosquery.ins` as described above.
+
+ - Move `texosquery.tex` to _TEXMF_`/tex/generic/texosquery/`
+ - Move `texosquery.cfg` to _TEXMF_`/tex/generic/texosquery/`
+ - Move `texosquery.sty` to _TEXMF_`/tex/latex/texosquery/`
+ - Move `texosquery.pdf` to _TEXMF_`/doc/generic/texosquery/`
+
+The `texosquery.cfg` file allows you to specify which application you
+want to use. First check which version of the Java Runtime
+Environment (JRE) you have installed:
+```bash
+java -version
+```
+This should display the version information. (For example, `"1.8.0_92"`)
+
+If the version number starts with `1.8` (“Java 8”), then you can use `texosquery-jre8.jar`.
+This is the full application. You can use `texosquery` or 
+`texosquery-jre5` as well, but there's less locale support with them. 
+The `texosquery-jre8` bash script and `texosquery-jre8.bat` batch script invokes Java with 
+`-Djava.locale.providers=CLDR,JRE`.
+
+If Windows users have simply been supplied with an executable versions
+of the `texosquery-jre8.jar` file (`texosquery-jre8.exe`) then you'll have to set the
+`JAVA_TOOL_OPTIONS` environment variable instead.
+ 
+This `java.locale.providers` setting allows Java to access locale
+information from the [Unicode Common Locale Data Repository
+(CLDR)](http://cldr.unicode.org/) installed on their system. The
+pending Java 9 should include this by default, so this will only be
+relevant to Java 8. Earlier versions of Java (7 or below) don't have
+this option, which limits the locale support to that which is
+natively provided by the JRE.
+
+If the version information starts with `1.7` (“Java 7”), then you can use 
+`texosquery.jar`. This is the default application and provides most
+of the functions of the full application, but there's less locale support.
+You can also use the even more limited `texosquery-jre5`, but you can't use
+`texosquery-jre8`, so you can't take advantage of the CLDR.
+
+If the version information starts with `1.5` (“Java 5”) or `1.6`
+(“Java 6”), then you can _only_ use `texosquery-jre5`.  The locale
+support is significantly reduced in this case and there's no support
+for language scripts. Note that these versions of Java are
+deprecated.
+
+Once you have determined which application you want to use, edit the
+`texosquery.cfg` so that `\TeXOSInvokerName` is defined to the appropriate invocation. For example, with Java 8:
+```tex
+\def\TeXOSInvokerName{texosquery-jre8}
+```
+or with Java 5 or 6:
+```tex
+\def\TeXOSInvokerName{texosquery-jre5}
+```
+(bash users will have to add the `.sh` extension if it hasn't
+been removed, as per the above instructions.)
+
 ## Examples:
 
 Plain TeX:
@@ -69,8 +190,11 @@
 % arara: pdftex: {shell: on}
 \input texosquery
 
+\TeXOSQuery{\result}{-b}
+IEFT BCP 47 language tag: \result.
+
 \TeXOSQueryLocale{\result}
-locale: \result.
+POSIX locale: \result.
 
 \TeXOSQueryCwd{\result}
 cwd: {\tt \result}.
@@ -98,8 +222,11 @@
 
 \begin{document}
 
+\TeXOSQuery{\result}{-b}
+IEFT BCP 47 language tag: \result.
+
 \TeXOSQueryLocale{\result}
-locale: \result.
+POSIX locale: \result.
 
 \TeXOSQueryCwd{\result}
 cwd: \texttt{\result}.
@@ -125,39 +252,39 @@
 For a full list of available commands, see the documentation
 (`texosquery.pdf`).
 
-You can omit `texosquery.tex` and directly use `texosquery`
-in TeX's shell escape, but take care of special characters
-occurring in the result or if double-quotes occur in
-`\jobname`.
-
 ## Source code
 
-The `.tex` and `.sty` files and documentation are contained in
-`texosquery.dtx`. To compile the documentation:
-```bash
-pdflatex texosquery.dtx
-makeindex -s gglo.ist -t texosquery.glg -o texosquery.gls texosquery.glo
-makeindex -s gind.ist texosquery.idx
-pdflatex texosquery.dtx
-pdflatex texosquery.dtx
+The Java source is in the `.java` files and the manifest for each 
+`.jar` file is `Manifest*.txt` (`Manifest-jre8.txt` for `texosquery-jre8` etc). 
+Assuming the following directory structure:
 ```
-
-The Java source is in `TeXOSQuery.java` and the manifest for the
-`.jar` file is `Manifest.txt`. Assuming the following directory
-structure:
-```
 java/TeXOSQuery.java
-java/Manifest.txt
+java/TeXOSQueryJRE5.java
+java/TeXOSQueryJRE7.java
+java/TeXOSQueryJRE8.java
+java/QueryAction.java
+java/QueryActionType.java
+java/FileSortType.java
+java/FileSortComparator.java
+java/FileListType.java
+java/FileWalkVisitor.java
+java/Manifest-jre5.txt
+java/Manifest-jre7.txt
+java/Manifest-jre8.txt
 classes/com/dickimawbooks/texosquery/
 ```
-Then to create `texosquery.jar`, do:
+Then to create `texosquery-jre8.jar`, do (for JDK version 1.8):
 ```bash
 cd java 
-javac -d ../classes TeXOSQuery.java
+javac -d ../classes TeXOSQuery.java QueryAction.java QueryActionType.java TeXOSQueryJRE8.java FileSortType.java FileSortComparator.java FileListType.java FileWalkVisitor.java
 cd ../classes
-jar cmf ../java/Manifest.txt ../texosquery.jar com/dickimawbooks/texosquery/*.class
+jar cmf ../java/Manifest-jre8.txt ../texosquery-jre8.jar com/dickimawbooks/texosquery/*.class
 ```
 
+Similarly for the other `.jar` files, replacing `8` with `7` or `5`.
+(The Java 7 version should really be `texosquery-jre7.jar`, but is
+simply named `texosquery.jar` in the distribution for backward compatibility reasons. If you compile the code, the `.jar` name is your choice.)
+
 ---
 
 Source on GitHub: https://github.com/nlct/texosquery

Modified: trunk/Master/texmf-dist/doc/support/texosquery/texosquery.pdf
===================================================================
(Binary files differ)

Deleted: trunk/Master/texmf-dist/scripts/texosquery/texosquery
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.jar
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.jar
===================================================================
--- trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.jar	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.jar	2017-03-24 22:42:34 UTC (rev 43596)

Property changes on: trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.jar
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.sh
===================================================================
--- trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.sh	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.sh	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery-jre5.jar`
+java -jar "$jarpath" "$@"


Property changes on: trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre5.sh
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.jar
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.jar
===================================================================
--- trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.jar	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.jar	2017-03-24 22:42:34 UTC (rev 43596)

Property changes on: trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.jar
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.sh
===================================================================
--- trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.sh	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.sh	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery-jre8.jar`
+java -Djava.locale.providers=CLDR,JRE -jar "$jarpath" "$@"


Property changes on: trunk/Master/texmf-dist/scripts/texosquery/texosquery-jre8.sh
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/texmf-dist/scripts/texosquery/texosquery.jar
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/scripts/texosquery/texosquery.sh
===================================================================
--- trunk/Master/texmf-dist/scripts/texosquery/texosquery.sh	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/texosquery/texosquery.sh	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery.jar`
+java -jar "$jarpath" "$@"


Property changes on: trunk/Master/texmf-dist/scripts/texosquery/texosquery.sh
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/source/support/texosquery/TeXOSQuery.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/TeXOSQuery.java	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/texmf-dist/source/support/texosquery/TeXOSQuery.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1,767 +0,0 @@
-package com.dickimawbooks.texosquery;
-
-import java.io.BufferedReader;
-import java.util.Locale;
-import java.util.Calendar;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-/**
- * Main class.
- * @author Nicola Talbot
- * @version 1.1
- * @since 1.0
- */
-public class TeXOSQuery {
-
-    private static final String VERSION_NUMBER = "1.1";
-    private static final String VERSION_DATE = "2016-07-14";
-    private static final char BACKSLASH = '\\';
-    private static final char FORWARDSLASH = '/';
-    private static final long ZERO = 0L;
-    
-    /**
-     * Escapes hash from input string.
-     * @param string Input string.
-     * @return String with hash escaped.
-     */
-    private static String escapeHash(String string) {
-        return string.replaceAll("#", "\\\\#");
-    }
-
-    /**
-     * Gets a string representation of the provided locale.
-     * @param locale The provided locale.
-     * @return String representation.
-     */
-    private static String getLocale(Locale locale) {
-        return getLocale(locale, false);
-    }
-
-    /**
-     * Gets a string representation of the provided locale, converting the code
-     * set if possible.
-     * @param locale The provided locale.
-     * @param convertCodeset Boolean value to convert the code set.
-     * @return String representation.
-     */
-    private static String getLocale(Locale locale, boolean convertCodeset) {
-        
-        String identifier = "";
-
-        if (locale != null) {
-            
-            String language = locale.getLanguage();
-
-            if (language != null) {
-                identifier = language;
-            }
-
-            String country = locale.getCountry();
-
-            if ((country != null) &&
-                    (!"".equals(country))) {
-                
-                if ("".equals(identifier)) {
-                    identifier = country;
-                } else {
-                    identifier = identifier.concat("-").concat(country);
-                }
-                
-            }
-
-            String codeset = System.getProperty("file.encoding", "UTF-8");
-
-            if ((codeset != null) &&
-                    (!"".equals(codeset))) {
-                
-                if (convertCodeset) {
-                    codeset = codeset.toLowerCase().replaceAll("-", "");
-                }
-
-                identifier = identifier.concat(".").concat(codeset);
-            }
-
-            String script = locale.getScript();
-
-            if ((script != null) &&
-                    (!"".equals(script))) {
-                identifier = identifier.concat("@").concat(escapeHash(script));
-            }
-
-        }
-
-        return identifier;
-    }
-
-    /**
-     * Gets the OS name.
-     * @return The OS name as string.
-     */
-    private static String getOSname() {
-        return getSystemProperty("os.name");
-    }
-
-    /**
-     * Gets the OS architecture.
-     * @return The OS architecture as string.
-     */
-    private static String getOSarch() {
-        return getSystemProperty("os.arch");
-    }
-
-    /**
-     * Gets the OS version.
-     * @return The OS version as string.
-     */
-    private static String getOSversion() {
-        return getSystemProperty("os.version");
-    }
-
-    /**
-     * Gets the user home.
-     * @return The user home as string.
-     */
-    private static String getUserHome() {
-        return getSystemProperty("user.home");
-    }
-
-    /*
-   * 
-     */
-    /**
-     * Converts the filename string to TeX path. Since this is designed to work
-     * within TeX, backslashes in paths need to be replaced with forward
-     * slashes.
-     * @param filename The filename string.
-     * @return TeX path.
-     */
-    private static String toTeXPath(String filename) {
-        
-        String path = "";
-        
-        if (filename != null) {
-            if (File.separatorChar == BACKSLASH) {
-                filename = filename.replaceAll("\\\\", "/");
-            }
-            path = escapeHash(filename);
-        }
-        
-        return path;
-    }
-
-    /**
-     * Converts the TeX path back to the original representation.
-     * @param filename The filename string.
-     * @return The original representation.
-     */
-    private static String fromTeXPath(String filename) {
-        
-        if (File.separatorChar != FORWARDSLASH) {
-            filename = filename.replaceAll("/", File.separator);
-        }
-
-        return filename;
-    }
-
-    /**
-     * Gets a file representation from a filename string.
-     * @param filename Filename string.
-     * @return File representation 
-     */
-    private static File fileFromTeXPath(String filename) {
-        
-        filename = fromTeXPath(filename);
-        File file = new File(filename);
-
-        if (!file.exists() && file.getParent() == null) {
-
-            try {
-                Process process = new ProcessBuilder(
-                        "kpsewhich",
-                        filename
-                ).start();
-
-                if (process.waitFor() == 0) {
-                
-                    InputStream stream = process.getInputStream();
-                    
-                    if (stream != null) {
-                        
-                        BufferedReader reader = new BufferedReader(
-                                new InputStreamReader(stream)
-                        );
-
-                        String line = reader.readLine();
-                        reader.close();
-
-                        if ((line != null) && (!"".equals(line))) {
-                            file = new File(fromTeXPath(line));
-                        }
-                    }
-                }
-            } catch (IOException exception1) {
-                // quack quack
-            } catch (InterruptedException exception2) {
-                // quack quack
-            }
-        }
-
-        return file;
-    }
-
-    /**
-     * Gets the current working directory.
-     * @return The current working directory.
-     */
-    private static String getCwd() {
-        return getSystemProperty("user.dir");
-    }
-
-    /**
-     * Gets the temporary directory.
-     * @return Temporary directory.
-     */
-    private static String getTmpDir() {
-        return getSystemProperty("java.io.tmpdir");
-    }
-
-    /**
-     * Gets the current date.
-     * @return The current date.
-     */
-    private static String pdfnow() {
-        return pdfDate(Calendar.getInstance());
-    }
-
-    /**
-     * Gets the date in an specific format.
-     * @param calendar A calendar object.
-     * @return Date in an specific format.
-     */
-    private static String pdfDate(Calendar calendar) {
-        String tz = String.format("%1$tz", calendar);
-        return String.format(
-                "D:%1$tY%1$tm%1td%1$tH%1$tM%1$tS%2$s'%3$s'",
-                calendar,
-                tz.substring(0, 3),
-                tz.substring(3)
-        );
-    }
-
-    /**
-     * Gets the date from a file.
-     * @param file File.
-     * @return The date in an specific format.
-     */
-    private static String pdfDate(File file) {
-        
-        String date = "";
-        
-        try {
-            long millisecs = file.lastModified();
-            
-            if (millisecs > ZERO) {
-                
-                Calendar calendar = Calendar.getInstance();
-                calendar.setTimeInMillis(millisecs);
-                date = pdfDate(calendar);
-                
-            }
-        } catch (SecurityException exception) {
-            // quack quack
-        }
-
-        return date;
-    }
-
-    /**
-     * Gets the file length.
-     * @param file The file.
-     * @return The length as a string.
-     */
-    private static String getFileLength(File file) {
-        
-        String output = "";
-        
-        try {
-            long length = file.length();
-
-            if (length > ZERO) {
-                output = String.format("%d", length);
-            }
-        } catch (SecurityException exception) {
-            // quack quack
-        }
-
-        return output;
-    }
-
-    /**
-     * Gets the list of files from a directory.
-     * @param separator Separator.
-     * @param directory Directory.
-     * @return List as a string.
-     */
-    private static String getFileList(String separator, File directory) {
-        
-        StringBuilder builder = new StringBuilder();
-        
-        if (directory.isDirectory()) {
-        
-            try {
-                
-                String[] list = directory.list();
-                if (list != null) {
-                    
-                    for (int i = 0; i < list.length; i++) {
-                        
-                        if (i > 0) {
-                            builder.append(separator);
-                        }
-                        
-                        builder.append(escapeHash(list[i]));
-                        
-                    }
-                }
-                
-            } catch (SecurityException exception) {
-                // quack quack
-            }
-        }
-
-        return builder.toString();
-    }
-
-    /**
-     * Gets a filtered list of files from directory.
-     * @param separator Separator.
-     * @param regex Regular expression.
-     * @param directory Directory.
-     * @return Filtered list as string.
-     */
-    private static String getFilterFileList(String separator,
-            final String regex, File directory) {
-        
-        StringBuilder builder = new StringBuilder();
-        
-        if (directory.isDirectory()) {
-      
-            if ((regex == null) || ("".equals(regex))) {
-                builder.append(getFileList(separator, directory));
-            }
-            else {        
-                try {
-                    String[] list = directory.list(new FilenameFilter() {
-                        @Override
-                        public boolean accept(File dir, String name) {
-                            return name.matches(regex);
-                        }
-                    });
-
-                    if (list != null) {
-                        
-                        for (int i = 0; i < list.length; i++) {
-                        
-                            if (i > 0) {
-                                builder.append(separator);
-                            }
-                            
-                            builder.append(escapeHash(list[i]));
-                        }
-                        
-                    }
-                } catch (SecurityException exception) {
-                    // quack quack
-                }
-            }
-        }
-
-        return builder.toString();
-    }
-
-    /**
-     * Gets the file URI.
-     * @param file The file.
-     * @return The URI.
-     */
-    private static String fileURI(File file) {
-        
-        String uri = "";
-        
-        if (file.exists()) {
-            try {
-                uri = file.toURI().toString();
-            } catch (SecurityException exception) {
-                // quack quack
-            }
-        }
-
-        return uri;
-    }
-
-    /**
-     * Gets the file path.
-     * @param file The file.
-     * @return The path.
-     */
-    private static String filePath(File file) {
-        
-        String path = "";
-        
-        if (file.exists()) {
-            try {
-                path = toTeXPath(file.getCanonicalPath());
-            } catch (SecurityException exception1) {
-                // quack quack
-            } catch (IOException exception2) {
-                // quack quack
-            }
-        }
-
-        return path;
-    }
-
-    /**
-     * Gets the path for the file's parent.
-     * @param file The file.
-     * @return The path.
-     */
-    private static String parentPath(File file) {
-        
-        String path = "";
-        
-        if (file.exists()) {
-            try {
-                path = toTeXPath(file.getCanonicalFile().getParent());
-            } catch (SecurityException exception1) {
-                // quack quack
-            } catch (IOException exception2) {
-                // quack quack
-            }
-        }
-
-        return path;
-    }
-
-    /**
-     * Prints the syntax usage.
-     */
-    private static void syntax() {
-        System.out.println("Usage: texosquery <option>...");
-
-        System.out.println();
-        System.out.println("Cross-platform OS query application");
-        System.out.println("for use with TeX's shell escape.");
-        System.out.println();
-        System.out.println("Each query displays the result in a single line.");
-        System.out.println("A blank line is printed if the requested");
-        System.out.println("information is unavailable.");
-
-        System.out.println();
-        System.out.println("-h or --help\tDisplay this help message and exit");
-        System.out.println("-v or --version\tDisplay version information and exit");
-        System.out.println();
-        System.out.println("General:");
-        System.out.println();
-        System.out.println("-L or --locale\t\tDisplay locale information");
-        System.out.println("-l or --locale-lcs\tAs --locale but codeset ");
-        System.out.println("\t\t\tin lowercase with hyphens stripped");
-        System.out.println("-c or --cwd\t\tDisplay current working directory");
-        System.out.println("-m or --userhome\tDisplay user's home directory");
-        System.out.println("-t or --tmpdir\t\tDisplay temporary directory");
-        System.out.println("-o or --osname\t\tDisplay OS name");
-        System.out.println("-r or --osversion\tDisplay OS version");
-        System.out.println("-a or --osarch\t\tDisplay OS architecture");
-        System.out.println("-n or --pdfnow\t\tDisplay current date-time in PDF format");
-
-        System.out.println();
-        System.out.println("File Queries:");
-        System.out.println();
-        System.out.println("Paths should use / for the directory divider.");
-        System.out.println();
-        System.out.println("-d <file> or --pdfdate <file>");
-        System.out.println("  Display date stamp of <file> in PDF format");
-        System.out.println();
-        System.out.println("-s <file> or --filesize <file>");
-        System.out.println("  Display size of <file> in bytes");
-        System.out.println();
-        System.out.println("-i <sep> <dir> or --list <sep> <dir>");
-        System.out.println("  Display list of all files in <dir> separated by <sep>");
-        System.out.println();
-        System.out.println("-f <sep> <regex> <dir> or --filterlist <sep> <regex> <dir>");
-        System.out.println("  Display list of files in <dir> that match <regex> separated by <sep>");
-        System.out.println();
-        System.out.println("-u <file> or --uri <file>");
-        System.out.println("  Display the URI of <file>");
-        System.out.println();
-        System.out.println("-p <file> or --path <file>");
-        System.out.println("  Display the canonical path of <file>");
-        System.out.println();
-        System.out.println("-e <file> or --dirname <file>");
-        System.out.println("  Display the canonical path of the parent of <file>");
-    }
-
-    /**
-     * Prints the version.
-     */
-    private static void version() {
-        System.out.println(String.format("texosquery %s %s", VERSION_NUMBER,
-                VERSION_DATE));
-        System.out.println("Copyright 2016 Nicola Talbot");
-        System.out.println("License LPPL 1.3+ (http://ctan.org/license/lppl1.3)");
-    }
-
-    /**
-     * Prints the information with optional grouping.
-     * @param group Determines whether to add grouping
-     * @param info Information to print
-     */ 
-   private static void print(boolean group, String info)
-   {
-      if (group)
-      {
-         System.out.println(String.format("{%s}", info));
-      }
-      else
-      {
-         System.out.println(info);
-      }
-   }
-
-    /**
-     * Main method.
-     * @param args Command line arguments.
-     */
-    public static void main(String[] args) {
-        if (args.length == 0) {
-            System.err.println("Missing argument. Try texosquery --help");
-            System.exit(1);
-        }
-
-        boolean group = false;
-
-        for (int i = 0, n=args.length-1; i < args.length; i++) {
-            if (args[i].equals("-L") || args[i].equals("--locale")) {
-                if (i < n) group = true;
-
-                print(group, getLocale(Locale.getDefault()));
-            } else if (args[i].equals("-l") || args[i].equals("--locale-lcs")) {
-                if (i < n) group = true;
-
-                print(group, getLocale(Locale.getDefault(), true));
-            } else if (args[i].equals("-c") || args[i].equals("--cwd")) {
-                if (i < n) group = true;
-
-                print(group, getCwd());
-            } else if (args[i].equals("-m") || args[i].equals("--userhome")) {
-                if (i < n) group = true;
-
-                print(group, getUserHome());
-            } else if (args[i].equals("-t") || args[i].equals("--tmpdir")) {
-                if (i < n) group = true;
-
-                print(group, getTmpDir());
-            } else if (args[i].equals("-r") || args[i].equals("--osversion")) {
-                if (i < n) group = true;
-
-                print(group, getOSversion());
-            } else if (args[i].equals("-a") || args[i].equals("--osarch")) {
-                if (i < n) group = true;
-
-                print(group, getOSarch());
-            } else if (args[i].equals("-o") || args[i].equals("--osname")) {
-                if (i < n) group = true;
-
-                print(group, getOSname());
-            } else if (args[i].equals("-n") || args[i].equals("--pdfnow")) {
-                if (i < n) group = true;
-
-                print(group, pdfnow());
-            } else if (args[i].equals("-d") || args[i].equals("--pdfdate")) {
-                i++;
-
-                if (i >= args.length) {
-                    System.err.println(
-                            String.format("filename expected after %s", args[i - 1]));
-                    System.exit(1);
-                }
-
-                if (i < n) group = true;
-
-                if ("".equals(args[i])) {
-                    print(group, "");
-                } else {
-                    print(group, pdfDate(fileFromTeXPath(args[i])));
-                }
-            } else if (args[i].equals("-s") || args[i].equals("--filesize")) {
-                i++;
-
-                if (i >= args.length) {
-                    System.err.println(
-                            String.format("filename expected after %s", args[i - 1]));
-                    System.exit(1);
-                }
-
-                if (i < n) group = true;
-
-                if ("".equals(args[i])) {
-                    print(group, "");
-                } else {
-                    print(group, getFileLength(fileFromTeXPath(args[i])));
-                }
-            } else if (args[i].equals("-i") || args[i].equals("--list")) {
-                i++;
-
-                if (i >= args.length) {
-                    System.err.println(
-                            String.format("separator and directory name expected after %s",
-                                    args[i - 1]));
-                    System.exit(1);
-                }
-
-                i++;
-
-                if (i >= args.length) {
-                    System.err.println(
-                            String.format("directory name expected after %s %s",
-                                    args[i - 2], args[i - 1]));
-                    System.exit(1);
-                }
-
-                if (i < n) group = true;
-
-                if ("".equals(args[i])) {
-                    print(group, "");
-                } else {
-                    print(group, getFileList(args[i - 1],
-                            new File(fromTeXPath(args[i]))));
-                }
-            } else if (args[i].equals("-f") || args[i].equals("--filterlist")) {
-                i++;
-
-                if (i >= args.length) {
-                    System.err.println(
-                            String.format(
-                                    "separator, regex and directory name expected after %s",
-                                    args[i - 1]));
-                    System.exit(1);
-                }
-
-                i++;
-
-                if (i >= args.length) {
-                    System.err.println(
-                            String.format("regex and directory name expected after %s %s",
-                                    args[i - 2], args[i - 1]));
-                    System.exit(1);
-                }
-
-                i++;
-
-                if (i >= args.length) {
-                    System.err.println(
-                            String.format("directory name expected after %s %s",
-                                    args[i - 3], args[i - 2], args[i - 1]));
-                    System.exit(1);
-                }
-
-                if (i < n) group = true;
-
-                if ("".equals(args[i])) {
-                    print(group, "");
-                } else {
-                    print(group, getFilterFileList(
-                            args[i - 2], args[i - 1], new File(fromTeXPath(args[i]))));
-                }
-            } else if (args[i].equals("-u") || args[i].equals("--uri")) {
-                i++;
-
-                if (i >= args.length) {
-                    System.err.println(
-                            String.format("filename expected after %s", args[i - 1]));
-                    System.exit(1);
-                }
-
-                if (i < n) group = true;
-
-                if ("".equals(args[i])) {
-                    print(group, "");
-                } else {
-                    print(group, fileURI(fileFromTeXPath(args[i])));
-                }
-            }
-            else if (args[i].equals("-p") || args[i].equals("--path"))
-            {
-                i++;
-
-                if (i >= args.length) {
-                    System.err.println(
-                            String.format("filename expected after %s", args[i - 1]));
-                    System.exit(1);
-                }
-
-                if (i < n) group = true;
-
-                if ("".equals(args[i])) {
-                    print(group, "");
-                } else {
-                    print(group, filePath(fileFromTeXPath(args[i])));
-                }
-            }
-            else if (args[i].equals("-e") || args[i].equals("--dirname"))
-            {
-                i++;
-
-                if (i >= args.length) {
-                    System.err.println(
-                            String.format("filename expected after %s", args[i - 1]));
-                    System.exit(1);
-                }
-
-                if (i < n) group = true;
-
-                if ("".equals(args[i])) {
-                    print(group, "");
-                } else {
-                    print(group, 
-                     parentPath(fileFromTeXPath(args[i])));
-                }
-            }
-            else if (args[i].equals("-h") || args[i].equals("--help")) {
-                syntax();
-                System.exit(0);
-            } else if (args[i].equals("-v") || args[i].equals("--version")) {
-                version();
-                System.exit(0);
-            } else {
-                System.err.println(String.format("unknown option '%s'", args[i]));
-                System.exit(1);
-            }
-        }
-    }
-    
-    /**
-     * Gets the system property.
-     * @param key Key.
-     * @return Value;
-     */
-    private static String getSystemProperty(String key) {
-        
-        String value = "";
-        
-        try {
-            value = System.getProperty(key, "");
-        }
-        catch (SecurityException exception) {
-            // quack quack
-        }
-        
-        return value;
-        
-    }
-
-}

Added: trunk/Master/texmf-dist/source/support/texosquery/java/FileListType.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/FileListType.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/FileListType.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,24 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+/**
+ * Indicates the type of file to be included in listings.
+ * @since 1.2
+ */
+public enum FileListType
+{
+   FILE_LIST_ANY, FILE_LIST_DIRECTORIES_ONLY,
+   FILE_LIST_REGULAR_FILES_ONLY
+}
+


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/FileListType.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/FilePathSortComparator.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/FilePathSortComparator.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/FilePathSortComparator.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,186 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+import java.util.Comparator;
+import java.nio.file.Path;
+import java.nio.file.Files;
+import java.nio.file.attribute.FileTime;
+
+/**
+ * Used to compare two paths according to the given sort type.
+ * This uses the java.nio.file library, which was introduced in Java 7,
+ * so this isn't available for the JRE5 version.
+ * @since 1.2
+ */
+public class FilePathSortComparator implements Comparator<Path>
+{
+   /**
+    * Creates a new comparator for ordering path listings.
+    * @param sortType the way in which the files should be ordered
+    */ 
+   public FilePathSortComparator(FileSortType sortType)
+   {
+      this.sortType = sortType;
+   }
+
+   /**
+    * Compares two paths according to this object's sort type. 
+    * @param path1 the first path
+    * @param path2 the second path
+    * @return -1 if path1 is considered less than path2, 0 if both are the same
+    * or +1 if path2 is greater than path1, according to the sort
+    * criteria
+    */ 
+   @Override
+   public int compare(Path path1, Path path2)
+   {
+      int idx=-1;
+      int result=0;
+      long date1=0L;
+      long date2=0L;
+      long size1=0L;
+      long size2=0L;
+      String ext1="";
+      String ext2="";
+      FileTime time1=null;
+      FileTime time2=null;
+
+      String name1 = path1.toString();
+      String name2 = path2.toString();
+
+      String basename1 = path1.getName(path1.getNameCount()-1).toString();
+      String basename2 = path2.getName(path2.getNameCount()-1).toString();
+
+      switch (sortType)
+      {
+         case FILE_SORT_NAME_ASCENDING:
+           return name1.compareTo(name2);
+         case FILE_SORT_NAME_DESCENDING:
+           return name2.compareTo(name1);
+         case FILE_SORT_NAME_NOCASE_ASCENDING:
+           return name1.compareToIgnoreCase(name2);
+         case FILE_SORT_NAME_NOCASE_DESCENDING:
+           return name2.compareToIgnoreCase(name1);
+         case FILE_SORT_EXT_ASCENDING:
+
+           idx = basename1.lastIndexOf(".");
+
+           ext1 = idx > -1 ? basename1.substring(idx+1) : "";
+
+           idx = basename2.lastIndexOf(".");
+
+           ext2 = idx > -1 ? basename2.substring(idx+1) : "";
+
+           result = ext1.compareTo(ext2);
+
+            // If the extensions are the same, compare paths instead
+
+           return result == 0 ? name1.compareTo(name2) : result;
+
+         case FILE_SORT_EXT_DESCENDING:
+
+           idx = basename1.lastIndexOf(".");
+
+           ext1 = idx > -1 ? basename1.substring(idx+1) : "";
+
+           idx = basename2.lastIndexOf(".");
+
+           ext2 = idx > -1 ? basename2.substring(idx+1) : "";
+
+           result =  ext2.compareTo(ext1);
+
+           return result == 0 ? name2.compareTo(name1) : result;
+
+         case FILE_SORT_DATE_ASCENDING:
+
+           try
+           {
+              time1 = Files.getLastModifiedTime(path1);
+           }
+           catch (Exception e)
+           {
+              // IO error or security manager has prohibited access
+              return 1;
+           }
+
+           try
+           {
+              time2 = Files.getLastModifiedTime(path2);
+           }
+           catch (Exception e)
+           {
+              // IO error or security manager has prohibited access
+              return -1;
+           }
+
+           return time1.compareTo(time2);
+
+         case FILE_SORT_DATE_DESCENDING:
+
+           try
+           {
+              time1 = Files.getLastModifiedTime(path1);
+           }
+           catch (Exception e)
+           {
+              // IO error or security manager has prohibited access
+              return -1;
+           }
+
+           try
+           {
+              time2 = Files.getLastModifiedTime(path2);
+           }
+           catch (Exception e)
+           {
+              // IO error or security manager has prohibited access
+              return 1;
+           }
+
+           return time2.compareTo(time1);
+
+         case FILE_SORT_SIZE_ASCENDING:
+
+           try
+           {
+              size1 = Files.size(path1);
+              size2 = Files.size(path2);
+           }
+           catch (Exception e)
+           {// file missing or no read access or for some other
+            // reason the file size can't be obtained.
+           }
+
+           return size1 == size2 ? 0 : (size1 < size2 ? -1 : 0);
+
+         case FILE_SORT_SIZE_DESCENDING:
+
+           try
+           {
+              size1 = Files.size(path1);
+              size2 = Files.size(path2);
+           }
+           catch (Exception e)
+           {// file missing or no read access or for some other
+            // reason the file size can't be obtained.
+           }
+
+           return size1 == size2 ? 0 : (size1 > size2 ? -1 : 0);
+      }
+
+      return 0;
+   }
+
+   private FileSortType sortType;
+}


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/FilePathSortComparator.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/FileSortComparator.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/FileSortComparator.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/FileSortComparator.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,170 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+import java.util.Comparator;
+import java.io.File;
+
+/**
+ * Used to compare two file names according to the given sort type.
+ * @since 1.2
+ */
+public class FileSortComparator implements Comparator<String>
+{
+   /**
+    * Creates a new comparator for ordering file listings.
+    * @param baseDir the directory containing the listed files
+    * @param sortType the way in which the files should be ordered
+    */ 
+   public FileSortComparator(File baseDir, FileSortType sortType)
+   {
+      this.baseDir = baseDir;
+      this.sortType = sortType;
+   }
+
+   /**
+    * Compares two files according to this object's sort type. 
+    * @param name1 the name of the first file
+    * @param name2 the name of the second file
+    * @return -1 if name1 is considered less than name2, 0 if both are the same
+    * or +1 if name2 is greater than name1, according to the sort
+    * criteria
+    */ 
+   @Override
+   public int compare(String name1, String name2)
+   {
+      int idx=-1;
+      int result=0;
+      long date1=0L;
+      long date2=0L;
+      long size1=0L;
+      long size2=0L;
+      String ext1="";
+      String ext2="";
+      File file1;
+      File file2;
+
+      switch (sortType)
+      {
+         case FILE_SORT_NAME_ASCENDING:
+           return name1.compareTo(name2);
+         case FILE_SORT_NAME_DESCENDING:
+           return name2.compareTo(name1);
+         case FILE_SORT_NAME_NOCASE_ASCENDING:
+           return name1.compareToIgnoreCase(name2);
+         case FILE_SORT_NAME_NOCASE_DESCENDING:
+           return name2.compareToIgnoreCase(name1);
+         case FILE_SORT_EXT_ASCENDING:
+
+           idx = name1.lastIndexOf(".");
+
+           ext1 = idx > -1 ? name1.substring(idx+1) : "";
+
+           idx = name2.lastIndexOf(".");
+
+           ext2 = idx > -1 ? name2.substring(idx+1) : "";
+
+           result = ext1.compareTo(ext2);
+
+           return result == 0 ? name1.compareTo(name2) : result;
+
+         case FILE_SORT_EXT_DESCENDING:
+
+           idx = name1.lastIndexOf(".");
+
+           ext1 = idx > -1 ? name1.substring(idx+1) : "";
+
+           idx = name2.lastIndexOf(".");
+
+           ext2 = idx > -1 ? name2.substring(idx+1) : "";
+
+           result =  ext2.compareTo(ext1);
+
+           return result == 0 ? name2.compareTo(name1) : result;
+
+         case FILE_SORT_DATE_ASCENDING:
+
+           file1 = new File(baseDir, name1);
+           file2 = new File(baseDir, name2);
+
+           try
+           {
+              date1 = file1.lastModified();
+              date2 = file2.lastModified();
+           }
+           catch (Exception e)
+           {// file missing or no read access or for some other
+            // reason the last modified date can't be obtained.
+           }
+
+           return date1 == date2 ? 0 : (date1 < date2 ? -1 : 0);
+
+         case FILE_SORT_DATE_DESCENDING:
+
+           file1 = new File(baseDir, name1);
+           file2 = new File(baseDir, name2);
+
+           try
+           {
+              date1 = file1.lastModified();
+              date2 = file2.lastModified();
+           }
+           catch (Exception e)
+           {// file missing or no read access or for some other
+            // reason the last modified date can't be obtained.
+           }
+
+           return date1 == date2 ? 0 : (date1 > date2 ? -1 : 0);
+
+         case FILE_SORT_SIZE_ASCENDING:
+
+           file1 = new File(baseDir, name1);
+           file2 = new File(baseDir, name2);
+
+           try
+           {
+              size1 = file1.length();
+              size2 = file2.length();
+           }
+           catch (Exception e)
+           {// file missing or no read access or for some other
+            // reason the file size can't be obtained.
+           }
+
+           return size1 == size2 ? 0 : (size1 < size2 ? -1 : 0);
+
+         case FILE_SORT_SIZE_DESCENDING:
+
+           file1 = new File(baseDir, name1);
+           file2 = new File(baseDir, name2);
+
+           try
+           {
+              size1 = file1.length();
+              size2 = file2.length();
+           }
+           catch (Exception e)
+           {// file missing or no read access or for some other
+            // reason the file size can't be obtained.
+           }
+
+           return size1 == size2 ? 0 : (size1 > size2 ? -1 : 0);
+      }
+
+      return 0;
+   }
+
+
+   private File baseDir;
+   private FileSortType sortType;
+}


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/FileSortComparator.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/FileSortType.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/FileSortType.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/FileSortType.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,131 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+/**
+ * Indicates the ordering of files in listings.
+ * @since 1.2
+ */
+public enum FileSortType
+{
+   FILE_SORT_DEFAULT ("default"), 
+   FILE_SORT_DATE_ASCENDING ("date-ascending", "date", "date-asc"), 
+   FILE_SORT_DATE_DESCENDING ("date-descending", "date-des"),
+   FILE_SORT_SIZE_ASCENDING ("size-ascending", "size", "size-asc"), 
+   FILE_SORT_SIZE_DESCENDING ("size-descending", "size-des"),
+   FILE_SORT_NAME_ASCENDING ("name-ascending", "name", "name-asc"), 
+   FILE_SORT_NAME_DESCENDING ("name-descending", "name-des"),
+   FILE_SORT_NAME_NOCASE_ASCENDING ("iname-ascending", "iname", "iname-asc"), 
+   FILE_SORT_NAME_NOCASE_DESCENDING ("iname-descending", "iname-des"), 
+   FILE_SORT_EXT_ASCENDING ("ext-ascending", "ext", "ext-asc"), 
+   FILE_SORT_EXT_DESCENDING ("ext-descending", "ext-des");
+
+   private final String name, altName1, altName2;
+
+   FileSortType(String name)
+   {
+      this(name, null, null);
+   }
+
+   FileSortType(String name, String altName)
+   {
+      this(name, altName, null);
+   }
+
+   FileSortType(String name, String altName1, String altName2)
+   {
+      this.name = name;
+      this.altName1 = altName1;
+      this.altName2 = altName2;
+   }
+
+   /**
+    * Returns available option names. 
+    */ 
+   private String options()
+   {
+      if (altName1 == null && altName2 == null)
+      {
+         return name;
+      }
+
+      if (altName2 == null)
+      {
+         return String.format("%s (or %s)", name, altName1);
+      }
+
+      return String.format("%s (or %s or %s)", name, altName1, altName2);
+   }
+
+   /**
+    * Checks if the given type matches this option.
+    * @return true if type matches this option
+    */ 
+   private boolean isOption(String type)
+   {
+      return type.equals(name) || type.equals(altName1) 
+        || type.equals(altName2);
+   }
+
+   /**
+    * Returns a list of available sort options used in the command
+    * line invocation.
+    * @return list of options for syntax information.
+    */ 
+   public static String getFileSortOptions()
+   {
+      StringBuilder builder = new StringBuilder();
+
+      for (FileSortType t : FileSortType.values())
+      {
+         if (builder.length() > 0)
+         {
+            builder.append(", ");
+         }
+
+         builder.append(t.options());
+      }
+
+      return builder.toString();
+   }
+
+   /**
+    * Gets the sort type from the given string.
+    * @param type the sort type as provided by the command line
+    * invocation 
+    * @return a FileSortType object that indicates the sort type
+    */ 
+   public static FileSortType getFileSortType(String type)
+   {
+      if (type == null)
+      {
+         return FileSortType.FILE_SORT_DEFAULT;
+      }
+
+      for (FileSortType t : FileSortType.values())
+      {
+         if (t.isOption(type))
+         {
+            return t;
+         }
+      }
+
+      throw new IllegalArgumentException( "Invalid sort type: "+type);
+   }
+
+   public String toString()
+   {
+      return name;
+   }
+}
+


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/FileSortType.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/FileWalkVisitor.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/FileWalkVisitor.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/FileWalkVisitor.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,221 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.nio.file.Path;
+import java.nio.file.Files;
+import java.nio.file.FileVisitResult;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Vector;
+import java.util.Comparator;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * This class is used during a file walk to determine if a directory
+ * may be descended and to add allowed files to the list.
+ * This relies on the java.nio.file library, which was introduced to
+ * Java 7, so this isn't available for the JRE5 version.
+ * @since 1.2
+ */
+public class FileWalkVisitor extends SimpleFileVisitor<Path>
+{
+   /**
+    * Creates a new visitor for a file walk. This will only allow
+    * regular, non-hidden, readable files, where the name matches
+    * the supplied regular expression. The found files are inserted
+    * into the results list according to the comparator.
+    */ 
+   public FileWalkVisitor(TeXOSQuery invoker, String regex, 
+     Comparator<Path> comparator)
+   {
+      this.invoker = invoker;
+      this.comparator = comparator;
+      pattern = Pattern.compile(regex);
+      result = new Vector<Path>();
+   }
+
+   /**
+    * Returns the list built during the file walk. 
+    * @return file list
+    */ 
+   public Vector<Path> getList()
+   {
+      return result;
+   }
+
+   /**
+    * Invoked for a directory before entries in the directory are
+    * visited. 
+    *
+    * Hidden directories are automatically skipped, even if
+    * openin_any is <tt>a</tt>. Symbolic links and directories without 
+    * read access are also skipped.
+    *
+    * @param dir the directory about to be visited
+    * @param attrs the directory's basic attributes
+    * @return the visit result
+    */ 
+   @Override
+   public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+    throws IOException
+   {
+      if (Files.isHidden(dir) || !Files.isReadable(dir)
+        || Files.isSymbolicLink(dir))
+      {
+         invoker.info(String.format(
+           "Walk skipping directory: %s", dir.toString()));
+         return FileVisitResult.SKIP_SUBTREE;
+      }
+
+      // We don't need to check openin_any here as the starting
+      // directory of the walk should already have been checked to
+      // ensure it's on the CWD path.
+
+      return FileVisitResult.CONTINUE;
+   }
+
+
+   /**
+    * Invoked for a file in a directory. 
+    *
+    * Hidden files are automatically skipped, regardless of
+    * openin_any. Files that don't have read access are also skipped
+    * and so are symbolic files.
+    *
+    * @param file a reference to the file
+    * @param attrs the file's basic attributes
+    * @return the visit result
+    */ 
+   @Override
+   public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+    throws IOException
+   {
+      if (Files.isHidden(file) || !Files.isReadable(file)
+          || attrs.isSymbolicLink())
+      {
+         invoker.info(String.format(
+           "Walk skipping file: %s", file.toString()));
+         return FileVisitResult.CONTINUE;
+      }
+
+      // Does the file name match the supplied pattern?
+
+      String name = file.getName(file.getNameCount()-1).toString();
+
+      Matcher m = pattern.matcher(name);
+
+      if (m.matches())
+      {
+         addPath(file);
+      }
+
+      return FileVisitResult.CONTINUE;
+   }
+
+   /**
+    * Inserts path into results list according to the comparator. 
+    * @param path the path to be added to the list
+    */ 
+   private void addPath(Path path)
+   {
+      int n = result.size();
+
+      if (n == 0)
+      {
+         result.add(path);
+         return;
+      }
+
+      for (int i = 0; i < n; i++)
+      {
+         Path thisPath = result.get(i);
+
+         if (comparator.compare(thisPath, path) > 0)
+         {
+            result.add(i, path);
+            return;
+         }
+      }
+
+      result.add(path);
+   }
+
+   /**
+    *Walks the path starting from the given directory, which must be the 
+    *current working directory or a descendent. 
+    */ 
+   public static String walk(TeXOSQuery invoker, 
+        String separator,
+        String regex, 
+        File directory,
+        FileSortType sortType)
+   throws IOException
+   {
+      if (!directory.exists())
+      {
+         throw new FileNotFoundException(
+          String.format("No such file: %s", directory.toString()));
+      }
+
+      if (!directory.isDirectory())
+      {
+         throw new IOException(
+          String.format("Not a directory: %s", directory.toString()));
+      }
+
+      directory = directory.getCanonicalFile();
+
+      File cwd = new File(invoker.getSystemProperty("user.dir", "."));
+
+      if (!cwd.equals(directory) && !invoker.isFileInTree(directory, cwd))
+      {
+         throw new IOException(
+          String.format("Walk must start in current working directory path: %s",
+           cwd.toString()));
+      }
+
+      Path start = directory.toPath();
+
+      FileWalkVisitor visitor = new FileWalkVisitor(invoker, regex,
+       new FilePathSortComparator(sortType));
+
+      Files.walkFileTree(start, visitor);
+
+      Vector<Path> result = visitor.getList();
+
+      StringBuilder builder = new StringBuilder();
+
+      for (Path path : result)
+      {
+         if (builder.length() > 0)
+         {
+            builder.append(separator);
+         }
+
+         builder.append(
+           invoker.escapeFileName(start.relativize(path).toString()));
+      }
+
+      return builder.toString();
+   }
+
+   private TeXOSQuery invoker;
+   private Pattern pattern;
+   private Vector<Path> result;
+   private Comparator<Path> comparator;
+}


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/FileWalkVisitor.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre5.txt
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre5.txt	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre5.txt	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,2 @@
+Main-Class: com/dickimawbooks/texosquery/TeXOSQueryJRE5
+Class-Path: .


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre5.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre7.txt
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre7.txt	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre7.txt	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,2 @@
+Main-Class: com/dickimawbooks/texosquery/TeXOSQueryJRE7
+Class-Path: .


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre7.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre8.txt
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre8.txt	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre8.txt	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,2 @@
+Main-Class: com/dickimawbooks/texosquery/TeXOSQueryJRE8
+Class-Path: .


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/Manifest-jre8.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/QueryAction.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/QueryAction.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/QueryAction.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,448 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+
+/**
+ * Class representing an action to be performed by the application.
+ * @since 1.2
+ */ 
+public abstract class QueryAction implements Serializable
+{
+   public QueryAction()
+   {
+   }
+
+   public QueryAction(String longForm, QueryActionType type,
+      String description)
+   {
+      this(longForm, null, 0, 0, "", type, description);
+   }
+
+   public QueryAction(String longForm, QueryActionType type,
+      String description, int minCompat)
+   {
+      this(longForm, null, 0, 0, "", type, description, minCompat);
+   }
+
+   public QueryAction(String longForm, String shortForm, 
+     QueryActionType type, String description)
+   {
+      this(longForm, shortForm, 0, 0, "", type, description);
+   }
+
+   public QueryAction(String longForm, String shortForm, 
+     QueryActionType type, String description, int minCompat)
+   {
+      this(longForm, shortForm, 0, 0, "", type, description, minCompat);
+   }
+
+   public QueryAction(String longForm, String shortForm, String syntax, 
+      QueryActionType type, String description)
+   {
+      this(longForm, shortForm, 0, 0, syntax, type, description);
+   }
+
+   public QueryAction(String longForm, String shortForm,
+     int numOptional, int numRequired, String syntax, 
+     QueryActionType type, String description)
+   {
+      this(longForm, shortForm, numOptional, numRequired, 
+           syntax, type, description, 0);
+   }
+
+   public QueryAction(String longForm, String shortForm,
+     int numOptional, int numRequired, String syntax, 
+     QueryActionType type, String description, int minCompat)
+   {
+      if (longForm != null)
+      {
+         longName = "--"+longForm;
+      }
+
+      if (shortForm != null)
+      {
+         shortName = "-"+shortForm;
+      }
+
+      optional = numOptional;
+      required = numRequired;
+
+      this.syntax = syntax;
+      this.type = type;
+      this.description = description;
+      this.minCompatibility = minCompat;
+   }
+
+   public boolean isAction(String name)
+   {
+      return name.equals(shortName) || name.equals(longName)
+        || (longName != null && name.startsWith(longName+"="));
+   }
+
+   public int parseArgs(String[] args, int index)
+   throws IllegalArgumentException
+   {
+      if (required > 0)
+      {
+         requiredArgs = new String[required];
+      }
+
+      if (args[index].startsWith(longName+"="))
+      {
+         int idx = args[index].indexOf("=")+1;
+         invokedName = longName;
+
+         if (idx == args[index].length())
+         {
+            if (required == 1)
+            {
+               requiredArgs[0] = "";
+            }
+            else
+            {
+               throw new IllegalArgumentException(String.format(
+                 "Invalid syntax for action '%s'.%nExpected: %s",
+                 invokedName, getUsage(invokedName)));
+            }
+
+            return index+1;
+         }
+
+         String[] sp;
+
+         if (required+optional > 1)
+         {
+            sp = args[index].substring(idx).split(" ");
+         }
+         else
+         {
+            sp = new String[]{args[index].substring(idx)};
+         }
+
+         idx = 0;
+
+         for (int i = 0; i < required; i++)
+         {
+            if (i >= sp.length)
+            {
+               throw new IllegalArgumentException(String.format(
+                 "Invalid syntax for action '%s'.%nExpected: %s",
+                 invokedName, getUsage(invokedName)));
+            }
+
+            requiredArgs[i] = sp[idx++];
+         }
+
+         optionalProvided = 0;
+
+         if (optional > 0)
+         {
+            optionalArgs = new String[optional];
+         }
+
+         for (int i = 0; i < optional; i++)
+         {
+            if (idx >= sp.length)
+            {
+               // no optional arguments, skip
+               break;
+            }
+
+            optionalArgs[optionalProvided++] = sp[idx++];
+         }
+
+         return index+1;
+      }
+      else
+      {
+         invokedName = args[index++];
+
+         for (int i = 0; i < required; i++)
+         {
+            if (index >= args.length)
+            {
+               throw new IllegalArgumentException(String.format(
+                 "Invalid syntax for action '%s'.%nExpected: %s",
+                 invokedName, getUsage(invokedName)));
+            }
+
+            requiredArgs[i] = args[index++];
+         }
+
+         optionalProvided = 0;
+
+         if (optional > 0)
+         {
+            optionalArgs = new String[optional];
+         }
+
+         for (int i = 0; i < optional; i++)
+         {
+            if (index >= args.length || args[index].startsWith("-"))
+            {
+               // no optional arguments, skip
+               break;
+            }
+
+            optionalArgs[optionalProvided++] = args[index++];
+         }
+      }
+
+      return index;
+   }
+
+   public int providedOptionCount()
+   {
+      return optionalProvided;
+   }
+
+   public String getOptionalArgument(int index)
+   {
+      return index < optionalArgs.length ? optionalArgs[index] : null;
+   }
+
+   public String getRequiredArgument(int index)
+   {
+      return requiredArgs[index];
+   }
+
+   public String getInvocation()
+   {
+      StringBuilder builder = new StringBuilder(getInvokedName());
+
+      if (requiredArgs != null)
+      {
+         for (String arg : requiredArgs)
+         {
+            if (arg.contains(" "))
+            {
+               builder.append(String.format(" '%s'", 
+                  arg.replaceAll("'", "\\\\'")));
+            }
+            else
+            {
+               builder.append(String.format(" %s", arg));
+            }
+         }
+      }
+
+      if (optionalArgs != null)
+      {
+         for (String arg : optionalArgs)
+         {
+            if (arg == null) continue;
+
+            if (arg.contains(" "))
+            {
+               builder.append(String.format(" '%s'", 
+                  arg.replaceAll("'", "\\\\'")));
+            }
+            else
+            {
+               builder.append(String.format(" %s", arg));
+            }
+         }
+      }
+
+      return builder.toString();
+   }
+
+   public String getInvokedName()
+   {
+      return invokedName;
+   }
+
+   public QueryActionType getType()
+   {
+      return type;
+   }
+
+   public String getUsage(String name)
+   {
+      return String.format("%s%s",
+        name, syntax == null || "".equals(syntax) ? "" : " "+syntax);
+   }
+
+   /**
+    * Formats the description to fit maximum of 80 character line
+    * width.
+    */ 
+   private String formatDescription()
+   {
+      int n = description.length();
+      int max = MAX_CHARS_PER_LINE-8;
+
+      if (n < max)
+      {
+         return description;
+      }
+
+      StringBuilder builder = new StringBuilder();
+      StringBuilder line = new StringBuilder();
+      StringBuilder word = new StringBuilder();
+
+      for (int i = 0, offset=1; i < n; i += offset)
+      {
+         int codepoint = description.codePointAt(i);
+         offset = Character.charCount(codepoint);
+
+         if (codepoint == ' ')
+         {
+            if (line.length()+word.length()+1 >= max)
+            {
+               builder.append(line);
+               builder.append(String.format("%n"));
+               line = new StringBuilder();
+               line.append('\t');
+            }
+
+            line.append(word);
+            line.append(' ');
+            word = new StringBuilder();
+         }
+         else
+         {
+            word.appendCodePoint(codepoint);
+         }
+      }
+
+      if (line.length()+word.length()+1 >= max)
+      {
+         builder.append(line);
+         builder.append(String.format("%n"));
+         line = new StringBuilder();
+         line.append('\t');
+      }
+
+      line.append(word);
+      builder.append(line);
+
+      return builder.toString();
+   }
+
+   public String help()
+   {
+      String usage;
+
+      if (shortName == null)
+      {
+         usage = getUsage(longName);
+      }
+      else
+      {
+         usage = String.format("%s or %s", getUsage(shortName),
+           getUsage(longName));
+      }
+
+      int n = usage.length();
+
+      return String.format("%s%n\t%s.%n", usage, formatDescription());
+   }
+
+   public String doAction(int compatible) throws IllegalArgumentException
+   {
+      if (compatible < minCompatibility)
+      {
+         throw new IllegalArgumentException(String.format(
+         "'%s' option not available in compatibility mode %d",
+         invokedName, compatible));
+      }
+
+      return action();
+   }
+
+   protected abstract String action();
+
+   /**
+    * Make a copy of this object.
+    */ 
+   public final QueryAction copy()
+   {
+      try
+      {
+         ByteArrayOutputStream byteStr = new ByteArrayOutputStream();
+
+         new ObjectOutputStream(byteStr).writeObject(this);
+
+         QueryAction action = (QueryAction) new ObjectInputStream(
+           new ByteArrayInputStream(byteStr.toByteArray())).readObject();
+         action.same(this);
+     
+         return action;
+      }
+      catch (Exception e)
+      {
+         throw new AssertionError(e);
+      }
+   }
+
+   private void same(QueryAction action)
+   {
+      longName = action.longName;
+      shortName = action.shortName;
+      invokedName = action.invokedName;
+      syntax = action.syntax;
+      optional = action.optional;
+      optionalProvided = action.optionalProvided;
+      required = action.required;
+      type = action.type;
+      description = action.description;
+      minCompatibility = action.minCompatibility;
+
+      if (action.optionalArgs != null)
+      {
+         optionalArgs = new String[action.optionalArgs.length];
+
+         for (int i = 0; i < action.optionalArgs.length; i++)
+         {
+            optionalArgs[i] = action.optionalArgs[i];
+         }
+      }
+
+      if (action.requiredArgs != null)
+      {
+         requiredArgs = new String[action.requiredArgs.length];
+
+         for (int i = 0; i < action.requiredArgs.length; i++)
+         {
+            requiredArgs[i] = action.requiredArgs[i];
+         }
+      }
+   }
+
+   public String getLongName()
+   {
+      return longName;
+   }
+
+   private String longName=null;
+   private String shortName=null;
+   private String invokedName=null;
+   private String syntax="";
+   private int optional=0;
+   private int optionalProvided=0;
+   private int required=0;
+   private String[] requiredArgs=null;
+   private String[] optionalArgs=null;
+   private QueryActionType type;
+   private String description;
+   private int minCompatibility=0;
+
+   private static final int MAX_CHARS_PER_LINE=80;
+}


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/QueryAction.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/QueryActionType.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/QueryActionType.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/QueryActionType.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,19 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+public enum QueryActionType
+{
+   FILE_ACTION, LOCALE_ACTION, GENERAL_ACTION
+}
+


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/QueryActionType.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQuery.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQuery.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQuery.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,4459 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+import java.io.BufferedReader;
+import java.util.Locale;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+import java.util.Vector;
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.text.DecimalFormatSymbols;
+import java.text.Format;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.text.DateFormatSymbols;
+import java.text.NumberFormat;
+import java.text.DecimalFormat;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Serializable;
+
+/**
+ * Application functions. These methods need to be Java version 1.5
+ * compatible. The 1.7 methods need to be in the TeXOSQueryJRE7 class
+ * (which provides the main part of texosquery.jar) and the 1.8 methods in 
+ * TeXOSQueryJRE8 (which provides the main part of texosquery-jre8.jar).
+ *
+ * The texosquery-jre5.jar version should not be considered secure
+ * and is only provided for antiquated systems.
+ * Java 5 and 6 are both deprecated and are now considered security
+ * risks.
+ *
+ * Since this application is designed to be run from TeX, the output
+ * needs to be easy to parse using TeX commands. For this reason,
+ * most exceptions are caught and an empty string is returned. The
+ * TeX code can then check for an empty value to determine failure.
+ * There's a debug mode to print error messages to STDERR to
+ * investigate the reason for failure.
+ * @author Nicola Talbot
+ * @version 1.2
+ * @since 1.0
+ */
+public class TeXOSQuery implements Serializable
+{
+   /**
+    * Constructor.
+    * @param name The application name. 
+    */ 
+   public TeXOSQuery(String name)
+   {
+      this.name = name;
+   }
+
+   /**
+    * Gets the application name. 
+    * @return the application name
+    * @since 1.2
+    */ 
+   public String getName()
+   {
+      return name;
+   }
+
+   /**
+    * Runs kpsewhich and returns the result. This is for single
+    * argument lookups through kpsewhich, such as a file location
+    * or variable value.
+    * @param arg The argument to pass to kpsewhich
+    * @return The result read from the first line of STDIN
+    * @since 1.2
+    */
+   protected String kpsewhich(String arg)
+      throws IOException,InterruptedException
+   {
+      // Create and start the process.
+      Process process = 
+        new ProcessBuilder("kpsewhich", arg).start();
+
+      int exitCode = process.waitFor();
+
+      String line = null;
+
+      if (exitCode == 0)
+      {
+         // kpsewhich completed with exit code 0.
+         // Read STDIN to find the result.
+                
+         InputStream stream = process.getInputStream();
+                    
+         if (stream == null)
+         {
+            throw new IOException(String.format(
+             "Unable to open input stream from process: kpsewhich '%s'",
+             arg));
+         }
+
+         BufferedReader reader = null;
+
+         try
+         {
+            reader = new BufferedReader(new InputStreamReader(stream));
+
+            // only read a single line, nothing further is required
+            // for a variable or file location query.
+            line = reader.readLine();
+         }
+         finally
+         {
+            if (reader != null)
+            {
+               reader.close();
+            }
+         }
+      }
+      else
+      {
+         // kpsewhich failed.
+
+         throw new IOException(String.format(
+           "\"kpsewhich '%s'\" failed with exit code: %d", arg, exitCode));
+      }
+
+      return line;
+   }
+
+    /**
+     * Print message if in debug mode. Message is printed to STDERR
+     * if the debug level is greater than or equal to the given level.
+     * Debugging messages are all written to STDERR rather than
+     * STDOUT so they show up in the transcript rather than being
+     * captured by the shell escape.
+     * @param message Debugging message.
+     * @param level Debugging level.
+     * @since 1.2
+     */
+   public void debug(String message, int level)
+   {
+      if (debugLevel >= level)
+      {
+         System.err.println(String.format("%s: %s", name, message));
+      }
+   }
+
+    /**
+     * Print message if in debug mode. Message is printed to STDERR
+     * if the debug level is 1 or more.
+     * @param message Debugging message.
+     * @since 1.2
+     */
+   public void debug(String message)
+   {
+      debug(message, DEBUG_ERROR_LEVEL);
+   }
+    
+    /**
+     * Message if in debug mode. This is for information rather than
+     * errors. The message is printed to STDERR if the debug level
+     * is 3 or more.
+     * @param message Debugging message.
+     * @since 1.2
+     */
+   public void info(String message)
+   {
+      debug(message, DEBUG_INFO_LEVEL);
+   }
+    
+    /**
+     * Print message and exception if in debug mode. Message is printed to
+     * STDERR if the debug level is greater than or equal to the given level.
+     * The exception may be null. If not null, the exception message
+     * is printed.
+     * @param message Debugging message.
+     * @param excpt Exception.
+     * @param msgLevel Debugging level for message.
+     * @param traceLevel Debugging level for stack trace.
+     * @since 1.2
+     */
+   public void debug(String message, Throwable excpt, int msgLevel,
+      int traceLevel)
+   {
+      debug(message, msgLevel);
+
+      if (excpt != null)
+      {
+         debug(excpt.getMessage(), msgLevel);
+
+         if (debugLevel >= traceLevel)
+         {
+            excpt.printStackTrace();
+         }
+      }
+   }
+
+    /**
+     * Print message and exception if in debug mode. The message
+     * level is 1 and the trace level is 2.
+     * @param message Debugging message.
+     * @param excpt Exception.
+     * @since 1.2
+     */
+   public void debug(String message, Throwable excpt)
+   {
+      debug(message, excpt, DEBUG_ERROR_LEVEL, DEBUG_STACK_TRACE_LEVEL);
+   }
+
+    /**
+     * Checks if file is in or below the given directory. This might
+     * be easier with java.nio.file.Path etc but that requires Java
+     * 1.7, so use the old-fashioned method.
+     * @param file The file being checked
+     * @param dir The directory being searched
+     * @return true if found
+     * @since 1.2
+     */
+   protected boolean isFileInTree(File file, File dir)
+    throws IOException
+   {
+      if (file == null || dir == null) return false;
+
+      file = file.getCanonicalFile();
+      dir = dir.getCanonicalFile();
+
+      File parent = file.getParentFile();
+
+      while (parent != null)
+      {
+         if (parent.equals(dir))
+         {
+            return true;
+         }
+
+         parent = parent.getParentFile();
+      }
+
+      return false;
+   }
+
+   /**
+    * Determine if the given file is hidden.
+    * Java's File.isHidden() method seems to consider "." and ".."
+    * as hidden directories, so this method converts the file to a
+    * canonical path before testing.
+    * @param file The file to check
+    * @return True if the file is considered hidden. 
+     * @since 1.2
+    */ 
+   public boolean isHidden(File file)
+   {
+      try
+      {
+         return file.getCanonicalFile().isHidden();
+      }
+      catch (IOException e)
+      {
+         // file can't be converted to a canonical path, so
+         // consider it hidden
+
+         debug(String.format(
+           "Unable to convert file to a canonical path: ", 
+           file.toString()), e);
+      }
+
+      return true;
+   }
+
+    /**
+     * Queries if the given file may be read according to
+     * openin_any. Since the user may not require any of the file
+     * access functions, the openin variable is only set the first
+     * time this method is used to reduce unnecessary overhead.
+     * kpsewhich is used to lookup the value of openin_any, which
+     * may have one of the following values: a (any), r (restricted,
+     * no hidden files) or p (paranoid, as restricted and no parent
+     * directories and no absolute paths except under $TEXMFOUTPUT)
+     * @param file The file to be checked
+     * @return true if read-access allowed
+     * @since 1.2
+     */
+   public boolean isReadPermitted(File file)
+   {
+      // if file doesn't exist, it can't be read
+      if (file == null || !file.exists())
+      {
+         return false;
+      }
+
+      try
+      {
+         if (openin == OPENIN_UNSET)
+         {
+            //First time this method has been called. Use kpsewhich
+            //to determine the value.
+
+            try
+            {
+               String result = kpsewhich("-var-value=openin_any");
+
+               if ("a".equals(result))
+               {
+                  openin=OPENIN_A;
+               }
+               else if ("r".equals(result))
+               {
+                  openin=OPENIN_R;
+               }
+               else if ("p".equals(result))
+               {
+                  openin=OPENIN_P;
+               }
+               else
+               {
+                  // This shouldn't occur, but just in case...
+                  debug(String.format("Invalid openin_any value: %s",
+                     result));
+                  openin = OPENIN_P;
+               }
+            }
+            catch (Exception e)
+            {
+               // kpsewhich failed, assume paranoid
+               debug("Can't determine openin value, assuming 'p'", e);
+               openin = OPENIN_P;
+            }
+
+            // Now find TEXMFOUTPUT if set (only need this with the
+            // paranoid setting)
+
+            if (openin == OPENIN_P)
+            {
+               String path = null;
+
+               try
+               {
+                  path = System.getenv("TEXMFOUTPUT");
+               }
+               catch (SecurityException e)
+               {
+                  debug("Can't query TEXMFOUTPUT", e);
+               }
+
+               if (path != null && !"".equals(path))
+               {
+                  texmfoutput = new File(fromTeXPath(path));
+
+                  if (!texmfoutput.exists())
+                  {
+                     debug(String.format(
+                           "TEXMFOUTPUT doesn't exist, ignoring: %s",
+                           texmfoutput.toString()));
+                     texmfoutput = null;
+                  }
+                  else if (!texmfoutput.isDirectory())
+                  {
+                     debug(String.format(
+                           "TEXMFOUTPUT isn't a directory, ignoring: %s",
+                           texmfoutput.toString()));
+                     texmfoutput = null;
+                  }
+                  else if (!texmfoutput.canRead())
+                  {
+                     debug(String.format(
+                           "TEXMFOUTPUT doesn't have read permission, ignoring: %s",
+                           texmfoutput.toString()));
+                     texmfoutput = null;
+                  }
+               }
+            }
+         }
+
+         // Now check if the given file can be read according to the
+         // openin setting.
+
+         switch (openin)
+         {
+            case OPENIN_A: 
+              // any file can be read as long as the OS allows it
+               return file.canRead(); 
+            case OPENIN_P:
+              // paranoid check
+
+              if (isFileInTree(file, texmfoutput))
+              {
+                 // file under TEXMFOUTPUT, so it's okay as long
+                 // as it has read permission
+                 return file.canRead();
+              }
+
+              // does the file have an absolute path?
+
+              if (file.isAbsolute())
+              {
+                 debug(String.format(
+                   "Read access forbidden by openin_any=%c (has absolute path outside TEXMFOUTPUT): %s",
+                   openin, file));
+                 return false;
+              }
+
+              // is the file outside the cwd?
+              File cwd = new File(getSystemProperty("user.dir", "."));
+
+              if (file.getParentFile() != null && !isFileInTree(file, cwd))
+              {
+                 debug(String.format(
+                   "Read access forbidden by openin_any=%c (outside cwd path): %s",
+                   openin, file));
+                 return false;
+              }
+
+            // no break, fall through to restricted check
+            case OPENIN_R:
+
+              if (isHidden(file))
+              {
+                 // hidden file so not permitted
+                 debug(String.format(
+                   "Read access forbidden by openin_any=%c (hidden file): %s",
+                   openin, file));
+                 return false;
+              }
+
+            break;
+            default:
+              // this shouldn't happen, but just in case...
+              debug(String.format("Invalid openin value: %d", openin));
+              // don't allow, something's gone badly wrong
+              return false;
+         }
+
+         // return read access
+         return file.canRead();
+      }
+      catch (Exception e)
+      {
+         // Catch all exceptions
+         debug(String.format("Read permission check failed: %s", file), e);
+
+         // Can't permit read if something's gone wrong here.
+         return false;
+      }
+   }
+
+    /**
+     * Gets the given system property or the default value.
+     * Returns the default value if the property isn't set or can't be accessed.
+     * @param propName The property name
+     * @param defValue The default value
+     * @return The property value or the default if unavailable
+     * @since 1.2
+     */
+   public String getSystemProperty(String propName, String defValue)
+   {
+      try
+      {
+         return System.getProperty(propName, defValue);
+      }
+      catch (SecurityException e)
+      {
+         // The security manager doesn't permit access to this property.
+
+         debug(String.format("Unable to access property: %s", propName), e);
+         return defValue;
+      }
+   }
+
+    /**
+     * Escapes potentially problematic characters from a string that will be
+     * expanded when input by TeX's shell escape.
+     * 
+     * Some of the methods in this class return TeX code. Those
+     * returned values shouldn't be escaped as it would interfere
+     * with the code, so just use this method on information
+     * directly obtained from Java. This will typically be either
+     * file names (in which case the characters within the string
+     * must all be "letter" or "other") or regular text for use in
+     * the document (such as dates or times, in which case the
+     * characters may be active to allow them to be correctly
+     * typeset, such as UTF-8 characters with inputenc.sty).
+     *
+     * The date-time and numeric patterns (such as "YYYY-MM-DD"
+     * or "#,##0.0") are dealt with elsewhere as they need different treatment.
+     *
+     * \\TeXOSQuery locally defines commands for characters
+     * used in file names (catcode 12). These are all in the form
+     * \\fxxx (such as \\fhsh for a literal hash). Since the
+     * texosquery.tex code is designed to be generic we can't assume
+     * the eTeX \\detokenize primitive is available. This does,
+     * however, assume that the document author hasn't changed the
+     * category codes of the ASCII alphanumerics, but that ought to
+     * be a safe assumption.
+     *
+     * We also have commands for characters intended for use in document
+     * text, which shouldn't be interpreted literally. These are all
+     * in the form \\txxx (such as \\thsh which should expand to
+     * \#).
+     *
+     * The regular space \\tspc guards against a space occurring after
+     * a character that needs to be converted to a control sequence.
+     * (For example "# 1" becomes "\\thsh \\tspc 1")
+     * There's also a literal space \\fspc to guard against spaces
+     * in file names.
+     *
+     * This should take care of any insane file-naming schemes, such
+     * as <tt>bad~file name#1.tex</tt>, <tt>stupid {file} name.tex</tt>,
+     * <tt style="white-space: pre;">spaced    out  file #2.tex</tt>,
+     * <tt>file's stupid name.tex</tt>.
+     *
+     * To help protect against input encoding problems, non-ASCII
+     * characters are wrapped in \\twrp (regular text) or \\fwrp
+     * (file names). \\TeXOSQuery locally redefines these to
+     * \\texosquerynonasciiwrap and \\texosquerynonasciidetokwrap 
+     * which may be used to provide some protection or conversion from one
+     * encoding to another, if required.
+     * 
+     * For example, the language "français" would be returned as
+     * "fran\\twrp{ç}ais", which can be typeset directly with
+     * XeTeX or LuaTeX or through active characters with
+     * inputenc.sty, but the directory called <tt>Françcois</tt> would be
+     * returned as <tt>Fran\\fwrp{ç}cois</tt>, which will try to
+     * detokenize the ç character.
+     *
+     * @param string Input string.
+     * @param isRegularText true if the string represents text (for example, 
+     * month names), set to false if string is something literal,
+     * such as a file name.
+     * @return The processed string
+     * @since 1.2
+     */
+   public String escapeSpChars(String string, boolean isRegularText)
+   {
+      if (compatible < 2)
+      {
+         return escapeHash(string);
+      }
+
+      StringBuilder builder = new StringBuilder();
+
+      // This iterates over Unicode characters so we can't use a simple
+      // i++ increment. The offset is obtained from Character.charCount
+      for (int i = 0, n = string.length(); i < n; )
+      {
+         int codepoint = string.codePointAt(i);
+         i += Character.charCount(codepoint);
+
+         builder.append(escapeSpChars(codepoint, isRegularText));
+      }
+
+      return builder.toString();
+   }
+
+    /**
+     * Escapes file name. This should already have had the directory
+     * divider changed to a forward slash where necessary.
+     * @param filename Input string.
+     * @return String with characters escaped.
+     * @since 1.2
+     */
+   public String escapeFileName(String filename)
+   {
+      return escapeSpChars(filename, false);
+   }
+
+    /**
+     * Escapes regular text.
+     * @param string Input string.
+     * @return String with characters escaped.
+     * @since 1.2
+     */
+   public String escapeText(String string)
+   {
+      return escapeSpChars(string, true);
+   }
+
+    /**
+     * Escapes regular text.
+     * @param codepoint Input Unicode character.
+     * @return String with characters escaped.
+     * @since 1.2
+     */
+   public String escapeText(int codepoint)
+   {
+      return escapeSpChars(codepoint, true);
+   }
+
+    /**
+     * Escapes the given Unicode character.
+     * All ASCII punctuation characters have a literal and textual
+     * command to represent them in file names and document text,
+     * respectively. The literal (file name) commands are prefixed
+     * with "f" and the textual commands are prefixed with "t".
+     * None of the control codes should appear in any of the
+     * results, but they are checked for completeness.
+     * @param codePoint Input code point.
+     * @param isRegularText true if the character is in a string representing
+     * text, set to false if string is a file name etc
+     * @return String with character escaped.
+     * @since 1.2
+     */
+   public String escapeSpChars(int codepoint, boolean isRegularText)
+   {
+      return escapeSpChars(codepoint, isRegularText ? "t" : "f");
+   }
+
+    /**
+     * Escapes the given Unicode character.
+     * As above but with the prefix supplied.
+     * @param codePoint Input code point.
+     * @param prefix The control sequence name prefix.
+     * @return String with character escaped.
+     * @since 1.2
+     */
+   public String escapeSpChars(int codepoint, String prefix)
+   {
+      switch (codepoint)
+      {
+         case '!': return String.format("\\%sexc ", prefix);
+         case '"': return String.format("\\%sdqt ", prefix);
+         case '#': return String.format("\\%shsh ", prefix);
+         case '$': return String.format("\\%sdol ", prefix);
+         case '%': return String.format("\\%spct ", prefix);
+         case '&': return String.format("\\%samp ", prefix);
+         case '\'': return String.format("\\%sapo ", prefix);
+         case '(': return String.format("\\%sopb ", prefix);
+         case ')': return String.format("\\%sclb ", prefix);
+         case '*': return String.format("\\%sast ", prefix);
+         case '+': return String.format("\\%spls ", prefix);
+         case ',': return String.format("\\%scom ", prefix);
+         case '-': return String.format("\\%shyn ", prefix);
+         case '.': return String.format("\\%sdot ", prefix);
+         case '/': return String.format("\\%sslh ", prefix);
+         case ':': return String.format("\\%scln ", prefix);
+         case ';': return String.format("\\%sscl ", prefix);
+         case '<': return String.format("\\%sles ", prefix);
+         case '=': return String.format("\\%seql ", prefix);
+         case '>': return String.format("\\%sgre ", prefix);
+         case '?': return String.format("\\%sque ", prefix);
+         case '@': return String.format("\\%satc ", prefix);
+         case '[': return String.format("\\%sosb ", prefix);
+         case '\\': return String.format("\\%sbks ", prefix);
+         case ']': return String.format("\\%scsb ", prefix);
+         case '^': return String.format("\\%scir ", prefix);
+         case '_': return String.format("\\%susc ", prefix);
+         case '`': return String.format("\\%sgrv ", prefix);
+         case '{': return String.format("\\%slbr ", prefix);
+         case '}': return String.format("\\%srbr ", prefix);
+         case '~': return String.format("\\%stld ", prefix);
+         case ' ': return String.format("\\%sspc ", prefix);
+         // These next few cases shouldn't occur, but
+         // check for them anyway.
+         case 0x007F: return ""; // delete control
+         case 0x0009: return "^^I";// tab
+         case 0x000A: // lf (fall through to cr)
+         case 0x000C: // ff
+         case 0x000D: return " "; // cr
+         default:
+
+           if (codepoint < 32)
+           {
+              return ""; // strip control characters
+           }
+           else if (codepoint >= 32 && codepoint <= 126)
+           {
+              // ASCII letters and digits (all ASCII punctuation
+              // dealt with above).
+              return String.format("%c", codepoint);
+           }
+           else
+           {
+              // Outside Basic Latin set.
+              return String.format("\\%swrp{%c}", prefix, codepoint);
+           }
+      }
+   }
+
+    /**
+     * Escapes any hashes in input string.
+     * Now only used if compatibility level is less than 2 (pre
+     * texosquery version 1.2).
+     * @param string Input string.
+     * @return String with hash escaped.
+     */
+   public static String escapeHash(String string)
+   {
+      return string.replaceAll("#", "\\\\#");
+   }
+
+    /**
+     * Escapes hash from input character.
+     * No longer required.
+     * @param c Input character.
+     * @return String with hash escaped.
+     */
+   public static String escapeHash(char c)
+   {
+      return String.format("%s", c == '#' ? "\\#" : c);
+   }
+
+    /**
+     * Gets the OS name. As far as I can tell, the "os.name"
+     * property should return a string that just contains Basic
+     * Latin upper or lower case letters, so we don't need to worry
+     * about special characters.
+     * @return The OS name as string.
+     */
+   public String getOSname()
+   {
+      return getSystemProperty("os.name", "");
+   }
+
+    /**
+     * Gets the OS architecture. As with the OS name, this shouldn't
+     * contain any special characters.
+     * @return The OS architecture as string.
+     */
+   public String getOSarch()
+   {
+      return getSystemProperty("os.arch", "");
+   }
+
+    /**
+     * Gets the OS version. This may contain an underscore, so treat
+     * it like a file name.
+     * @return The OS version as string.
+     */
+   public String getOSversion()
+   {
+      return escapeFileName(getSystemProperty("os.version", ""));
+   }
+
+    /**
+     * Converts the filename string to TeX path. Since this is designed to work
+     * within TeX, backslashes in paths need to be replaced with forward
+     * slashes.
+     * @param filename The filename string.
+     * @return TeX path.
+     */
+   public String toTeXPath(String filename)
+   {
+      if (filename == null)
+      {
+         // This shouldn't happen, but just in case...
+         try
+         {
+            // throw so we can get a stack trace for debugging
+            throw new NullPointerException();
+         }
+         catch (NullPointerException e)
+         {
+            debug("null file name", e);
+         }
+
+         return "";
+      }
+
+      // If the OS uses backslash as the directory divider,
+      // convert all backslashes to forward slashes. The Java regex
+      // means that we need four backslashes to represent a single literal
+      // backslash.
+
+      if (File.separatorChar == BACKSLASH)
+      {
+         filename = filename.replaceAll("\\\\", "/");
+      }
+
+      return escapeFileName(filename);
+   }
+
+    /**
+     * Converts the TeX path to the OS representation.
+     * The file name will typically be passed as a parameter through
+     * \\TeXOSQuery so it will have forward slashes as the directory
+     * divider regardless of the OS (as per \\input and
+     * \\includegraphics). This method converts the TeX file name
+     * into one that's valid for the OS.
+     * @param filename The filename string.
+     * @return The OS representation.
+     */
+   public String fromTeXPath(String filename)
+   {
+      if (filename == null)
+      {
+         // This shouldn't happen, but just in case...
+         try
+         {
+            throw new NullPointerException();
+         }
+         catch (NullPointerException e)
+         {
+            debug("null file name", e);
+         }
+
+         return "";
+      }
+
+      if (compatible < 2)
+      {
+         if (File.separatorChar == BACKSLASH)
+         {
+            return filename.replaceAll("/", "\\\\");
+         }
+
+         return filename;
+      }
+
+      // The file name may contain awkward characters. For example,
+      // the user may have a file called imagefile#1.png and
+      // they're trying to do, say,
+      // \TeXOSQuery{\result}{-p imagefile#1.png}
+      // If the shell escape is using bash, the hash will be
+      // interpreted as a comment character, so the argument
+      // received by texosquery will actually be "imagefile"
+      // since the "#1.png" part will be interpreted as a comment.
+
+      // The user can protect the # from the shell using
+      // \TeXOSQuery{\result}{-p imagefile\string\#1.png}
+      // which bash will pass as 'imagefile#1.png', but
+      // perhaps another type of shell might pass it literally
+      // as 'imagefile\#1.png', so the following allows for
+      // that by simply stripping all backslashes from the file name.
+      // (The file name is always supplied with forward slashes as
+      // the directory divider regardless of the operating system.)
+      // We can substitute the divider at this point as well.
+ 
+      StringBuilder builder = new StringBuilder();
+
+      for (int i = 0, n = filename.length(), offset=1; i < n; i+=offset)
+      {
+         int codepoint = filename.codePointAt(i);
+         offset = Character.charCount(codepoint);
+
+         int nextIndex = i+offset;
+         int nextCodePoint = (nextIndex<n ? filename.codePointAt(nextIndex):0);
+
+         if (codepoint == '/')
+         {
+            builder.appendCodePoint(File.separatorChar);
+         }
+         if (codepoint == BACKSLASH)
+         {
+            // Would anyone really want a literal backslash in a
+            // file name? Allow a double backslash to represent a
+            // literal backslash but only if the OS directory
+            // divider isn't a backslash. Otherwise discard
+            // this character.
+
+            if (File.separatorChar != BACKSLASH && nextCodePoint == BACKSLASH)
+            {
+               builder.appendCodePoint(codepoint);
+               i = nextIndex;
+               offset = Character.charCount(nextCodePoint);
+            }
+            else if (nextCodePoint == '/')
+            {
+               // Would anyone want a literal forward slash? Allow a
+               // slash to be escaped just in case.
+               builder.appendCodePoint('/');
+               i = nextIndex;
+               offset = Character.charCount(nextCodePoint);
+            }
+         }
+         else
+         {
+            builder.appendCodePoint(codepoint);
+         }
+      }
+
+      return builder.toString();
+   }
+
+    /**
+     * Gets a file representation from a filename string. If the
+     * provided file doesn't have a parent and if it's not found in the
+     * current directory, kpsewhich will be used to locate it on
+     * TeX's path. The provided file name is assumed to have been
+     * passed through commands provided by texosquery.tex so the
+     * directory dividers should be forward slashes, even if the OS
+     * uses backslashes. The returned file may not exist. Any method
+     * that uses this method needs to check for existence.
+     * @param filename Filename string.
+     * @return File representation 
+     * @since 1.2
+     */
+   public File fileFromTeXPath(String filename)
+   {
+      // Convert from TeX to the OS path representation.
+      filename = fromTeXPath(filename);
+
+      File file = new File(filename);
+
+      if (!file.exists() && file.getParent() == null)
+      {
+         // If the file doesn't exist and it doesn't have a parent
+         // directory, use kpsewhich to find it.
+
+         try
+         {
+            String result = kpsewhich(filename);
+
+            if (result != null && !"".equals(result))
+            {
+               file = new File(fromTeXPath(result));
+            }
+         }
+         catch (Exception exception)
+         {
+            // Catch all exceptions
+            debug(String.format("kpsewhich couldn't find the file: %s",
+                                filename),
+                  exception);
+
+            // The File object will be returned even though the file
+            // can't be found.
+         }
+      }
+
+      return file;
+   }
+
+    /**
+     * Gets the user's home directory.
+     * @return The user home as string.
+     */
+   public String getUserHome()
+   {
+      File dir = new File(getSystemProperty("user.home", ""));
+
+      if (!isReadPermitted(dir))
+      {
+         debug("Read access not permitted for the home directory");
+         return "";
+      }
+
+      // The resulting path needs to be converted to a TeX path.
+      return toTeXPath(dir.getAbsolutePath());
+   }
+
+    /**
+     * Gets the current working directory.
+     * @return The current working directory.
+     */
+   public String getCwd()
+   {
+      File dir = new File(getSystemProperty("user.dir", "."));
+
+      if (!isReadPermitted(dir))
+      {
+         // perhaps the current directory is hidden?
+         debug("Read access not permitted for the current directory");
+         return "";
+      }
+
+      // The resulting path needs to be converted to a TeX path.
+      return toTeXPath(dir.getAbsolutePath());
+   }
+
+    /**
+     * Gets the temporary directory.
+     * @return Temporary directory.
+     */
+   public String getTmpDir()
+   {
+      String filename = getSystemProperty("java.io.tmpdir", "");
+
+      if ("".equals(filename))
+      {
+         // Not set
+         return "";
+      }
+
+      File dir = new File(filename);
+
+      if (!isReadPermitted(dir))
+      {
+         debug(String.format("Read access not permitted for directory: %s", 
+           dir));
+         return "";
+      }
+
+      // The resulting path needs to be converted to a TeX path.
+      return toTeXPath(filename);
+   }
+
+   /**
+    * Gets the week year for the given calendar.
+    * Calendar.getWeekYear() was added to Java 7, so this defaults
+    * to the year instead. This method needs to be overridden in
+    * TeXOSQueryJRE7 and TeXOSQueryJRE8.
+    * @return The week year
+    * @since 1.2
+    */ 
+   public int getWeekYear(Calendar cal)
+   {
+      return cal.get(Calendar.YEAR);
+   }
+
+   /**
+    * Converts the day of week index returned by
+    * Calendar.DAY_OF_WEEK to Monday=1 based indexing.
+    * @param index the day of week index obtained from Calendar.DAY_OF_WEEK
+    * @return index with Monday=1 as the base
+    * @since 1.2
+    */ 
+   private int getDayOfWeekIndex(int index)
+   {
+      switch (index)
+      {
+         case Calendar.MONDAY: return 1;
+         case Calendar.TUESDAY: return 2;
+         case Calendar.WEDNESDAY: return 3;
+         case Calendar.THURSDAY: return 4;
+         case Calendar.FRIDAY: return 5;
+         case Calendar.SATURDAY: return 6;
+         case Calendar.SUNDAY: return 7;
+      }
+
+      try
+      {
+        // this shouldn't happen
+        throw new IllegalArgumentException(
+          String.format("Invalid day of week index: %d", index));
+      }
+      catch (Exception e)
+      {
+         debug(e.getMessage(), e);
+      }
+
+      return 0;
+   }
+
+   /**
+    * Gets all the date-time data for the current date-time. 
+    * @return data in format that can be read by \\texosqueryfmtdatetime
+    * @since 1.2
+    */ 
+   public String getDateTimeData()
+   {
+      Calendar cal = Calendar.getInstance();
+      cal.setTimeInMillis(now.getTime());
+
+      int hourH = cal.get(Calendar.HOUR_OF_DAY);
+
+      int hourk = (hourH == 0 ? 24 : hourH);
+
+      int hourK = cal.get(Calendar.HOUR);
+
+      int hourh = (hourK == 0 ? 12 : hourK);
+
+      TimeZone timeZone = cal.getTimeZone();
+      boolean isDaylightSaving = timeZone.inDaylightTime(now);
+
+      int timezoneoffset = cal.get(Calendar.ZONE_OFFSET);
+
+      if (isDaylightSaving)
+      {
+         timezoneoffset += cal.get(Calendar.DST_OFFSET);
+      }
+
+      // convert from offset millisec to hours and minutes
+      // (ignore left-over seconds and milliseconds)
+
+      int tzm = timezoneoffset/60000;
+
+      int tzh = tzm/60;
+
+      tzm = tzm % 60;
+
+      return String.format(
+       "{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{%d}{{%d}{%d}{%s}{%d}}",
+       cal.get(Calendar.ERA),
+       cal.get(Calendar.YEAR),
+       getWeekYear(cal),
+       cal.get(Calendar.MONTH)+1,
+       cal.get(Calendar.WEEK_OF_YEAR),
+       cal.get(Calendar.WEEK_OF_MONTH),
+       cal.get(Calendar.DAY_OF_YEAR),
+       cal.get(Calendar.DAY_OF_MONTH),
+       cal.get(Calendar.DAY_OF_WEEK_IN_MONTH),
+       getDayOfWeekIndex(cal.get(Calendar.DAY_OF_WEEK)),// Monday=1, etc
+       cal.get(Calendar.AM_PM),
+       hourH, hourk, hourK, hourh,
+       cal.get(Calendar.MINUTE),
+       cal.get(Calendar.SECOND),
+       cal.get(Calendar.MILLISECOND),
+       tzh, tzm, timeZone.getID(), 
+       isDaylightSaving ? 1 : 0);
+   }
+
+   /**
+    * Get the time zone names for the given locale.
+    * The data for each zone is provided in the form
+    * {id}{short name}{long name}{short dst name}\marg{long dst name}
+    * @param localeTag The locale 
+    * @return list of zone information for the locale
+    * @since 1.2
+    */ 
+
+   public String getTimeZones(String localeTag)
+   {
+      Locale locale;
+
+      if (localeTag == null || "".equals(localeTag))
+      {
+         locale = Locale.getDefault();
+      }
+      else
+      {
+         locale = getLocale(localeTag);
+      }
+
+      StringBuilder builder = new StringBuilder();
+
+      String[] zones = TimeZone.getAvailableIDs();
+
+      for (int i = 0; i < zones.length; i++)
+      {
+         TimeZone tz = TimeZone.getTimeZone(zones[i]);
+
+         builder.append(String.format("{{%s}{%s}{%s}{%s}{%s}}",
+          escapeFileName(tz.getID()), 
+          escapeText(tz.getDisplayName(false, TimeZone.SHORT, locale)),
+          escapeText(tz.getDisplayName(false, TimeZone.LONG, locale)),
+          escapeText(tz.getDisplayName(true, TimeZone.SHORT, locale)),
+          escapeText(tz.getDisplayName(true, TimeZone.LONG, locale))));
+      }
+
+      return builder.toString();
+   }
+
+    /**
+     * Gets the current date in PDF format. (The same format as
+     * \pdfcreationdate.)
+     * @return The current date.
+     */
+   public String pdfnow()
+   {
+      Calendar cal = Calendar.getInstance();
+      cal.setTimeInMillis(now.getTime());
+
+      return pdfDate(cal);
+   }
+
+    /**
+     * Gets the date in PDF format.
+     * @param calendar A calendar object.
+     * @return Date in PDF format.
+     */
+   public String pdfDate(Calendar calendar)
+   {
+       String tz = String.format("%1$tz", calendar);
+
+       if (compatible < 2)
+       {
+          return String.format(
+               "D:%1$tY%1$tm%1td%1$tH%1$tM%1$tS%2$s'%3$s'",
+               calendar,
+               tz.substring(0, 3),
+               tz.substring(3));
+       }
+       else
+       {
+          // Need to ensure D : + or - and ' have category code 12
+          // The simplest way to deal with this is to pass
+          // everything after the "D" to escapeFileName since
+          // the sign is hidden in the format.
+
+          return String.format("\\pdfd %s",
+             escapeFileName(
+               String.format(
+               ":%1$tY%1$tm%1td%1$tH%1$tM%1$tS%2$s'%3$s'",
+               calendar,
+               tz.substring(0, 3),
+               tz.substring(3))
+             )); 
+
+       }
+   }
+
+   /**
+    * Gets the date of a file in PDF format.
+    * @param file File.
+    * @return The date in PDF format.
+    */
+   public String pdfDate(File file)
+   {
+      try
+      {
+         if (!file.exists())
+         {
+            debug(String.format(
+                 "Unable to get timestamp for file (no such file): %s",
+                 file.toString()));
+            return "";
+         }
+
+         if (!isReadPermitted(file))
+         {
+            debug(String.format("No read access for file: %s", file));
+            return "";
+         }
+        
+         long millisecs = file.lastModified();
+            
+         if (millisecs > ZERO)
+         {
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTimeInMillis(millisecs);
+
+            return pdfDate(calendar);
+         }
+
+         // I/O error has occurred (already checked for file
+         // existence and read permission, so it's something weird).
+         // Perhaps the file is corrupt or the user has an eccentric OS that
+         // doesn't support file modification timestamps.
+         debug(String.format(
+               "Unable to get timestamp for file (I/O error): %s",
+               file.toString()));
+      }
+      catch (Exception exception)
+      {
+         // Catch all possible exceptions, including security
+         // exception.
+
+         debug(String.format(
+              "Unable to get timestamp for file: %s",
+              file.toString()),
+              exception);
+      }
+
+      // Unsuccessful
+      return "";
+   }
+
+    /**
+     * Gets the file length in bytes.
+     * @param file The file.
+     * @return The length as a string.
+     */
+   public String getFileLength(File file)
+   {
+      try
+      {
+         if (!file.exists())
+         {
+            debug(String.format(
+              "Unable to get the size of file (no such file): %s",
+              file.toString()));
+            return "";
+         }
+        
+         if (!isReadPermitted(file))
+         {
+            debug(String.format("No read access for file: %s", file));
+            return "";
+         }
+        
+         return String.format("%d", file.length());
+
+      }
+      catch (Exception exception)
+      {
+         // Catch all possible exceptions, including security
+         // exceptions.
+
+         debug(String.format("Unable to get the size of file: %s",
+               file.toString()),
+               exception);
+      }
+
+      // Unsuccessful
+      return "";
+   }
+
+   /**
+    * Sort the given list of file names. Java 8 has a better sort
+    * method so this is overridden in the TeXOSQueryJRE8 class.
+    * @param list The list of file names to be sorted
+    * @param directory The directory in which the files are
+    * contained
+    * @param sortType How to order the list
+    */ 
+    public void sortFileList(String[] list, File directory, 
+      FileSortType sortType)
+    {
+       Arrays.sort(list, new FileSortComparator(directory, sortType));
+    }
+
+    /**
+     * Checks the directory used for file listings. The JRE5 version
+     * just returns the argument. The other versions convert the
+     * directory to a canonical path and check it's permitted. (The
+     * JRE7 and 8 versions are more restrictive.)
+     */ 
+    protected File checkDirectoryListing(File dir) throws IOException
+    {
+       return dir;
+    }
+
+    /**
+     * Gets the list of files from a directory. This uses
+     * getFilterFileList to filter out files prohibited by the
+     * openin_any setting. Note that the separator isn't escaped as
+     * the user may want some actual TeX code. For example, the
+     * separator might need to be a double backslash.
+     * The user will need to take the appropriate precautions
+     * to protect it from expansion during the shell escape.
+     * @param separator Separator.
+     * @param directory Directory (root not permitted).
+     * @param sortType How to sort the file list
+     * @param listType The type of files to include in the list
+     * @return List as a string.
+     */
+   public String getFileList(String separator, File directory, 
+            FileSortType sortType, FileListType listType)
+   {
+      return getFilterFileList(separator, ".*", directory, sortType, listType);
+   }
+
+    /**
+     * Gets a filtered list of files from directory.
+     * Files with read access prohibited by openin_any or the OS are
+     * omitted from the list. The regular expression is anchored,
+     * so ".*foo" will only match file names that end with "foo".
+     *
+     * For security reasons, as from v1.2, the directory must have a
+     * parent (otherwise malicious code could try to perform a
+     * recursive search across the filing system, which would hog
+     * resources). To allow for backward compatibility, the insecure
+     * JRE5 version doesn't have this new restriction.
+     *
+     * @param separator Separator.
+     * @param regex Regular expression.
+     * @param directory Directory.
+     * @param sortType How to sort the file list
+     * @param listType The type of files to include in the list
+     * @return Filtered list as string.
+     */
+   public String getFilterFileList(String separator,
+            final String regex, File directory, 
+            FileSortType sortType, final FileListType listType)
+   {
+      if (directory == null)
+      {
+         // shouldn't happen, but just in case...
+
+         debug("Unable to list contents (null directory)");
+         return "";
+      }
+
+      // Check for existence and that the given File is actually a directory.
+
+      if (!directory.exists())
+      {
+         debug(String.format(
+               "Unable to list contents (no such directory): %s",
+               directory.toString()));
+         return "";
+      }
+
+      if (!directory.isDirectory())
+      {
+         debug(String.format(
+               "Unable to list contents (not a directory): %s",
+               directory.toString()));
+         return "";
+      }
+
+      try
+      {
+         // security check (converts to full canonical path with JRE7 or 8)
+
+         directory = checkDirectoryListing(directory);
+      }
+      catch (Exception e)
+      {
+         debug(String.format("Unable to list contents of: %s",
+                directory.getAbsolutePath()), e);
+         return "";
+      }
+
+      if (!isReadPermitted(directory))
+      {
+         debug(String.format("No read access for directory: %s", directory));
+         return "";
+      }
+
+      if ((regex == null) || ("".equals(regex)))
+      {
+         // null or empty regular expression forbidden (use ".*" for
+         // all files, "" means only match a file with an empty
+         // filename, which doesn't make much sense).
+
+         debug("Null or empty regular expression in getFilterFileList");
+         return "";
+      }
+
+      StringBuilder builder = new StringBuilder();
+        
+      try
+      {
+         String[] list = directory.list(
+            new FilenameFilter()
+            {
+               @Override
+               public boolean accept(File dir, String name)
+               {
+                  File file = new File(dir, name);
+ 
+                  if (!isReadPermitted(file))
+                  {
+                     debug(String.format("No read access for file: %s", file));
+                     return false;
+                  }
+
+                  switch (listType)
+                  {
+                     case FILE_LIST_DIRECTORIES_ONLY:
+
+                        if (!file.isDirectory()) return false;
+
+                     break;
+                     case FILE_LIST_REGULAR_FILES_ONLY:
+
+                        if (file.isDirectory()) return false;
+
+                     break;
+                  }
+
+                  return name.matches(regex);
+               }
+            });
+
+         if (list != null)
+         {
+            if (sortType != FileSortType.FILE_SORT_DEFAULT)
+            {
+               sortFileList(list, directory, sortType);
+            }
+
+            for (int i = 0; i < list.length; i++)
+            {
+               if (i > 0)
+               {
+                  builder.append(separator);
+               }
+                            
+               if (list[i].contains(separator))
+               {
+                  builder.append(String.format("{%s}", escapeFileName(list[i])));
+               }
+               else
+               {
+                  builder.append(escapeFileName(list[i]));
+               }
+            }
+                        
+         }
+
+         return builder.toString();
+      }
+      catch (Exception exception)
+      {
+         // Catch all possible exceptions
+         debug(String.format("Unable to list contents of '%s' using regex: %s",
+               directory.toString(), regex),
+               exception);
+      }
+
+      // Unsuccessful
+      return "";
+   }
+
+   /**
+    * Recursive file listing. This method must have the CWD or a
+    * descendent as the starting directory. It will return list of
+    * files relative to the starting directory where the basename
+    * matches the supplied regular expression. Hidden files/directories 
+    * and symbolic links are skipped regardless of the openin_any setting.
+    * Files without read access are also omitted from the list.
+    *
+    * This method requires the java.nio.file library, which was
+    * introduced in Java 7, so this isn't available for the JRE5
+    * version.
+    *
+    * @param separator separator to use in returned list
+    * @param regex regular expression used to match file basenames
+    * @param directory starting directory (must be cwd or a
+    * descendent of cwd)
+    * @return list of relative paths
+    */ 
+   public String walk(String separator,
+            String regex, File directory, 
+            FileSortType sortType)
+   {
+      debug("walk requires at least JRE 7 version");
+      return "";
+   }
+
+    /**
+     * Gets the file URI. 
+     * @param file The file.
+     * @return The URI.
+     */
+   public String fileURI(File file)
+   {
+      if (file == null)
+      {
+         // This shouldn't happen, but just in case...
+         debug("null file passed to fileURI");
+         return "";
+      }
+
+      if (!file.exists())
+      {
+         debug(String.format("can't obtain URI of file (no such file): %s",
+            file.toString()));
+         return "";
+      }
+        
+      if (!isReadPermitted(file))
+      {
+         debug(String.format("No read access for file: %s", file));
+         return "";
+      }
+        
+      try
+      {
+         return escapeFileName(file.getCanonicalFile().toURI().toString());
+      }
+      catch (Exception exception)
+      {
+         debug(String.format("Can't obtain URI of file: %s", file.toString()),
+          exception);
+      }
+
+      // Unsuccessful
+      return "";
+    }
+
+    /**
+     * Gets the full TeX file path name from File object.
+     * @param file The file.
+     * @return The path.
+     */
+   public String filePath(File file)
+   {
+      if (file == null)
+      {
+         // This shouldn't happen, but just in case...
+         debug("null file passed to filePath");
+         return "";
+      }
+
+      if (!file.exists())
+      {
+         debug(String.format(
+           "Can't obtain full file path (no such file): %s",
+           file.toString()));
+         return "";
+      }
+
+      if (!isReadPermitted(file))
+      {
+          debug(String.format(
+            "Can't obtain full file path (no read access): %s",
+            file.toString()));
+          return "";
+      }
+
+      try
+      {
+         return toTeXPath(file.getCanonicalPath());
+      }
+      catch (Exception exception)
+      {
+         debug(String.format(
+           "Can't obtain full path for file: %s", file.toString()),
+            exception);
+      }
+
+      // Unsuccessful
+      return "";
+    }
+
+    /**
+     * Gets the path for the file's parent.
+     * @param file The file.
+     * @return The path.
+     * @since 1.1
+     */
+   public String parentPath(File file)
+   {
+      if (file == null)
+      {
+         // This shouldn't happen, but just in case...
+         debug("null file passed to filePath");
+         return "";
+      }
+
+      if (!file.exists())
+      {
+         debug(String.format(
+           "Can't obtain full parent path for file (no such file): %s",
+           file.toString()));
+         return "";
+      }
+
+      if (!isReadPermitted(file))
+      {
+          debug(String.format(
+            "Can't obtain full path for file (no read access): %s",
+            file.toString()));
+          return "";
+      }
+
+      try
+      {
+         File parent = file.getCanonicalFile().getParentFile();
+
+         if (parent == null)
+         {
+            // No parent? If getCanonicalFile fails it throws an
+            // exception, so no parent would presumably mean the
+            // file's in the root directory.
+
+            debug(String.format(
+              "No parent found for file: %s", file.toString()));
+            return "";
+         }
+
+         return toTeXPath(parent.getAbsolutePath());
+
+      } 
+      catch (Exception exception)
+      {
+         debug(String.format(
+           "Can't obtain full parent path for file: %s", file.toString()),
+           exception);
+      }
+
+      // Unsuccessful
+      return "";
+   }
+
+   /**
+    * Gets the script for the given locale. Java only introduced
+    * support for language scripts in version 1.7, so this returns
+    * null here. The Java 7 and 8 support needs to override this method.
+    * @param locale The locale
+    * @return The language script associated with the given locale or 
+    * null if not available
+    * @since 1.2
+    */ 
+   public String getScript(Locale locale)
+   {
+      return null;
+   }
+
+   /**
+    * Gets the language tag for the given locale.
+    * @param locale The locale or null for the default locale
+    * @return The language tag
+    * @since 1.2
+    */ 
+   public String getLanguageTag(Locale locale)
+   {
+      if (locale == null)
+      {
+         locale = Locale.getDefault();
+      }
+
+      String tag = locale.getLanguage();
+
+      String country = locale.getCountry();
+
+      if (country != null && !"".equals(country))
+      {
+         tag = String.format("%s-%s", tag, country);
+      }
+
+      String variant = locale.getVariant();
+
+      if (variant != null && !"".equals(variant))
+      {
+         tag = String.format("%s-%s", tag, variant);
+      }
+
+      return tag;
+   }
+
+    /**
+     * Gets a string representation of the provided locale.
+     * @param locale The provided locale.
+     * @return String representation.
+     */
+   public String getLocale(Locale locale)
+   {
+      return getLocale(locale, false);
+   }
+
+    /**
+     * Gets a POSIX representation of the provided locale, converting the code
+     * set if possible. If the boolean argument is true, this
+     * attempts to convert the code set to a identifier that stands
+     * a better chance of being recognised by inputenc.sty. For
+     * example, UTF-8 will be converted to utf8. None of TeX's
+     * special characters should occur in any of the locale
+     * information, but we'd better treat it like a file name just in
+     * case.
+     * @param locale The provided locale.
+     * @param convertCodeset Boolean value to convert the code set.
+     * @return String representation.
+     */
+   public String getLocale(Locale locale, boolean convertCodeset)
+   {
+      String identifier = "";
+
+      if (locale == null)
+      {
+         // No locale provided, return empty string
+         debug("null locale");
+         return "";
+      }
+
+      String language = locale.getLanguage();
+
+      if (language == null)
+      {
+          // No language provided for the locale. The language
+          // part will be omitted from the returned string.
+         debug(String.format("No language for locale: %s", locale.toString()));
+      }
+      else
+      {
+         identifier = language;
+      }
+
+      String country = locale.getCountry();
+
+      if (country == null || "".equals(country))
+      {
+         // No country is associated with the locale. The
+         // country part will be omitted from the returned
+         // string. This is just information, not an error.
+
+         info(String.format("No region for locale: %s", locale.toString()));
+      }
+      else
+      {
+         if ("".equals(identifier))
+         {
+            // The identifier hasn't been set (no language
+            // provided), so just set it to the country code.
+            identifier = country;
+         }
+         else
+         {
+            // Append the country code to the identifier.
+            identifier = identifier.concat("-").concat(country);
+         }
+      }
+
+      String codeset = getCodeSet(convertCodeset);
+
+      identifier = identifier.concat(".").concat(codeset);
+
+      // Find the script if available. This is used as the modifier part
+      // but it's better to use a language tag if the script is
+      // needed.
+
+      String script = getScript(locale);
+
+      if (script == null || "".equals(script))
+      {
+         // Script information is missing. Ignore it.
+         // This is just an advisory message.
+
+         info(String.format("No script available for locale: %s",
+             locale.toString()));
+      }
+      else
+      {
+         // Append the script. This will be a four letter string 
+         // (if it's not empty).
+         identifier = identifier.concat("@").concat(script);
+      }
+
+      return escapeFileName(identifier);
+   }
+
+   /**
+    * Gets default file encoding. (Don't escape it here or it will cause
+    * a problem when called in getLocale.)
+    * @param convertCodeset If true convert codeset to fit
+    * inputenc.sty
+    * @return the file encoding.
+    * @since 1.2
+    */ 
+   public String getCodeSet(boolean convertCodeset)
+   {
+      // Get the OS default file encoding or "UTF-8" if not set.
+
+      String codeset = getSystemProperty("file.encoding", "UTF-8");
+
+      // The codeset should not be null here as a default has
+      // been provided if the property is missing.
+
+      if (convertCodeset)
+      {
+         // If conversion is required, change to lower case
+         // and remove any hyphens.
+         codeset = codeset.toLowerCase().replaceAll("-", "");
+      }
+
+      return codeset;
+   }
+
+   /**
+    * Gets the two-letter alpha region code from the numeric code.
+    * (Java doesn't seem to recognise the numeric codes.)
+    * @param ISO 3166-1 numeric code
+    * @return ISO 3166-1 alpha code
+    * @since 1.2
+    */ 
+   public String getRegionAlpha2Code(int code)
+   {
+      switch (code)
+      {
+         case 4: return "AF";
+         case 8: return "AL";
+         case 10: return "AQ";
+         case 12: return "DZ";
+         case 16: return "AS";
+         case 20: return "AD";
+         case 24: return "AO";
+         case 28: return "AG";
+         case 31: return "AZ";
+         case 32: return "AR";
+         case 36: return "AU";
+         case 40: return "AT";
+         case 44: return "BS";
+         case 48: return "BH";
+         case 50: return "BD";
+         case 51: return "AM";
+         case 52: return "BB";
+         case 56: return "BE";
+         case 60: return "BM";
+         case 64: return "BT";
+         case 68: return "BO";
+         case 70: return "BA";
+         case 72: return "BW";
+         case 74: return "BV";
+         case 76: return "BR";
+         case 84: return "BZ";
+         case 86: return "IO";
+         case 90: return "SB";
+         case 92: return "VG";
+         case 96: return "BN";
+         case 100: return "BG";
+         case 104: return "MM";
+         case 108: return "BI";
+         case 112: return "BY";
+         case 116: return "KH";
+         case 120: return "CM";
+         case 124: return "CA";
+         case 132: return "CV";
+         case 136: return "KY";
+         case 140: return "CF";
+         case 144: return "LK";
+         case 148: return "TD";
+         case 152: return "CL";
+         case 156: return "CN";
+         case 158: return "TW";
+         case 162: return "CX";
+         case 166: return "CC";
+         case 170: return "CO";
+         case 174: return "KM";
+         case 175: return "YT";
+         case 178: return "CG";
+         case 180: return "CD";
+         case 184: return "CK";
+         case 188: return "CR";
+         case 191: return "HR";
+         case 192: return "CU";
+         case 196: return "CY";
+         case 203: return "CZ";
+         case 204: return "BJ";
+         case 208: return "DK";
+         case 212: return "DM";
+         case 214: return "DO";
+         case 218: return "EC";
+         case 222: return "SV";
+         case 226: return "GQ";
+         case 231: return "ET";
+         case 232: return "ER";
+         case 233: return "EE";
+         case 234: return "FO";
+         case 238: return "FK";
+         case 239: return "GS";
+         case 242: return "FJ";
+         case 246: return "FI";
+         case 248: return "AX";
+         case 250: return "FR";
+         case 254: return "GF";
+         case 258: return "PF";
+         case 260: return "TF";
+         case 262: return "DJ";
+         case 266: return "GA";
+         case 268: return "GE";
+         case 270: return "GM";
+         case 275: return "PS";
+         case 276: return "DE";
+         case 288: return "GH";
+         case 292: return "GI";
+         case 296: return "KI";
+         case 300: return "GR";
+         case 304: return "GL";
+         case 308: return "GD";
+         case 312: return "GP";
+         case 316: return "GU";
+         case 320: return "GT";
+         case 324: return "GN";
+         case 328: return "GY";
+         case 332: return "HT";
+         case 334: return "HM";
+         case 336: return "VA";
+         case 340: return "HN";
+         case 344: return "HK";
+         case 348: return "HU";
+         case 352: return "IS";
+         case 356: return "IN";
+         case 360: return "ID";
+         case 364: return "IR";
+         case 368: return "IQ";
+         case 372: return "IE";
+         case 376: return "IL";
+         case 380: return "IT";
+         case 384: return "CI";
+         case 388: return "JM";
+         case 392: return "JP";
+         case 398: return "KZ";
+         case 400: return "JO";
+         case 404: return "KE";
+         case 408: return "KP";
+         case 410: return "KR";
+         case 414: return "KW";
+         case 417: return "KG";
+         case 418: return "LA";
+         case 422: return "LB";
+         case 426: return "LS";
+         case 428: return "LV";
+         case 430: return "LR";
+         case 434: return "LY";
+         case 438: return "LI";
+         case 440: return "LT";
+         case 442: return "LU";
+         case 446: return "MO";
+         case 450: return "MG";
+         case 454: return "MW";
+         case 458: return "MY";
+         case 462: return "MV";
+         case 466: return "ML";
+         case 470: return "MT";
+         case 474: return "MQ";
+         case 478: return "MR";
+         case 480: return "MU";
+         case 484: return "MX";
+         case 492: return "MC";
+         case 496: return "MN";
+         case 498: return "MD";
+         case 499: return "ME";
+         case 500: return "MS";
+         case 504: return "MA";
+         case 508: return "MZ";
+         case 512: return "OM";
+         case 516: return "NA";
+         case 520: return "NR";
+         case 524: return "NP";
+         case 528: return "NL";
+         case 531: return "CW";
+         case 533: return "AW";
+         case 534: return "SX";
+         case 535: return "BQ";
+         case 540: return "NC";
+         case 548: return "VU";
+         case 554: return "NZ";
+         case 558: return "NI";
+         case 562: return "NE";
+         case 566: return "NG";
+         case 570: return "NU";
+         case 574: return "NF";
+         case 578: return "NO";
+         case 580: return "MP";
+         case 581: return "UM";
+         case 583: return "FM";
+         case 584: return "MH";
+         case 585: return "PW";
+         case 586: return "PK";
+         case 591: return "PA";
+         case 598: return "PG";
+         case 600: return "PY";
+         case 604: return "PE";
+         case 608: return "PH";
+         case 612: return "PN";
+         case 616: return "PL";
+         case 620: return "PT";
+         case 624: return "GW";
+         case 626: return "TL";
+         case 630: return "PR";
+         case 634: return "QA";
+         case 638: return "RE";
+         case 642: return "RO";
+         case 643: return "RU";
+         case 646: return "RW";
+         case 652: return "BL";
+         case 654: return "SH";
+         case 659: return "KN";
+         case 660: return "AI";
+         case 662: return "LC";
+         case 663: return "MF";
+         case 666: return "PM";
+         case 670: return "VC";
+         case 674: return "SM";
+         case 678: return "ST";
+         case 682: return "SA";
+         case 686: return "SN";
+         case 688: return "RS";
+         case 690: return "SC";
+         case 694: return "SL";
+         case 702: return "SG";
+         case 703: return "SK";
+         case 704: return "VN";
+         case 705: return "SI";
+         case 706: return "SO";
+         case 710: return "ZA";
+         case 716: return "ZW";
+         case 724: return "ES";
+         case 728: return "SS";
+         case 729: return "SD";
+         case 732: return "EH";
+         case 740: return "SR";
+         case 744: return "SJ";
+         case 748: return "SZ";
+         case 752: return "SE";
+         case 756: return "CH";
+         case 760: return "SY";
+         case 762: return "TJ";
+         case 764: return "TH";
+         case 768: return "TG";
+         case 772: return "TK";
+         case 776: return "TO";
+         case 780: return "TT";
+         case 784: return "AE";
+         case 788: return "TN";
+         case 792: return "TR";
+         case 795: return "TM";
+         case 796: return "TC";
+         case 798: return "TV";
+         case 800: return "UG";
+         case 804: return "UA";
+         case 807: return "MK";
+         case 818: return "EG";
+         case 826: return "GB";
+         case 831: return "GG";
+         case 832: return "JE";
+         case 833: return "IM";
+         case 834: return "TZ";
+         case 840: return "US";
+         case 850: return "VI";
+         case 854: return "BF";
+         case 858: return "UY";
+         case 860: return "UZ";
+         case 862: return "VE";
+         case 876: return "WF";
+         case 882: return "WS";
+         case 887: return "YE";
+         case 894: return "ZM";
+      }
+
+      // not recognised, return the code as a string
+      debug(String.format("Unrecognised numeric region code: %d", code));
+      return String.format("%d", code);
+   }
+
+   /**
+    * Gets the locale from the given language tag. Since Java didn't
+    * support BCP47 language tags until v1.7, we can't use
+    * Locale.forLanguageTag(String) here. (The Java 7 and 8 support
+    * will need to override this method.) Only parse for language
+    * code, country code and variant. Grandfathered, irregular and private
+    * tags not supported.
+    * @param languageTag The language tag
+    * @return The locale that closest matches the language tag
+    * @since 1.2
+    */ 
+   public Locale getLocale(String languageTag)
+   {
+      // The BCP47 syntax is described in 
+      // https://tools.ietf.org/html/bcp47#section-2.1
+      // This is a match for a subset of the regular syntax.
+      // Only the language tag, the region and the variant are
+      // captured.
+      // Note: named capturing groups was introduced in Java 7, so we
+      // can't use them here.
+      Pattern p = Pattern.compile(
+        "(?:([a-z]{2,3}(?:-[a-z]{2,3})*))+(?:-[A-Z][a-z]{3})?(?:-([A-Z]{2}|[0-9]{3}))?(?:-([a-zA-Z0-9]{5,8}|[0-9][a-zA-Z0-9]{3}))?(?:-.)*");
+
+      Matcher m = p.matcher(languageTag);
+
+      if (m.matches())
+      {
+         String language = m.group(1);
+         String region = m.group(2);
+         String variant = m.group(3);
+
+         try
+         {
+            region = getRegionAlpha2Code(Integer.parseInt(region));
+         }
+         catch (NumberFormatException e)
+         {
+            // ignore, alpha region code was supplied
+         }
+
+         // Language won't be null as the pattern requires it, but
+         // the region and variant might be.
+
+         if (region == null)
+         {
+            // There isn't a Locale constructor that allows a
+            // variant without a region, so don't bother checking
+            // variant for null here.
+
+            return new Locale(language);
+         }
+
+         if (variant == null)
+         {
+            return new Locale(language, region);
+         }
+
+         return new Locale(language, region, variant);
+      }
+
+      debug(String.format("Can't parse language tag: %s", languageTag));
+
+      // strip anything to a hyphen and try that
+      String[] split = languageTag.split("-", 1);
+
+      return new Locale(split[0]);
+   }
+
+   /**
+    * Gets all numerical information for the given locale. If the
+    * given locale tag is null or empty, the default locale is used. The
+    * information is returned with each item grouped to make it
+    * easier to parse in TeX. This is an abridged version of
+    * getLocaleData().
+    * @param localeTag the tag identifying the locale or null for
+    * the default locale
+    * @return locale numerical information: language tag, 
+    * number group separator, decimal separator, exponent separator,
+    * grouping conditional (1 if locale uses number grouping
+    * otherwise 0),
+    * currency code (e.g. GBP), regional currency identifier (e.g. IMP),
+    * currency symbol (e.g. \\twrp{&0x00A3;}), currency TeX code (e.g.
+    * \\texosquerycurrency{pound}), monetary decimal separator.
+    * @since 1.2
+    */
+   public String getNumericalInfo(String localeTag)
+   {
+       Locale locale;
+
+       if (localeTag == null || "".equals(localeTag))
+       {
+          locale = Locale.getDefault();
+       }
+       else
+       {
+          locale = getLocale(localeTag);
+       }
+
+       DecimalFormatSymbols fmtSyms 
+               = DecimalFormatSymbols.getInstance(locale);
+
+       // ISO 4217 code
+       String currencyCode = fmtSyms.getInternationalCurrencySymbol();
+
+       // Currency symbol
+       String currency = fmtSyms.getCurrencySymbol();
+
+       // Check for known unofficial currency codes
+
+       String localeCurrencyCode = currencyCode;
+
+       String countryCode = locale.getCountry();
+
+       if (countryCode != null && !"".equals(countryCode))
+       {
+          if (countryCode.equals("GG") || countryCode.equals("GGY")
+           || countryCode.equals("831"))
+          {// Guernsey
+             localeCurrencyCode = "GGP";
+             currency = POUND_STRING;
+          }
+          else if (countryCode.equals("JE") || countryCode.equals("JEY")
+           || countryCode.equals("832"))
+          {// Jersey
+             localeCurrencyCode = "JEP";
+             currency = POUND_STRING;
+          }
+          else if (countryCode.equals("IM") || countryCode.equals("IMN")
+           || countryCode.equals("833"))
+          {// Isle of Man
+             localeCurrencyCode = "IMP";
+             currency = String.format("M%s", POUND_STRING);
+          }
+          else if (countryCode.equals("KI") || countryCode.equals("KIR")
+           || countryCode.equals("296"))
+          {// Kiribati
+             localeCurrencyCode = "KID";
+             currency = "$";
+          }
+          else if (countryCode.equals("TV") || countryCode.equals("TUV")
+           || countryCode.equals("798"))
+          {// Tuvaluan
+             localeCurrencyCode = "TVD";
+             currency = "$";
+          }
+          // Transnistrian ruble omitted as it conflicts with ISO
+          // 4217 so omitted. There's also no country code for
+          // Transnistria. Other currencies don't have an associated
+          // region code (for example, Somaliland) or don't have a
+          // known unofficial currency code (for example, Alderney).
+       }
+
+       // Convert known Unicode currency symbols to commands that
+       // may be redefined in TeX
+
+       String texCurrency = getTeXCurrency(currency);
+
+       NumberFormat numFormat = NumberFormat.getNumberInstance(locale);
+
+       // Currency codes should always be three letter upper case
+       // A-Z characters, so no need to escape them.
+
+       return String.format(
+         "{%s}{%s}{%s}{%s}{%d}{%s}{%s}{%s}{%s}{%s}",
+             escapeFileName(getLanguageTag(locale)),
+             escapeText(fmtSyms.getGroupingSeparator()),
+             escapeText(fmtSyms.getDecimalSeparator()),
+             escapeText(fmtSyms.getExponentSeparator()), 
+             numFormat.isGroupingUsed() ? 1 : 0,
+             currencyCode,
+             localeCurrencyCode,
+             escapeText(currency),
+             texCurrency,// already escaped
+             escapeText(fmtSyms.getMonetaryDecimalSeparator()));
+   }
+
+   /**
+    * Gets the currency with known symbols replaced by TeX commands
+    * provided by texosquery.tex. Some of the conditions in this
+    * method test for archaic currency symbols. It seems very
+    * unlikely that any of those cases would actually occur, but
+    * they're included for completeness.
+    * @param currency The original currency string 
+    * @return The TeX version
+    * @since 1.2
+    */ 
+   public String getTeXCurrency(String currency)
+   {
+      StringBuilder builder = new StringBuilder();
+
+      for (int i = 0, n = currency.length(); i < n; )
+      {
+         int codepoint = currency.codePointAt(i);
+         i += Character.charCount(codepoint);
+
+         switch (codepoint)
+         {
+            case DOLLAR_CHAR:
+               builder.append("\\texosquerycurrency{dollar}");
+            break;
+            case CENT_CHAR:
+               builder.append("\\texosquerycurrency{cent}");
+            break;
+            case POUND_CHAR:
+               builder.append("\\texosquerycurrency{pound}");
+            break;
+            case CURRENCY_CHAR:
+               builder.append("\\texosquerycurrency{sign}");
+            break;
+            case YEN_CHAR:
+               builder.append("\\texosquerycurrency{yen}");
+            break;
+            case ECU_CHAR:
+               builder.append("\\texosquerycurrency{ecu}");
+            break;
+            case COLON_CURRENCY_CHAR:
+               builder.append("\\texosquerycurrency{colon}");
+            break;
+            case CRUZEIRO_CHAR:
+               builder.append("\\texosquerycurrency{cruzeiro}");
+            break;
+            case FRANC_CHAR:
+               builder.append("\\texosquerycurrency{franc}");
+            break;
+            case LIRA_CHAR:
+               builder.append("\\texosquerycurrency{lira}");
+            break;
+            case MILL_CURRENCY_CHAR:
+               builder.append("\\texosquerycurrency{mill}");
+            break;
+            case NAIRA_CHAR:
+               builder.append("\\texosquerycurrency{naira}");
+            break;
+            case PESETA_CHAR:
+               builder.append("\\texosquerycurrency{peseta}");
+            break;
+            case LEGACY_RUPEE_CHAR:
+            case RUPEE_CHAR:
+               builder.append("\\texosquerycurrency{rupee}");
+            break;
+            case WON_CHAR:
+               builder.append("\\texosquerycurrency{won}");
+            break;
+            case NEW_SHEQEL_CHAR:
+               builder.append("\\texosquerycurrency{newsheqel}");
+            break;
+            case DONG_CHAR:
+               builder.append("\\texosquerycurrency{dong}");
+            break;
+            case EURO_CHAR:
+               builder.append("\\texosquerycurrency{euro}");
+            break;
+            case KIP_CHAR:
+               builder.append("\\texosquerycurrency{kip}");
+            break;
+            case TUGRIK_CHAR:
+               builder.append("\\texosquerycurrency{tugrik}");
+            break;
+            case DRACHMA_CHAR:
+               builder.append("\\texosquerycurrency{drachma}");
+            break;
+            case GERMAN_PENNY_CHAR:
+               builder.append("\\texosquerycurrency{germanpenny}");
+            break;
+            case PESO_CHAR:
+               builder.append("\\texosquerycurrency{peso}");
+            break;
+            case GUARANI_CHAR:
+               builder.append("\\texosquerycurrency{guarani}");
+            break;
+            case AUSTRAL_CHAR:
+               builder.append("\\texosquerycurrency{austral}");
+            break;
+            case HRYVNIA_CHAR:
+               builder.append("\\texosquerycurrency{hryvnia}");
+            break;
+            case CEDI_CHAR:
+               builder.append("\\texosquerycurrency{cedi}");
+            break;
+            case LIVRE_TOURNOIS_CHAR:
+               builder.append("\\texosquerycurrency{livretournois}");
+            break;
+            case SPESMILO_CHAR:
+               builder.append("\\texosquerycurrency{spesmilo}");
+            break;
+            case TENGE_CHAR:
+               builder.append("\\texosquerycurrency{tenge}");
+            break;
+            case TURKISH_LIRA_CHAR:
+               builder.append("\\texosquerycurrency{turkishlira}");
+            break;
+            case NORDIC_MARK_CHAR:
+               builder.append("\\texosquerycurrency{nordicmark}");
+            break;
+            case MANAT_CHAR:
+               builder.append("\\texosquerycurrency{manat}");
+            break;
+            case RUBLE_CHAR:
+               builder.append("\\texosquerycurrency{ruble}");
+            break;
+            default: 
+               builder.append(escapeText(codepoint));
+         }
+      }
+
+      return builder.toString();
+   }
+
+   /** Gets the standalone month names for the locale data.
+    * These are only available for Java 8, so just return the 
+    * month names used in the date format instead. The JRE8 version
+    * needs to override this method.
+    * @param cal The calendar
+    * @param locale The locale
+    * @return month names
+    * @since 1.2
+    */  
+   public String getStandaloneMonths(Calendar cal, Locale locale)
+   {
+      // can't use Calendar.getDisplayName() as it's not available
+      // with Java 5.
+      DateFormatSymbols dateFmtSyms = DateFormatSymbols.getInstance(locale);
+
+      StringBuilder monthNamesGroup = new StringBuilder();
+
+      String[] names = dateFmtSyms.getMonths();
+
+      for (int i = 0; i < 12; i++)
+      {
+         monthNamesGroup.append(String.format("{%s}", escapeText(names[i])));
+      }
+
+      return monthNamesGroup.toString();
+   }
+
+   /** Gets the standalone short month names for the locale data.
+    * These are only available for Java 8, so just return the 
+    * month names used in the date format instead. The JRE8 version
+    * needs to override this method.
+    * @param cal The calendar
+    * @param locale The locale
+    * @return short month names
+    * @since 1.2
+    */  
+   public String getStandaloneShortMonths(Calendar cal, Locale locale)
+   {
+      // can't use Calendar.getDisplayName() as it's not available
+      // with Java 5.
+      DateFormatSymbols dateFmtSyms = DateFormatSymbols.getInstance(locale);
+
+      StringBuilder shortMonthNamesGroup = new StringBuilder();
+
+      String[] names = dateFmtSyms.getShortMonths();
+
+      for (int i = 0; i < 12; i++)
+      {
+         shortMonthNamesGroup.append(String.format("{%s}", 
+           escapeText(names[i])));
+      }
+
+      return shortMonthNamesGroup.toString();
+   }
+
+   /** Gets the standalone day names for the locale data.
+    * These are only available for Java 8, so just return the 
+    * names used in the date format instead. The JRE8 version
+    * needs to override this method.
+    * @param cal The calendar
+    * @param locale The locale
+    * @return day of week names
+    * @since 1.2
+    */  
+   public String getStandaloneWeekdays(Calendar cal, Locale locale)
+   {
+      DateFormatSymbols dateFmtSyms = DateFormatSymbols.getInstance(locale);
+
+      String[] names = dateFmtSyms.getWeekdays();
+
+      // Be consistent with pgfcalendar:
+
+      return String.format("{%s}{%s}{%s}{%s}{%s}{%s}{%s}",
+          escapeText(names[Calendar.MONDAY]),
+          escapeText(names[Calendar.TUESDAY]),
+          escapeText(names[Calendar.WEDNESDAY]),
+          escapeText(names[Calendar.THURSDAY]),
+          escapeText(names[Calendar.FRIDAY]),
+          escapeText(names[Calendar.SATURDAY]),
+          escapeText(names[Calendar.SUNDAY]));
+   }
+
+   /** Gets the standalone short day names for the locale data.
+    * These are only available for Java 8, so just return the 
+    * names used in the date format instead. The JRE8 version
+    * needs to override this method.
+    * @param cal The calendar
+    * @param locale The locale
+    * @return day of week names
+    * @since 1.2
+    */  
+   public String getStandaloneShortWeekdays(Calendar cal, Locale locale)
+   {
+      DateFormatSymbols dateFmtSyms = DateFormatSymbols.getInstance(locale);
+
+      String[] names = dateFmtSyms.getShortWeekdays();
+
+      // Be consistent with pgfcalendar:
+
+      return String.format("{%s}{%s}{%s}{%s}{%s}{%s}{%s}",
+          escapeText(names[Calendar.MONDAY]),
+          escapeText(names[Calendar.TUESDAY]),
+          escapeText(names[Calendar.WEDNESDAY]),
+          escapeText(names[Calendar.THURSDAY]),
+          escapeText(names[Calendar.FRIDAY]),
+          escapeText(names[Calendar.SATURDAY]),
+          escapeText(names[Calendar.SUNDAY]));
+   }
+
+   /**
+    * Converts date/time pattern to a form that's easier for TeX to
+    * parse. This replaces the placeholders with <tt>\\patdtf{n}{c}</tt> where c
+    * is the placeholder character and n is the number of
+    * occurrences of c in the placeholder. (For example, 
+    * "<tt>dd-MMM-yyyy</tt>" is  converted to
+    * <tt>\\patdtf{2}{d}-\\patdtf{3}{M}-\\patdtf{4}{y}</tt>). The 
+    * query command \\TeXOSQuery in texosquery.tex will expand \\patdtf
+    * to the longer \\texosquerydtf to avoid conflict. This can then be
+    * redefined as appropriate. (See the "Pattern Formats" section
+    * of the TeX documented code for more detail.)
+    * @param localeFormat The date/time pattern
+    * @return TeX code
+    * @since 1.2
+    */ 
+   public String formatDateTimePattern(Format localeFormat)
+   {
+      SimpleDateFormat fmt = null;
+
+      try
+      {
+         fmt = (SimpleDateFormat)localeFormat;
+
+         if (fmt == null)
+         {
+            throw new NullPointerException();
+         }
+      }
+      catch (Exception e)
+      {
+         // this shouldn't happen
+         debug(String.format("Invalid argument: %s", localeFormat), e);
+         return "";
+      }
+
+      String pattern = fmt.toPattern();
+
+      StringBuilder builder = new StringBuilder();
+
+      int prev = 0;
+      int fieldLen = 0;
+      boolean inString = false;
+
+      for (int i = 0, n = pattern.length(), offset=1; i < n; i = i+offset)
+      {
+         int codepoint = pattern.codePointAt(i);
+         offset = Character.charCount(codepoint);
+
+         int nextIndex = i+offset;
+         int nextCodePoint = (nextIndex < n ? pattern.codePointAt(nextIndex):0);
+
+         if (inString)
+         {
+            if (codepoint == '\'')
+            {
+               if (nextCodePoint != '\'')
+               {
+                  // reached the end of the string
+                  builder.append('}');
+                  inString = false;
+               }
+               else
+               {
+                  // literal '
+                  builder.append("\\patapo ");
+                  i = nextIndex;
+                  offset = Character.charCount(nextCodePoint);
+               }
+            }
+            else
+            {
+               // still inside the string
+               builder.append(escapeText(codepoint));
+            }
+         }
+         else if (codepoint == prev)
+         {
+            fieldLen++;
+         }
+         else
+         {
+            switch (codepoint)
+            {
+               case '\'': // quote
+
+                  if (prev != 0)
+                  {
+                     builder.append(String.format(
+                         "\\patdtf{%d}{%c}", fieldLen, prev));
+                     prev = 0;
+                     fieldLen = 0;
+                  }
+
+                  // start of the string
+                  builder.append("\\patstr{");
+                  inString = true;
+
+               break;
+               case 'G': // era
+               case 'y': // year
+               case 'Y': // week year
+               case 'M': // month in year (context sensitive)
+               case 'L': // month in year (standalone)
+               case 'w': // week in year
+               case 'W': // week in month
+               case 'D': // day in year
+               case 'd': // day in month
+               case 'F': // day of week in month
+               case 'E': // day name in week
+               case 'u': // day number of week (1 = Mon)
+               case 'a': // am/pm marker
+               case 'H': // hour in day (0-23)
+               case 'k': // hour in day (1-24)
+               case 'K': // hour in am/pm (0-11)
+               case 'h': // hour in am/pm (1-12)
+               case 'm': // minute in hour
+               case 's': // second in minute
+               case 'S': // millisecond
+               case 'z': // time zone (locale)
+               case 'Z': // time zone (RFC 822)
+               case 'X': // time zone (ISO 8601)
+                 prev = codepoint;
+                 fieldLen = 1;
+               break;
+               default:
+                 // prev doesn't need escaping as it will be one
+                 // of the above letter cases.
+
+                 if (prev == 0)
+                 {
+                     builder.append(escapeText(codepoint));
+                 }
+                 else
+                 {
+                     builder.append(String.format(
+                       "\\patdtf{%d}{%c}%s", fieldLen, prev, 
+                       escapeText(codepoint)));
+                 }
+                 prev = 0;
+                 fieldLen = 0;
+            }
+         }
+      }
+
+      if (prev != 0)
+      {
+         builder.append(String.format(
+           "\\patdtf{%d}{%c}", fieldLen, prev));
+      }
+
+      return builder.toString();
+   }
+
+   /**
+    * Converts numeric pattern to a form that's easier for TeX to parse. 
+    * @param numFormat the numeric pattern
+    * @return TeX code
+    * @since 1.2
+    */ 
+   public String formatNumberPattern(Format numFormat)
+   {
+      DecimalFormat fmt = null;
+
+      try
+      {
+         fmt = (DecimalFormat)numFormat;
+
+         if (fmt == null)
+         {
+            throw new NullPointerException();
+         }
+      }
+      catch (Exception e)
+      {
+         // this shouldn't happen
+         debug(String.format("Invalid argument: %s", numFormat), e);
+         return "";
+      }
+
+      String pattern = fmt.toPattern();
+
+      // Is there a +ve;-ve sub-pattern pair?
+      // This is a bit awkward as a semi-colon could appear
+      // literally within a string.
+
+      String positive = null;
+      String negative = null;
+
+      StringBuilder builder = new StringBuilder();
+      boolean inString = false;
+
+      for (int i = 0, n = pattern.length(), offset=1; i < n; i = i+offset)
+      {
+         int codepoint = pattern.codePointAt(i);
+         offset = Character.charCount(codepoint);
+
+         int nextIndex = i+offset;
+         int nextCodePoint = (nextIndex < n ? pattern.codePointAt(nextIndex):0);
+
+         if (inString)
+         {
+            if (codepoint == '\'')
+            {
+               builder.appendCodePoint(codepoint);
+
+               if (nextCodePoint == '\'')
+               {
+                  // literal '
+                  builder.appendCodePoint(nextCodePoint);
+                  i = nextIndex;
+                  offset = Character.charCount(nextCodePoint);
+               }
+               else
+               {
+                  inString = false;
+               }
+            }
+            else
+            {
+               builder.appendCodePoint(codepoint);
+            }
+         }
+         else if (codepoint == '\'')
+         {
+            inString = true;
+            builder.appendCodePoint(codepoint);
+         }
+         else if (codepoint == ';')
+         {
+            if (positive == null)
+            {
+               positive = builder.toString();
+               builder = new StringBuilder();
+            }
+            else
+            {
+               debug(String.format("Too many ; found in pattern: %s", 
+                     pattern));
+            }
+         }
+         else
+         {
+            builder.appendCodePoint(codepoint);
+         }
+      }
+
+      if (positive == null)
+      {
+         positive = builder.toString();
+      }
+      else if (builder.length() > 0)
+      {
+         negative = builder.toString();
+      }
+
+      if (negative == null)
+      {
+         return String.format("\\patnumfmt{%s}", 
+           formatNumberSubPattern(positive));
+      }
+      else
+      {
+         return String.format("\\patpmnumfmt{%s}{%s}", 
+           formatNumberSubPattern(positive),
+           formatNumberSubPattern(negative));
+      }
+   }
+
+   /**
+    * Converts the sub-pattern of a numeric format.
+    * @param pattern The sub-pattern
+    * @return TeX code
+    * @since 1.2
+    */ 
+   private String formatNumberSubPattern(String pattern)
+   {
+      if (pattern == null || "".equals(pattern))
+      {
+         return "";
+      }
+
+      // Is this currency?
+
+      Pattern p = Pattern.compile("(.*(?:[^'](?:'')+){0,1})("+CURRENCY_CHAR
+        +"{1,2})(.*)");
+      Matcher m = p.matcher(pattern);
+
+      if (m.matches())
+      {
+         return formatCurrencyPattern(m.group(1), 
+           (m.group(2).length() == 2), m.group(3));
+      }
+
+      // Is this a percentage?
+
+      p = Pattern.compile("(.*(?:[^'](?:'')+){0,1})([%"+PERMILLE_CHAR+"])(.*)");
+      m = p.matcher(pattern);
+
+      if (m.matches())
+      {
+         boolean percent = ("%".equals(m.group(2)));
+
+         return formatPercentagePattern(m.group(1), m.group(3),
+          percent ? "patppct" : "patppml", 
+          percent ? "patspct" : "patspml");
+      }
+
+      // must be a number
+
+      return formatNumericPattern(pattern);
+   }
+
+   /**
+    * Converts the currency format.
+    * @param pre The pre-symbol pattern
+    * @param international Determines if the international currency
+    * symbol should be used
+    * @param post The post-symbol pattern
+    * @return TeX code
+    * @since 1.2
+    */ 
+   private String formatCurrencyPattern(String pre, boolean international,
+      String post)
+   {
+      if (post == null || "".equals(post))
+      {
+         pre = formatNumericPattern(pre);
+
+         // currency symbol is a suffix
+         if (international)
+         {
+            return String.format("\\patsicur{%s}{}", pre);
+         }
+         else
+         {
+            return String.format("\\patscur{%s}{}", pre);
+         }
+      }
+      else if (pre == null || "".equals(pre))
+      {
+         // currency symbol is a prefix
+
+         post = formatNumericPattern(post);
+
+         if (international)
+         {
+            return String.format("\\patpicur{%s}{}", post);
+         }
+         else
+         {
+            return String.format("\\patpcur{%s}{}", post);
+         }
+      }
+      else
+      {
+         // What do we do here? If pre contains '#' or '0' assume
+         // a suffix currency otherwise a prefix currency.
+
+         pre = formatNumericPattern(pre);
+         post = formatNumericPattern(post);
+
+         if (pre.matches(".*[0#].*"))
+         {
+            // suffix, pre is the number and post is trailing
+            // text
+            if (international)
+            {
+               return String.format("\\patsicur{%s}{%s}", pre, post);
+            }
+            else
+            {
+               return String.format("\\patscur{%s}{%s}", pre, post);
+            }
+         }
+         else
+         {
+            // prefix, post is the number and pre is leading
+            // text
+            if (international)
+            {
+               return String.format("\\patpicur{%s}{%s}", post, pre);
+            }
+            else
+            {
+               return String.format("\\patpcur{%s}{%s}", post, pre);
+            }
+         }
+      }
+   }
+
+   /**
+    * Converts percentage format.
+    * @param pre The pre-symbol pattern
+    * @param post The post-symbol pattern
+    * @param prefixCs The control sequence name to use if the symbol is a
+    * prefix
+    * @param suffixCs The control sequence name to use if the symbol is a
+    * suffix
+    * @return TeX code
+    * @since 1.2
+    */ 
+   private String formatPercentagePattern(String pre, String post,
+     String prefixCs, String suffixCs)
+   {
+      if (post == null || "".equals(post))
+      {
+         pre = formatNumericPattern(pre);
+
+         // symbol is a suffix
+
+         return String.format("\\%s{%s}{}", suffixCs, pre);
+      }
+      else if (pre == null || "".equals(pre))
+      {
+         // symbol is a prefix
+
+         post = formatNumericPattern(post);
+
+         return String.format("\\%s{%s}{}", prefixCs, post);
+      }
+      else
+      {
+         pre = formatNumericPattern(pre);
+         post = formatNumericPattern(post);
+
+         if (pre.matches(".*[0#].*"))
+         {
+            // suffix, pre is the number and post is trailing
+            // text
+
+            return String.format("\\%s{%s}{%s}", suffixCs, pre, post);
+         }
+         else
+         {
+            // prefix, post is the number and pre is leading
+            // text
+
+            return String.format("\\%s{%s}{%s}", prefixCs, post, pre);
+         }
+      }
+   }
+
+   /**
+    * Converts the numeric format.
+    * @param pattern The sub-pattern
+    * @return TeX code
+    * @since 1.2
+    */ 
+   private String formatNumericPattern(String pattern)
+   {
+      if (pattern == null || "".equals(pattern))
+      {
+         return "";
+      }
+
+      // Split around exponent (if present)
+
+      Pattern p = Pattern.compile("(.*(?:[^'](?:'')+?){0,1})(E.*)?");
+      Matcher m = p.matcher(pattern);
+
+      if (!m.matches())
+      {
+         debug(String.format(
+             "Can't match number format sub-pattern '%s' against regexp: %s",
+              pattern, p));
+         return "";
+      } 
+
+      String pre = m.group(1);
+      String post = m.group(2);
+
+      if (pre == null && post == null)
+      {
+         // empty pattern
+         return "";
+      }
+
+      if (post == null)
+      {
+         return formatDecimalPattern(pre);
+      }
+
+      return String.format("\\patsinumfmt{%s}{%s}",
+        formatDecimalPattern(pre),
+        formatIntegerPattern(post, true));
+   }
+
+   /**
+    * Converts a decimal pattern.
+    * @param pattern The pattern
+    * @return TeX code
+    * @since 1.2
+    */ 
+   private String formatDecimalPattern(String pattern)
+   {
+      // split on the decimal point (if present)
+
+      Pattern p = Pattern.compile("(.*?(?:[^'](?:'')){0,1})(?:\\.(.*))?");
+
+      Matcher m = p.matcher(pattern);
+
+      if (!m.matches())
+      {
+         debug(String.format(
+             "Can't match decimal pattern '%s' against regexp: %s",
+              pattern, p));
+         return "";
+      } 
+
+
+      String pre = m.group(1);
+      String post = m.group(2);
+
+      if (pre == null && post == null)
+      {
+         // empty pattern
+         return "";
+      }
+
+      if (post == null)
+      {
+         return formatIntegerPattern(pre, true);
+      }
+
+      return String.format("\\patdecfmt{%s}{%s}",
+        formatIntegerPattern(pre, true),
+        formatIntegerPattern(post, false));
+   }
+
+
+   /**
+    * Convert an integer pattern. The aim here is to have a number
+    * formatting command defined in TeX that will be passed a number
+    * with either leading or trailing zeros padded to 10 digits.
+    * TeX can't handle numbers higher than 2147483647, so any digits
+    * in the pattern beyond that are discarded. This means defining
+    * a command that effectively takes 10 arguments (with a bit of
+    * trickery to get around the 9-arg maximum). Each digit can then
+    * be rendered using either \\patdgt (always display the digit)
+    * or \\patdgtnz (only display the digit if it isn't a
+    * non-significant zero).
+    *
+    * These short commands will be converted to longer ones that are
+    * less likely to cause conflict when \\TeXOSQuery is used.
+    * (See the "Pattern Formats" section of the documented code for
+    * more details.)
+    * @param pattern The pattern
+    * @param leadPadding Determines if leading padding needs taking
+    * into account
+    * @return TeX code
+    * @since 1.2
+    */ 
+   private String formatIntegerPattern(String pattern, boolean leadPadding)
+   {
+      boolean inString = false;
+
+      int digitCount = 0;
+      int groupCount = -1;
+
+      // count the number of digits
+
+      for (int i = 0, n = pattern.length(), offset=1; i < n; i = i+offset)
+      {
+         int codepoint = pattern.codePointAt(i);
+         offset = Character.charCount(codepoint);
+
+         int nextIndex = i+offset;
+         int nextCodePoint = (nextIndex < n ? pattern.codePointAt(nextIndex):0);
+
+         if (inString)
+         {
+            if (codepoint == '\'')
+            {
+               if (nextCodePoint != '\'')
+               {
+                  inString = false;
+                  i = nextIndex;
+                  offset = Character.charCount(nextCodePoint);
+               }
+            }
+         }
+         else if (codepoint == '\'')
+         {
+            inString = true;
+         }
+         else if (codepoint == '#' || codepoint == '0')
+         {
+            digitCount++;
+
+            if (groupCount > -1) groupCount++;
+         }
+         else if (codepoint == ',')
+         {
+            groupCount=0;
+         }
+      }
+
+      int digitIndex = (leadPadding ? MAX_DIGIT_FORMAT : 0);
+
+      inString = false;
+
+      StringBuilder builder = new StringBuilder();
+
+      for (int i = 0, n = pattern.length(), offset=1; i < n; i = i+offset)
+      {
+         int codepoint = pattern.codePointAt(i);
+         offset = Character.charCount(codepoint);
+
+         int nextIndex = i+offset;
+         int nextCodePoint = (nextIndex < n ? pattern.codePointAt(nextIndex):0);
+
+         switch (codepoint)
+         {
+            case '\'':
+
+              if (!inString)
+              {
+                 inString = true;
+
+                 builder.append("\\patstr{");
+              }
+              else if (nextCodePoint == '\'')
+              {
+                 builder.append("\\patapo ");
+                 i = nextIndex;
+                 offset = Character.charCount(nextCodePoint);
+              }
+              else
+              {
+                 builder.append("}");
+                 inString = false;
+              }
+            break;
+            case '0':
+
+              if (leadPadding)
+              {
+                 if (digitIndex > MAX_DIGIT_FORMAT)
+                 {
+                    // too many digit markers in the pattern,
+                    // discard
+                 }
+                 else if (digitIndex > digitCount)
+                 {
+                    // not enough digit markers in the pattern
+                    // pad with #
+
+                    for ( ; digitIndex > digitCount; digitIndex--)
+                    {
+                       builder.append("\\patdgtnz ");
+
+                       if (groupCount > 0 && ((digitIndex-1) % groupCount) == 0)
+                       {
+                          builder.append("\\patngp ");
+                       }
+                    }
+
+                    builder.append("\\patdgt ");
+                 }
+                 else
+                 {
+                    builder.append("\\patdgt ");
+                 }
+
+                 digitIndex--;
+              }
+              else
+              {
+                 digitIndex++;
+
+                 if (digitIndex > MAX_DIGIT_FORMAT)
+                 {
+                    // too many digit markers in the pattern,
+                    // discard
+                 }
+                 else if (digitIndex == digitCount)
+                 {
+                    builder.append("\\patdgt ");
+
+                    // not enough digit markers in the pattern
+                    // pad with #
+
+                    for ( ; digitIndex < MAX_DIGIT_FORMAT; digitIndex++)
+                    {
+                       builder.append("\\patdgtnz ");
+                    }
+                 }
+                 else
+                 {
+                    builder.append("\\patdgt ");
+                 }
+              }
+            break;
+            case '#':
+
+              if (leadPadding)
+              {
+                 if (digitIndex > MAX_DIGIT_FORMAT)
+                 {
+                    // too many digit markers in the pattern,
+                    // discard
+                 }
+                 else if (digitIndex > digitCount)
+                 {
+                    // not enough digit markers in the pattern
+                    // pad with #
+
+                    for ( ; digitIndex > digitCount; digitIndex--)
+                    {
+                       builder.append("\\patdgtnz ");
+
+                       if (groupCount > 0 && ((digitIndex-1) % groupCount) == 0)
+                       {
+                          builder.append("\\patngp ");
+                       }
+                    }
+
+                    builder.append("\\patdgtnz ");
+                 }
+                 else
+                 {
+                    builder.append("\\patdgtnz ");
+                 }
+
+                 digitIndex--;
+              }
+              else
+              {
+                 digitIndex++;
+
+                 if (digitIndex > MAX_DIGIT_FORMAT)
+                 {
+                    // too many digit markers in the pattern,
+                    // discard
+                 }
+                 else if (digitIndex == digitCount)
+                 {
+                    builder.append("\\patdgtnz ");
+
+                    // not enough digit markers in the pattern
+                    // pad with #
+
+                    for ( ; digitIndex < MAX_DIGIT_FORMAT; digitIndex++)
+                    {
+                       builder.append("\\patdgtnz ");
+                    }
+                 }
+                 else
+                 {
+                    builder.append("\\patdgtnz ");
+                 }
+              }
+            break;
+            case '-':
+              builder.append("\\patmsg ");
+            break;
+            case ',':
+
+              if (digitIndex <= digitCount)
+              {
+                 builder.append("\\patngp ");
+              }
+
+            break;
+            default:
+              builder.append(escapeText(codepoint));
+         }
+      }
+
+      return builder.toString();
+   }
+
+   /**
+    * Gets all available data for the given locale. If the
+    * given locale tag is null, the default locale is used. The
+    * information is returned with grouping to make it
+    * easier to parse in TeX. (Each block is grouped, with each
+    * element within the block also grouped.)
+    *
+    * The standalone month names and day of week names are new
+    * to Java 8, so we can't use them for earlier versions.
+    * @param localeTag the language tag identifying the locale or null for
+    * the default locale
+    * @return locale data in grouped blocks:
+    * <ol>
+    * <li>language tag, language name, language name in given locale,
+    * country name, country name in given locale, variant name,
+    * variant name in given locale.
+    * <li> full date, long date, medium date, short date,
+    * first day of the week index.
+    * <li> full date, long date, medium date, short date patterns.
+    * <li> full time, long time, medium time, short time.
+    * <li> full time, long time, medium time, short time patterns.
+    * <li> weekday names.
+    * <li> short weekday names.
+    * <li> month names
+    * <li> short month names.
+    * <li> standalone week day names.
+    * <li> standalone short week day names.
+    * <li> standalone month names.
+    * <li> standalone short month names.
+    * <li> number group separator,
+    * decimal separator, exponent separator, grouping flag, ISO 4217 currency
+    * identifier (e.g. GBP), region currency identifier (usually the same as
+    * the ISO 4217 code, but may be an unofficial currency code, such as IMP),
+    * currency symbol (e.g. &0x00A3;), TeX currency symbol, monetary decimal 
+    * separator, percent symbol, per mille symbol.
+    * <li> number format, integer format, currency format,
+    * percent format.
+    * </ol>
+    * @since 1.2
+    */
+   public String getLocaleData(String localeTag)
+   {
+       Locale locale;
+
+       if (localeTag == null || "".equals(localeTag))
+       {
+          locale = Locale.getDefault();
+       }
+       else
+       {
+          locale = getLocale(localeTag);
+       }
+
+       String languageName = locale.getDisplayLanguage();
+
+       if (languageName == null)
+       {
+          languageName = "";
+       }
+
+       String localeLanguageName = locale.getDisplayLanguage(locale);
+
+       if (localeLanguageName == null)
+       {
+          localeLanguageName = "";
+       }
+
+       String countryName = locale.getDisplayCountry();
+
+       if (countryName == null)
+       {
+          countryName = "";
+       }
+
+       String localeCountryName = locale.getDisplayCountry(locale);
+
+       if (localeCountryName == null)
+       {
+          localeCountryName = "";
+       }
+
+       String variantName = locale.getDisplayVariant();
+
+       if (variantName == null)
+       {
+          variantName = "";
+       }
+
+       String localeVariantName = locale.getDisplayVariant(locale);
+
+       if (localeVariantName == null)
+       {
+          localeVariantName = "";
+       }
+
+       String langRegionGroup = String.format("{%s}{%s}{%s}{%s}{%s}{%s}{%s}",
+             escapeFileName(getLanguageTag(locale)),
+             escapeText(languageName),
+             escapeText(localeLanguageName),
+             escapeText(countryName),
+             escapeText(localeCountryName),
+             escapeText(variantName),
+             escapeText(localeVariantName));
+
+       DateFormat dateFullFormat = DateFormat.getDateInstance(
+        DateFormat.FULL, locale);
+
+       DateFormat dateLongFormat = DateFormat.getDateInstance(
+        DateFormat.LONG, locale);
+
+       DateFormat dateMediumFormat = DateFormat.getDateInstance(
+        DateFormat.MEDIUM, locale);
+
+       DateFormat dateShortFormat = DateFormat.getDateInstance(
+        DateFormat.SHORT, locale);
+
+       DateFormat timeFullFormat = DateFormat.getTimeInstance(
+        DateFormat.FULL, locale);
+
+       DateFormat timeLongFormat = DateFormat.getTimeInstance(
+        DateFormat.LONG, locale);
+
+       DateFormat timeMediumFormat = DateFormat.getTimeInstance(
+        DateFormat.MEDIUM, locale);
+
+       DateFormat timeShortFormat = DateFormat.getTimeInstance(
+        DateFormat.SHORT, locale);
+
+       DateFormat dateTimeFullFormat = DateFormat.getDateTimeInstance(
+        DateFormat.FULL, DateFormat.FULL, locale);
+
+       DateFormat dateTimeLongFormat = DateFormat.getDateTimeInstance(
+        DateFormat.LONG, DateFormat.LONG, locale);
+
+       DateFormat dateTimeMediumFormat = DateFormat.getDateTimeInstance(
+        DateFormat.MEDIUM, DateFormat.MEDIUM, locale);
+
+       DateFormat dateTimeShortFormat = DateFormat.getDateTimeInstance(
+        DateFormat.SHORT, DateFormat.SHORT, locale);
+
+       // first day of the week index consistent with pgfcalendar
+       // (0 = Monday, etc)
+       int firstDay = 0;
+
+       Calendar cal = Calendar.getInstance(locale);
+       cal.setTimeInMillis(now.getTime());
+
+       switch (cal.getFirstDayOfWeek())
+       {
+          case Calendar.MONDAY:
+            firstDay = 0;
+          break;
+          case Calendar.TUESDAY:
+            firstDay = 1;
+          break;
+          case Calendar.WEDNESDAY:
+            firstDay = 2;
+          break;
+          case Calendar.THURSDAY:
+            firstDay = 3;
+          break;
+          case Calendar.FRIDAY:
+            firstDay = 4;
+          break;
+          case Calendar.SATURDAY:
+            firstDay = 5;
+          break;
+          case Calendar.SUNDAY:
+            firstDay = 6;
+          break;
+       }
+
+       String dateGroup = String.format("{%s}{%s}{%s}{%s}{%d}",
+             escapeText(dateFullFormat.format(now)),
+             escapeText(dateLongFormat.format(now)),
+             escapeText(dateMediumFormat.format(now)),
+             escapeText(dateShortFormat.format(now)),
+             firstDay);
+
+       String dateFmtGroup = String.format("{%s}{%s}{%s}{%s}",
+         formatDateTimePattern(dateFullFormat),
+         formatDateTimePattern(dateLongFormat),
+         formatDateTimePattern(dateMediumFormat),
+         formatDateTimePattern(dateShortFormat));
+
+       String timeGroup = String.format("{%s}{%s}{%s}{%s}",
+             escapeText(timeFullFormat.format(now)),
+             escapeText(timeLongFormat.format(now)),
+             escapeText(timeMediumFormat.format(now)),
+             escapeText(timeShortFormat.format(now)));
+
+       String timeFmtGroup = String.format("{%s}{%s}{%s}{%s}",
+         formatDateTimePattern(timeFullFormat),
+         formatDateTimePattern(timeLongFormat),
+         formatDateTimePattern(timeMediumFormat),
+         formatDateTimePattern(timeShortFormat));
+
+       String dateTimeGroup = String.format("{%s}{%s}{%s}{%s}",
+             escapeText(dateTimeFullFormat.format(now)),
+             escapeText(dateTimeLongFormat.format(now)),
+             escapeText(dateTimeMediumFormat.format(now)),
+             escapeText(dateTimeShortFormat.format(now)));
+
+       String dateTimeFmtGroup = String.format("{%s}{%s}{%s}{%s}",
+         formatDateTimePattern(dateTimeFullFormat),
+         formatDateTimePattern(dateTimeLongFormat),
+         formatDateTimePattern(dateTimeMediumFormat),
+         formatDateTimePattern(dateTimeShortFormat));
+
+       DateFormatSymbols dateFmtSyms = DateFormatSymbols.getInstance(locale);
+
+       String[] names = dateFmtSyms.getWeekdays();
+
+       // Be consistent with pgfcalendar:
+
+       String weekdayNamesGroup = String.format(
+          "{%s}{%s}{%s}{%s}{%s}{%s}{%s}",
+           escapeText(names[Calendar.MONDAY]),
+           escapeText(names[Calendar.TUESDAY]),
+           escapeText(names[Calendar.WEDNESDAY]),
+           escapeText(names[Calendar.THURSDAY]),
+           escapeText(names[Calendar.FRIDAY]),
+           escapeText(names[Calendar.SATURDAY]),
+           escapeText(names[Calendar.SUNDAY]));
+
+       names = dateFmtSyms.getShortWeekdays();
+
+       String shortWeekdayNamesGroup = String.format(
+          "{%s}{%s}{%s}{%s}{%s}{%s}{%s}",
+           escapeText(names[Calendar.MONDAY]),
+           escapeText(names[Calendar.TUESDAY]),
+           escapeText(names[Calendar.WEDNESDAY]),
+           escapeText(names[Calendar.THURSDAY]),
+           escapeText(names[Calendar.FRIDAY]),
+           escapeText(names[Calendar.SATURDAY]),
+           escapeText(names[Calendar.SUNDAY]));
+
+       StringBuilder monthNamesGroup = new StringBuilder();
+
+       names = dateFmtSyms.getMonths();
+
+       for (int i = 0; i < 12; i++)
+       {
+          // skip 13th month (Calendar.UNDECIMBER)
+          monthNamesGroup.append(String.format("{%s}", escapeText(names[i])));
+       }
+
+       StringBuilder shortMonthNamesGroup = new StringBuilder();
+
+       names = dateFmtSyms.getShortMonths();
+
+       for (int i = 0; i < 12; i++)
+       {
+          shortMonthNamesGroup.append(String.format("{%s}", 
+            escapeText(names[i])));
+       }
+
+       // Get numerical data (as with getNumericalInfo)
+       DecimalFormatSymbols fmtSyms 
+               = DecimalFormatSymbols.getInstance(locale);
+
+       // ISO 4217 code
+       String currencyCode = fmtSyms.getInternationalCurrencySymbol();
+
+       // Currency symbol
+       String currency = fmtSyms.getCurrencySymbol();
+
+       // Check for known unofficial currency codes
+
+       String localeCurrencyCode = currencyCode;
+
+       String countryCode = locale.getCountry();
+
+       if (countryCode != null && !"".equals(countryCode))
+       {
+          if (countryCode.equals("GG") || countryCode.equals("GGY")
+           || countryCode.equals("831"))
+          {// Guernsey
+             localeCurrencyCode = "GGP";
+             currency = POUND_STRING;
+          }
+          else if (countryCode.equals("JE") || countryCode.equals("JEY")
+           || countryCode.equals("832"))
+          {// Jersey
+             localeCurrencyCode = "JEP";
+             currency = POUND_STRING;
+          }
+          else if (countryCode.equals("IM") || countryCode.equals("IMN")
+           || countryCode.equals("833"))
+          {// Isle of Man
+             localeCurrencyCode = "IMP";
+             currency = String.format("M%s", POUND_STRING);
+          }
+          else if (countryCode.equals("KI") || countryCode.equals("KIR")
+           || countryCode.equals("296"))
+          {// Kiribati
+             localeCurrencyCode = "KID";
+             currency = "$";
+          }
+          else if (countryCode.equals("TV") || countryCode.equals("TUV")
+           || countryCode.equals("798"))
+          {// Tuvaluan
+             localeCurrencyCode = "TVD";
+             currency = "$";
+          }
+          // Transnistrian ruble omitted as it conflicts with ISO
+          // 4217. There's also no country code for
+          // Transnistria. Other currencies don't have an associated
+          // region code (for example, Somaliland) or don't have a
+          // known unofficial currency code (for example, Alderney).
+       }
+
+       // Convert known Unicode currency symbols to commands that
+       // may be redefined in TeX
+
+       String texCurrency = getTeXCurrency(currency);
+
+       NumberFormat numFormat = NumberFormat.getNumberInstance(locale);
+       NumberFormat intFormat = NumberFormat.getIntegerInstance(locale);
+       NumberFormat curFormat = NumberFormat.getCurrencyInstance(locale);
+       NumberFormat pcFormat = NumberFormat.getPercentInstance(locale);
+
+       String numGroup = String.format(
+         "{%s}{%s}{%s}{%d}{%s}{%s}{%s}{%s}{%s}{%s}{%s}",
+             escapeText(fmtSyms.getGroupingSeparator()),
+             escapeText(fmtSyms.getDecimalSeparator()),
+             escapeText(fmtSyms.getExponentSeparator()), 
+             numFormat.isGroupingUsed() ? 1 : 0,
+             currencyCode,
+             localeCurrencyCode,
+             escapeText(currency),
+             texCurrency,// already escaped
+             escapeText(fmtSyms.getMonetaryDecimalSeparator()),
+             escapeText(fmtSyms.getPercent()),
+             escapeText(fmtSyms.getPerMill()));
+
+       String numFmtGroup = String.format("{%s}{%s}{%s}{%s}",
+         formatNumberPattern(numFormat),
+         formatNumberPattern(intFormat),
+         formatNumberPattern(curFormat),
+         formatNumberPattern(pcFormat));
+
+       return String.format(
+          "{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}",
+             langRegionGroup,
+             dateGroup,
+             dateFmtGroup,
+             timeGroup,
+             timeFmtGroup,
+             dateTimeGroup,
+             dateTimeFmtGroup,
+             weekdayNamesGroup,
+             shortWeekdayNamesGroup,
+             monthNamesGroup,
+             shortMonthNamesGroup,
+             getStandaloneWeekdays(cal, locale),
+             getStandaloneShortWeekdays(cal, locale),
+             getStandaloneMonths(cal, locale),
+             getStandaloneShortMonths(cal, locale),
+             numGroup, numFmtGroup);
+   }
+
+    /**
+     * Prints the syntax usage.
+     */
+   protected void syntax()
+   {
+      System.out.println(String.format("Usage: %s [<options>] <actions>", name));
+
+      System.out.println();
+      System.out.println("Cross-platform OS query application");
+      System.out.println("for use with TeX's shell escape.");
+      System.out.println();
+      System.out.println("Each query displays the result in a single line.");
+      System.out.println("An empty string is printed if the requested");
+      System.out.println("information is unavailable or not permitted.");
+      System.out.println("Multiple actions group the results.");
+      System.out.println();
+      System.out.println("See the manual (texdoc texosquery) for further details.");
+
+      System.out.println();
+      System.out.println("Options:");
+      System.out.println();
+
+      System.out.println("-h or --help or -help");
+      System.out.println("\tDisplay this help message and exit.");
+      System.out.println();
+
+      System.out.println("-v or --version or -version");
+      System.out.println("\tDisplay version information and exit.");
+      System.out.println();
+
+      System.out.println("--nodebug");
+      System.out.println("\tNo debugging messages (default)");
+      System.out.println();
+
+      System.out.println("--debug [<n>] or -debug [<n>]");
+      System.out.println("\tDisplay debugging messages on STDOUT.");
+      System.out.println("\t<n> should be an integer:");
+      System.out.println("\t0: no debugging (same as --nodebug)");
+      System.out.println("\t1: basic debugging messages");
+      System.out.println("\t2: additionally display stack trace.");
+      System.out.println(String.format("\tIf omitted %d is assumed", DEFAULT_DEBUG_LEVEL));
+      System.out.println();
+
+      System.out.println("--compatible <n> or -compat <n>");
+      System.out.println("\tCompatibility setting.");
+      System.out.println("\t<n> should be \"latest\" (default) or an integer:");
+
+      for (int i = 0; i < DEFAULT_COMPATIBLE; i++)
+      {
+         System.out.println(String.format("\t%d: version 1.%d", i, i));
+      }
+
+      System.out.println();
+      System.out.println("General actions:");
+      System.out.println();
+
+      for (QueryAction action : AVAILABLE_ACTIONS)
+      {
+         if (action.getType() == QueryActionType.GENERAL_ACTION)
+         {
+            System.out.println(action.help());
+         }
+      }
+
+      System.out.println();
+      System.out.println("Locale actions:");
+      System.out.println();
+
+      for (QueryAction action : AVAILABLE_ACTIONS)
+      {
+         if (action.getType() == QueryActionType.LOCALE_ACTION)
+         {
+            System.out.println(action.help());
+         }
+      }
+
+      System.out.println();
+      System.out.println("File actions:");
+      System.out.println();
+      System.out.println("Paths should use / for the directory divider.");
+      System.out.println("TeX's openin_any setting is checked before attempting");
+      System.out.println("to access file information.");
+      System.out.println();
+
+      for (QueryAction action : AVAILABLE_ACTIONS)
+      {
+         if (action.getType() == QueryActionType.FILE_ACTION)
+         {
+            System.out.println(action.help());
+         }
+      }
+   }
+
+    /**
+     * Prints the version.
+     */
+   protected void version()
+   {
+       System.out.println(String.format("%s %s %s", name, VERSION_NUMBER,
+                VERSION_DATE));
+       System.out.println("Copyright 2016 Nicola Talbot");
+       System.out.println("License LPPL 1.3+ (http://ctan.org/license/lppl1.3)");
+   }
+
+    /**
+     * Prints the information with optional grouping.
+     * @param numActions Add grouping if number of actions > 1
+     * @param info Information to print
+     * @since 1.2
+     */ 
+   protected void print(int numActions, String info)
+   {
+      if (compatible == 0)
+      {
+         // version 1.0 didn't use grouping
+         System.out.println(info);
+      }
+      else
+      {
+         if (numActions > 1)
+         {
+            System.out.println(String.format("{%s}", info));
+         }
+         else
+         {
+            System.out.println(info);
+         }
+      }
+   }
+
+   /**
+    * Find the action corresponding to the name (the command line
+    * switch). Once the action has been found, a copy must be
+    * returned since the same action may be used multiple times with
+    * different arguments.
+    * @param action The command line switch (either the short or long
+    * form)
+    * @return a copy of the predefined action or null if not found 
+    * @since 1.2
+    */ 
+   private QueryAction getAction(String action)
+   {
+      for (int i = 0; i < AVAILABLE_ACTIONS.length; i++)
+      {
+         if (AVAILABLE_ACTIONS[i].isAction(action))
+         {
+            return AVAILABLE_ACTIONS[i].copy();
+         }
+      }
+
+      return null;
+   }
+
+   public static int parseArgVal(String[] args, int i, Object[] argVal)
+   {
+      String[] sp;
+
+      if (args[i].startsWith("--"))
+      {
+         sp = args[i].split("=", 2);
+      }
+      else
+      {
+         sp = new String[]{args[i]};
+      }
+
+      argVal[0] = sp[0];
+
+      if (sp.length == 2)
+      {
+         argVal[1] = sp[1];
+         return i;
+      }
+
+      if (i == args.length-1 || args[i+1].startsWith("-"))
+      {
+         argVal[1] = null;
+         return i; 
+      }
+
+      argVal[1] = args[++i];
+
+      return i;
+   }
+
+   public static int parseArgInt(String[] args, int i, Object[] argVal)
+   {
+      i = parseArgVal(args, i, argVal);
+
+      if (argVal[1] != null)
+      {
+         try
+         {
+            argVal[1] = new Integer((String)argVal[1]);
+         }
+         catch (NumberFormatException e)
+         {
+            throw new IllegalArgumentException(String.format(
+              "Invalid '%s' value: %s", argVal[0], argVal[1]), e);
+         }
+      }
+
+      return i;
+   }
+
+   public static boolean isArg(String arg, String shortArg, String longArg)
+   {
+      return arg.equals("-"+shortArg) || arg.equals("--"+longArg) 
+        || arg.startsWith("--"+longArg+"=");
+   }
+
+
+   public static boolean isArg(String arg, String longArg)
+   {
+      return arg.equals("--"+longArg) || arg.startsWith("--"+longArg+"=");
+   }
+
+    /**
+     * Process command line arguments. Options must come before
+     * actions. (The copied QueryAction objects retain the settings
+     * from the time of their creation.)
+     * @param args Command line arguments.
+     * @since 1.2
+     */
+   public void processArgs(String[] args)
+   {
+      Vector<QueryAction> actions = new Vector<QueryAction>();
+      Object[] argVal = new Object[2];
+
+      for (int i = 0; i < args.length; i++)
+      {
+         QueryAction action = getAction(args[i]);
+
+         if (action != null)
+         {
+            try
+            {
+               i = action.parseArgs(args, i)-1;
+               actions.add(action);
+            }
+            catch (IllegalArgumentException e)
+            {
+               debug(e.getMessage(), e);
+               throw e;
+            }
+            catch (Throwable e)
+            {
+               debug(e.getMessage(), e);
+               throw new IllegalArgumentException(e.getMessage(), e);
+            }
+         }
+         else if (args[i].equals("-h") || args[i].equals("--help")
+            || args[i].equals("-help"))
+         {
+            syntax();
+            System.exit(0);
+         }
+         else if (args[i].equals("-v") || args[i].equals("--version") 
+           || args[i].equals("-version"))
+         {
+            version();
+            System.exit(0);
+         }
+         else if (args[i].equals("--nodebug"))
+         {
+            if (actions.size() > 0)
+            {
+               throw new IllegalArgumentException(String.format(
+                "Options must come before actions. Found option: %s", args[i]));
+            }
+
+            debugLevel = 0;
+         }
+         else if (isArg(args[i], "debug", "debug"))
+         {
+            if (actions.size() > 0)
+            {
+               throw new IllegalArgumentException(String.format(
+                "Options must come before actions. Found option: %s", args[i]));
+            }
+
+            i = parseArgInt(args, i, argVal);
+
+            if (argVal[1] == null)
+            {
+               debugLevel = DEFAULT_DEBUG_LEVEL;
+            }
+            else
+            {
+               debugLevel = ((Integer)argVal[1]).intValue();
+
+               if (debugLevel < 0)
+               {
+                  throw new IllegalArgumentException(String.format(
+                    "Invalid debug level: %s", args[i]));
+               }
+            }
+         }
+         else if (args[i].equals("--compatible") || args[i].equals("-compat"))
+         {
+            if (actions.size() > 0)
+            {
+               throw new IllegalArgumentException(String.format(
+                "Options must come before actions. Found option: %s", args[i]));
+            }
+
+            i = parseArgVal(args, i, argVal);
+
+            if (argVal[1] == null)
+            {
+               throw new IllegalArgumentException(String.format(
+                 "<level> expected after: %s", args[i]));
+            }
+
+            if (argVal[1].equals("latest"))
+            {
+               compatible = DEFAULT_COMPATIBLE;
+            }
+            else
+            {
+               try
+               {
+                  compatible = Integer.parseInt((String)argVal[1]);
+               }
+               catch (NumberFormatException e)
+               {
+                  throw new IllegalArgumentException(String.format(
+                   "Invalid %s argument (\"latest\" or %d to %d required): %s",
+                   argVal[0], 0, DEFAULT_COMPATIBLE, argVal[1]), e);
+               }
+            }
+         }
+         else
+         {
+             throw new IllegalArgumentException(String.format(
+               "Unknown option: %s%nTry %s --help", args[i], name));
+         }
+      }
+
+      int numActions = actions.size();
+
+      if (numActions == 0)
+      {
+         throw new IllegalArgumentException(String.format(
+           "One or more actions required.%nTry %s --help", name));
+      }
+
+      for (QueryAction action : actions)
+      {
+         try
+         {
+            print(numActions, action.doAction(compatible));
+         }
+         catch (Throwable e)
+         {
+            // Any errors should've been picked up by the action, 
+            // so this is most likely a runtime error that needs
+            // to be reported.
+
+            System.err.println("Fatal error: "+e.getMessage());
+
+            if (debugLevel < DEBUG_STACK_TRACE_LEVEL)
+            {
+               System.err.println(String.format(
+                 "Use --debug %d to obtain stack trace", 
+                 DEBUG_STACK_TRACE_LEVEL));
+            }
+
+            debug(String.format("Action failed: %s", action.getInvocation()),
+              e);
+            System.exit(1);
+         }
+      }
+   }
+
+   private final QueryAction[] AVAILABLE_ACTIONS = new QueryAction[]
+   {
+      new QueryAction("cwd", "c", QueryActionType.FILE_ACTION, 
+        "Display current working directory")
+      {
+         public String action()
+         {
+            return getCwd();
+         }
+      },
+      new QueryAction("userhome", "m", QueryActionType.FILE_ACTION,
+         "Display user's home directory")
+      {
+         public String action()
+         {
+            return getUserHome();
+         }
+      },
+      new QueryAction("tmpdir", "t", QueryActionType.FILE_ACTION,
+         "Display temporary directory")
+      {
+         public String action()
+         {
+            return getTmpDir();
+         }
+      },
+      new QueryAction("osname", "o", QueryActionType.GENERAL_ACTION,
+        "Display OS name")
+      {
+         public String action()
+         {
+            return getOSname();
+         }
+      },
+      new QueryAction("osversion", "r", QueryActionType.GENERAL_ACTION, 
+        "Display OS version")
+      {
+         public String action()
+         {
+            return getOSversion();
+         }
+      },
+      new QueryAction("osarch", "a", QueryActionType.GENERAL_ACTION, 
+        "Display OS architecture")
+      {
+         public String action()
+         {
+            return getOSarch();
+         }
+      },
+      new QueryAction("pdfnow", "n", QueryActionType.GENERAL_ACTION, 
+        "Display current date-time in PDF format")
+      {
+         public String action()
+         {
+            return pdfnow();
+         }
+      },
+      new QueryAction("locale", "L", QueryActionType.LOCALE_ACTION,
+         "Display POSIX locale information")
+      {
+         public String action()
+         {
+            return getLocale(Locale.getDefault());
+         }
+      },
+      new QueryAction("locale-lcs", "l", QueryActionType.LOCALE_ACTION,
+         "Display POSIX style locale information with lower case codeset")
+      {
+         public String action()
+         {
+            return getLocale(Locale.getDefault(), true);
+         }
+      },
+      new QueryAction("codeset-lcs", "C", QueryActionType.GENERAL_ACTION, 
+         "Lower case codeset with hyphens stripped", 2)
+      {
+         public String action()
+         {
+            return escapeFileName(getCodeSet(true));
+         }
+      },
+      new QueryAction("bcp47", "b", QueryActionType.LOCALE_ACTION,
+         "Display locale as BCP47 tag", 2)
+      {
+         public String action()
+         {
+            return escapeFileName(getLanguageTag(null));
+         }
+      },
+      new QueryAction("numeric", "N", 1, 0, "[locale]",
+          QueryActionType.LOCALE_ACTION,
+          "Display locale numeric information", 2)
+      {
+         public String action()
+         {
+            return getNumericalInfo(getOptionalArgument(0));
+         }
+      },
+      new QueryAction("locale-data", "D", 1, 0, "[locale]",
+         QueryActionType.LOCALE_ACTION,
+         "Display all available locale information", 2)
+      {
+         public String action()
+         {
+            return getLocaleData(getOptionalArgument(0));
+         }
+      },
+      new QueryAction("date-time", "M", 
+         QueryActionType.GENERAL_ACTION,
+         "Display all the current date-time data", 2)
+      {
+         public String action()
+         {
+            return getDateTimeData();
+         }
+      },
+      new QueryAction("time-zones", "Z", 1, 0, "[locale]",
+         QueryActionType.LOCALE_ACTION,
+         "Display all available time zone information", 2)
+      {
+         public String action()
+         {
+            return getTimeZones(getOptionalArgument(0));
+         }
+      },
+      new QueryAction("pdfdate", "d", 0, 1, "<file>",
+         QueryActionType.FILE_ACTION, 
+         "Display date stamp of <file> in PDF format")
+      {
+         public String action()
+         {
+            return pdfDate(fileFromTeXPath(getRequiredArgument(0)));
+         }
+      },
+      new QueryAction("filesize", "s", 0, 1, "<file>",
+         QueryActionType.FILE_ACTION,
+         "Display size of <file> in bytes")
+      {
+         public String action()
+         {
+            return getFileLength(fileFromTeXPath(getRequiredArgument(0)));
+         }
+      },
+      new QueryAction("list", "i", 1, 2, "<sep> <dir> [<sort>]",
+         QueryActionType.FILE_ACTION,
+         String.format("Display list of all files in <dir> separated by <sep>. If <sort> is omitted, the default order is used otherwise <sort> may be one of the following: %s",
+           FileSortType.getFileSortOptions()))
+      {
+         public String action()
+         {
+            return getFileList(getRequiredArgument(0),
+              new File(fromTeXPath(getRequiredArgument(1))),
+                  FileSortType.getFileSortType(getOptionalArgument(0)),
+                  FileListType.FILE_LIST_ANY);
+         }
+      },
+      new QueryAction("filterlist", "f", 1, 3, "<sep> <regex> <dir> [<sort>]",
+         QueryActionType.FILE_ACTION, 
+         String.format("Display list of files in <dir> that fully match <regex> separated by <sep>. If <sort> is omitted, the default order is used otherwise <sort> may be one of the following: %s", 
+           FileSortType.getFileSortOptions()))
+      {
+         public String action()
+         {
+            return getFilterFileList(
+                  getRequiredArgument(0), 
+                  getRequiredArgument(1), 
+                  new File(fromTeXPath(getRequiredArgument(2))),
+                  FileSortType.getFileSortType(getOptionalArgument(0)),
+                  FileListType.FILE_LIST_ANY);
+         }
+      },
+      new QueryAction("list-dir", "id", 1, 2, "<sep> <dir> [<sort>]",
+         QueryActionType.FILE_ACTION,
+         String.format("Display list of all sub-directories in <dir> separated by <sep>. If <sort> is omitted, the default order is used otherwise <sort> may be one of the following: %s",
+           FileSortType.getFileSortOptions()))
+      {
+         public String action()
+         {
+            return getFileList(getRequiredArgument(0),
+              new File(fromTeXPath(getRequiredArgument(1))),
+                  FileSortType.getFileSortType(getOptionalArgument(0)),
+                  FileListType.FILE_LIST_DIRECTORIES_ONLY);
+         }
+      },
+      new QueryAction("filterlist-dir", "fd", 1, 3, "<sep> <regex> <dir> [<sort>]",
+         QueryActionType.FILE_ACTION, 
+         String.format("Display list of sub-directories in <dir> that fully match <regex> separated by <sep>. If <sort> is omitted, the default order is used otherwise <sort> may be one of the following: %s", 
+           FileSortType.getFileSortOptions()))
+      {
+         public String action()
+         {
+            return getFilterFileList(
+                  getRequiredArgument(0), 
+                  getRequiredArgument(1), 
+                  new File(fromTeXPath(getRequiredArgument(2))),
+                  FileSortType.getFileSortType(getOptionalArgument(0)),
+                  FileListType.FILE_LIST_DIRECTORIES_ONLY);
+         }
+      },
+      new QueryAction("list-regular", "ir", 1, 2, "<sep> <dir> [<sort>]",
+         QueryActionType.FILE_ACTION,
+         String.format("Display list of all regular files in <dir> separated by <sep>. If <sort> is omitted, the default order is used otherwise <sort> may be one of the following: %s",
+           FileSortType.getFileSortOptions()))
+      {
+         public String action()
+         {
+            return getFileList(getRequiredArgument(0),
+              new File(fromTeXPath(getRequiredArgument(1))),
+                  FileSortType.getFileSortType(getOptionalArgument(0)),
+                  FileListType.FILE_LIST_REGULAR_FILES_ONLY);
+         }
+      },
+      new QueryAction("filterlist-regular", "fr", 1, 3, "<sep> <regex> <dir> [<sort>]",
+         QueryActionType.FILE_ACTION, 
+         String.format("Display list of regular files in <dir> that fully match <regex> separated by <sep>. If <sort> is omitted, the default order is used otherwise <sort> may be one of the following: %s", 
+           FileSortType.getFileSortOptions()))
+      {
+         public String action()
+         {
+            return getFilterFileList(
+                  getRequiredArgument(0), 
+                  getRequiredArgument(1), 
+                  new File(fromTeXPath(getRequiredArgument(2))),
+                  FileSortType.getFileSortType(getOptionalArgument(0)),
+                  FileListType.FILE_LIST_REGULAR_FILES_ONLY);
+         }
+      },
+      new QueryAction("walk", "w", 1, 3, "<sep> <regex> <dir> [<sort>]",
+         QueryActionType.FILE_ACTION, 
+          String.format("Display list of regular non-hidden files in <dir> (descending sub-directories) that fully match <regex> separated by <sep>. The starting directory <dir> may not be outside the current working directory. This action is not available for texosquery-jre5. If <sort> is omitted, the default order is used otherwise <sort> may be one of the following: %s", 
+           FileSortType.getFileSortOptions()), 2)
+      {
+         public String action()
+         {
+            return walk(
+                  getRequiredArgument(0), 
+                  getRequiredArgument(1), 
+                  new File(fromTeXPath(getRequiredArgument(2))),
+                  FileSortType.getFileSortType(getOptionalArgument(0)));
+         }
+      },
+      new QueryAction("uri", "u", 0, 1, "<file>",
+         QueryActionType.FILE_ACTION, "Display the URI of <file>")
+      {
+         public String action()
+         {
+            return fileURI(fileFromTeXPath(getRequiredArgument(0)));
+         }
+      },
+      new QueryAction("path", "p", 0, 1, "<file>",
+         QueryActionType.FILE_ACTION, "Display the canonical path of <file>")
+      {
+         public String action()
+         {
+            return filePath(fileFromTeXPath(getRequiredArgument(0)));
+         }
+      },
+      new QueryAction("dirname", "e", 0, 1, "<file>",
+         QueryActionType.FILE_ACTION,
+         "Display the canonical path of the parent of <file>")
+      {
+         public String action()
+         {
+            return parentPath(fileFromTeXPath(getRequiredArgument(0)));
+         }
+      }
+   };
+
+   /**
+    * Application name.
+    */ 
+   private String name;
+    
+   public static final int DEFAULT_COMPATIBLE=2;
+
+   private static final String VERSION_NUMBER = "1.2";
+   private static final String VERSION_DATE = "2017-03-23";
+   private static final char BACKSLASH = '\\';
+   private static final long ZERO = 0L;
+
+   /**
+    * Initialise current date-time for consistency.
+    */ 
+
+   private Date now = new Date();
+
+   /**
+    * openin_any settings
+    */
+   private static final char OPENIN_UNSET=0; // unset
+   private static final char OPENIN_A='a'; // any
+   private static final char OPENIN_R='r'; // restricted
+   private static final char OPENIN_P='p'; // paranoid
+
+   private char openin = OPENIN_UNSET;
+
+   private File texmfoutput = null;
+
+   /**
+    * Debug level. (0 = no debugging, 1 or more print error messages to
+    * STDERR, 2 or more include stack trace, 3 or more include
+    * informational messages.)
+    */
+   private int debugLevel = 0;
+
+   public static final int DEFAULT_DEBUG_LEVEL=3;
+   public static final int DEBUG_ERROR_LEVEL=1;
+   public static final int DEBUG_STACK_TRACE_LEVEL=2;
+   public static final int DEBUG_INFO_LEVEL=3;
+
+   /**
+    * Compatibility mode. Version 1.2 replaces escapeHash with
+    * escapeSpChars, which switches to using \\fhsh etc. Provide a
+    * mode to restore the previous behaviour.
+    */ 
+   private int compatible = DEFAULT_COMPATIBLE;
+
+   // TeX can only go up to 2147483647, so set the maximum number
+   // of digits provided for the number formatter. 
+
+   private static final int MAX_DIGIT_FORMAT=10;
+
+   // Dollar symbol
+   private static final char DOLLAR_CHAR=0x0024;
+
+   // Cent symbol
+   private static final char CENT_CHAR=0x00A2;
+
+   // Pound symbol
+   private static final char POUND_CHAR=0x00A3;
+
+   // Pound symbol as a string
+   private static final String POUND_STRING=""+POUND_CHAR;
+
+   // Currency symbol
+   private static final char CURRENCY_CHAR=0x00A4;
+
+   // Yen symbol
+   private static final char YEN_CHAR=0x00A5;
+
+   // ECU symbol
+   private static final char ECU_CHAR=0x20A0;
+
+   // Colon currency symbol
+   private static final char COLON_CURRENCY_CHAR=0x20A1;
+
+   // Cruzeiro symbol
+   private static final char CRUZEIRO_CHAR=0x20A2;
+
+   // Franc symbol
+   private static final char FRANC_CHAR=0x20A3;
+
+   // Lira symbol
+   private static final char LIRA_CHAR=0x20A4;
+
+   // Mill currency symbol
+   private static final char MILL_CURRENCY_CHAR=0x20A5;
+
+   // Naira symbol
+   private static final char NAIRA_CHAR=0x20A6;
+
+   // Peseta symbol
+   private static final char PESETA_CHAR=0x20A7;
+
+   // Legacy rupee symbol
+   private static final char LEGACY_RUPEE_CHAR=0x20A8;
+
+   // Won symbol
+   private static final char WON_CHAR=0x20A9;
+
+   // New sheqel symbol
+   private static final char NEW_SHEQEL_CHAR=0x20AA;
+
+   // Dong symbol
+   private static final char DONG_CHAR=0x20AB;
+
+   // Euro symbol
+   private static final char EURO_CHAR=0x20AC;
+
+   // Kip symbol
+   private static final char KIP_CHAR=0x20AD;
+
+   // Tugrik symbol
+   private static final char TUGRIK_CHAR=0x20AE;
+
+   // Drachma symbol
+   private static final char DRACHMA_CHAR=0x20AF;
+
+   // German penny symbol
+   private static final char GERMAN_PENNY_CHAR=0x20B0;
+
+   // Peso symbol
+   private static final char PESO_CHAR=0x20B1;
+
+   // Guarani symbol
+   private static final char GUARANI_CHAR=0x20B2;
+
+   // Austral symbol
+   private static final char AUSTRAL_CHAR=0x20B3;
+
+   // Hryvnia symbol
+   private static final char HRYVNIA_CHAR=0x20B4;
+
+   // Cedi symbol
+   private static final char CEDI_CHAR=0x20B5;
+
+   // Livre tournois symbol
+   private static final char LIVRE_TOURNOIS_CHAR=0x20B6;
+
+   // Spesmilo symbol
+   private static final char SPESMILO_CHAR=0x20B7;
+
+   // Tenge symbol
+   private static final char TENGE_CHAR=0x20B8;
+
+   // Official rupee symbol
+   private static final char RUPEE_CHAR=0x20B9;
+
+   // Turkish lira symbol
+   private static final char TURKISH_LIRA_CHAR=0x20BA;
+
+   // Nordic mark symbol
+   private static final char NORDIC_MARK_CHAR=0x20BB;
+
+   // Manat symbol
+   private static final char MANAT_CHAR=0x20BC;
+
+   // Ruble symbol
+   private static final char RUBLE_CHAR=0x20BD;
+
+   // Per mille symbol
+   private static final char PERMILLE_CHAR=0x2030;
+}


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQuery.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE5.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE5.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE5.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,54 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+import java.io.BufferedReader;
+import java.util.Locale;
+import java.util.Calendar;
+import java.text.DecimalFormatSymbols;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * Main class. Supports Java 5 onwards.
+ * @author Nicola Talbot
+ * @version 1.2
+ * @since 1.2
+ */
+public class TeXOSQueryJRE5 extends TeXOSQuery
+{
+   public TeXOSQueryJRE5()
+   {
+      super("texosquery-jre5");
+   }
+
+    /**
+     * Main method.
+     * @param args Command line arguments.
+     */
+   public static void main(String[] args)
+   {
+      try
+      {
+         (new TeXOSQueryJRE5()).processArgs(args);
+      }
+      catch (IllegalArgumentException e)
+      {
+         System.err.println(e.getMessage());
+         System.exit(1);
+      }
+   }
+}


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE5.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE7.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE7.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE7.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,197 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+import java.util.Locale;
+import java.util.Locale.Builder;
+import java.util.Calendar;
+import java.io.Serializable;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Main class. Supports Java 7 onwards.
+ * @author Nicola Talbot
+ * @version 1.2
+ * @since 1.2
+ */
+public class TeXOSQueryJRE7 extends TeXOSQuery
+{
+   public TeXOSQueryJRE7()
+   {
+      super("texosquery");
+   }
+
+   /**
+    * Converts the given directory to a canonical path
+    * and checks to make sure it has a parent directory.
+    * @param dir the directory to check
+    * @return the canonical path
+    * @throws IOException if directory can't be converted to a
+    * canonical path or if the canonical path doesn't have a parent
+    * directory or is outside the current working directory
+    */ 
+   @Override
+   protected File checkDirectoryListing(File dir) throws IOException
+   {
+      dir = dir.getCanonicalFile();
+
+      if (dir.getParentFile() == null)
+      {
+         throw new IOException(String.format(
+           "Listing on root directory not permitted: %s", dir));
+      }
+
+      File cwd = new File(getSystemProperty("user.dir", "."));
+
+      if (!cwd.equals(dir) && !isFileInTree(dir, cwd))
+      {
+         throw new IOException(String.format(
+           "Listing outside cwd path not permitted: %s", dir));
+      }
+
+      return dir;
+   }
+
+   /**
+    * Recursive file listing. This method must have the CWD or a
+    * descendent as the starting directory. It will return list of
+    * files relative to the starting directory where the basename
+    * matches the supplied regular expression. Hidden files/directories 
+    * and symbolic links are skipped regardless of the openin_any setting.
+    * Files without read access are also omitted from the list.
+    *
+    * @param separator separator to use in returned list
+    * @param regex regular expression used to match file basenames
+    * @param directory starting directory (must be cwd or a
+    * descendent of cwd)
+    * @return list of relative paths
+    */
+   @Override
+   public String walk(String separator,
+            String regex, File directory, 
+            FileSortType sortType)
+   {
+      try
+      {
+         return FileWalkVisitor.walk(this, separator,
+           regex, directory, sortType);
+      }
+      catch (Exception e)
+      {
+         debug(String.format("Can't walk directory: %s",
+           directory.toString()), e);
+      }
+
+      return "";
+   }
+
+    /**
+     * Gets the script for the given locale.
+     * @param locale The locale
+     * @return The language script associated with the given locale or null if not available
+     */
+   @Override
+   public String getScript(Locale locale)
+   {
+      return locale.getScript();
+   }
+
+   /**
+    * Gets the locale from the given language tag.
+    * @param languageTag The language tag
+    * @return The locale that closest matches the language tag
+    */
+   @Override
+   public Locale getLocale(String languageTag)
+   {
+      Locale locale = Locale.forLanguageTag(languageTag);
+
+      // Locale.forLanguageTag() doesn't recognise
+      // numeric regions. So test for a numeric region.
+
+      String region = locale.getCountry();
+
+      try
+      {
+         region = getRegionAlpha2Code(Integer.parseInt(region));
+      }
+      catch (NumberFormatException e)
+      {
+         // region isn't numeric, so we don't need to do anything
+         // else
+         return locale;
+      }
+
+      Locale.Builder builder = new Locale.Builder();
+      builder.setLocale(locale);
+      builder.setRegion(region);
+
+      return builder.build();
+   }
+
+   /**
+    * Gets the language tag for the given locale.
+    * @param locale The locale or null for the default locale
+    * @return The language tag
+    */
+   @Override
+   public String getLanguageTag(Locale locale)
+   {
+      if (locale == null)
+      {
+         locale = Locale.getDefault();
+      }
+
+      return locale.toLanguageTag();
+   }
+
+   /**
+    * Gets the week year for the given calendar.
+    * @return The week year
+    */
+   @Override
+   public int getWeekYear(Calendar cal)
+   {
+      try
+      {
+        return cal.isWeekDateSupported() ?
+          cal.getWeekYear() : cal.get(Calendar.YEAR);
+      }
+      catch (UnsupportedOperationException e)
+      {
+         // shouldn't happen with the above conditional, but just in
+         // case...
+
+         debug(e.getMessage(), e);
+         return cal.get(Calendar.YEAR);
+      }
+   }
+
+   /**
+    * Main method.
+    * @param args Command line arguments.
+    */
+   public static void main(String[] args)
+   {
+      try
+      {
+         (new TeXOSQueryJRE7()).processArgs(args);
+      }
+      catch (IllegalArgumentException e)
+      {
+         System.err.println(e.getMessage());
+         System.exit(1);
+      }
+   }
+}


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE7.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE8.java
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE8.java	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE8.java	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,377 @@
+/*
+    Copyright (C) 2016 Nicola L.C. Talbot
+    www.dickimaw-books.com
+
+    This work may be distributed and/or modified under the
+    conditions of the LaTeX Project Public License, either version 1.3
+    of this license or (at your option) any later version.
+    The latest version of this license is in
+    http://www.latex-project.org/lppl.txt
+    and version 1.3 or later is part of all distributions of LaTeX
+    version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+import java.util.Locale;
+import java.util.Locale.Builder;
+import java.util.Calendar;
+import java.util.Map;
+import java.util.Arrays;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Main class. Supports Java 8 onwards.
+ * @author Nicola Talbot
+ * @version 1.2
+ * @since 1.2
+ */
+public class TeXOSQueryJRE8 extends TeXOSQuery
+{
+   public TeXOSQueryJRE8()
+   {
+      super("texosquery-jre8");
+   }
+
+   /**
+    * Converts the given directory to a canonical path
+    * and checks to make sure it has a parent directory.
+    * @param dir the directory to check
+    * @return the canonical path
+    * @throws IOException if directory can't be converted to a
+    * canonical path or if the canonical path doesn't have a parent
+    * directory or is outside the current working directory
+    */ 
+   @Override
+   protected File checkDirectoryListing(File dir) throws IOException
+   {
+      dir = dir.getCanonicalFile();
+
+      if (dir.getParentFile() == null)
+      {
+         throw new IOException(String.format(
+           "Listing on root directory not permitted: %s", dir));
+      }
+
+      File cwd = new File(getSystemProperty("user.dir", "."));
+
+      if (!cwd.equals(dir) && !isFileInTree(dir, cwd))
+      {
+         throw new IOException(String.format(
+           "Listing outside cwd path not permitted: %s", dir));
+      }
+
+      return dir;
+   }
+
+   /**
+    * Recursive file listing. This method must have the CWD or a
+    * descendent as the starting directory. It will return list of
+    * files relative to the starting directory where the basename
+    * matches the supplied regular expression. Hidden files/directories 
+    * and symbolic links are skipped regardless of the openin_any setting.
+    * Files without read access are also omitted from the list.
+    *
+    * @param separator separator to use in returned list
+    * @param regex regular expression used to match file basenames
+    * @param directory starting directory (must be cwd or a
+    * descendent of cwd)
+    * @return list of relative paths
+    */
+   @Override
+   public String walk(String separator,
+            String regex, File directory, 
+            FileSortType sortType)
+   {
+      try
+      {
+         return FileWalkVisitor.walk(this, separator,
+           regex, directory, sortType);
+      }
+      catch (Exception e)
+      {
+         debug(String.format("Can't walk directory: %s",
+           directory.toString()), e);
+      }
+
+      return "";
+   }
+
+
+    /**
+     * Gets the script for the given locale.
+     * @param locale The locale
+     * @return The language script associated with the given locale or null if not available
+     */
+   @Override
+   public String getScript(Locale locale)
+   {
+      return locale.getScript();
+   }
+
+   /**
+    * Gets the locale from the given language tag.
+    * @param languageTag The language tag
+    * @return The locale that closest matches the language tag
+    */
+   @Override
+   public Locale getLocale(String languageTag)
+   {
+      Locale locale = Locale.forLanguageTag(languageTag);
+
+      // Locale.forLanguageTag() doesn't recognise
+      // numeric regions. So test for a numeric region.
+
+      String region = locale.getCountry();
+
+      try
+      {
+         region = getRegionAlpha2Code(Integer.parseInt(region));
+      }
+      catch (NumberFormatException e)
+      {
+         // region isn't numeric, so we don't need to do anything
+         // else
+         return locale;
+      }
+
+      Locale.Builder builder = new Locale.Builder();
+      builder.setLocale(locale);
+      builder.setRegion(region);
+
+      return builder.build();
+   }
+
+   /**
+    * Gets the language tag for the given locale.
+    * @param locale The locale or null for the default locale
+    * @return The language tag
+    */
+   @Override
+   public String getLanguageTag(Locale locale)
+   {
+      if (locale == null)
+      {
+         locale = Locale.getDefault();
+      }
+
+      return locale.toLanguageTag();
+   }
+
+   /**
+    * Gets the week year for the given calendar.
+    * @return The week year
+    */
+   @Override
+   public int getWeekYear(Calendar cal)
+   {
+      try
+      {
+        return cal.isWeekDateSupported() ?
+          cal.getWeekYear() : cal.get(Calendar.YEAR);
+      }
+      catch (UnsupportedOperationException e)
+      {
+         // shouldn't happen with the above conditional, but just in
+         // case...
+
+         debug(e.getMessage(), e);
+         return cal.get(Calendar.YEAR);
+      }
+   }
+
+   /** Gets the standalone month names for the locale data.
+    * These are only available for Java 8, so just return the 
+    * month names used in the date format instead.
+    * @param cal The calendar
+    * @param locale The locale
+    * @return month names
+    */
+   public String getStandaloneMonths(Calendar cal, Locale locale)
+   {
+      Map<String,Integer> map = cal.getDisplayNames(Calendar.MONTH,
+        Calendar.LONG_STANDALONE, locale);
+
+      // Is the map order? Not sure so save in an array
+
+      String[] names = new String[12];
+
+      for (Map.Entry<String,Integer> entry : map.entrySet())
+      {
+         int idx = entry.getValue().intValue();
+
+         if (idx < 12)
+         {// Java has a 13th month that we're ignoring
+            names[idx] = entry.getKey();
+         }
+      }
+
+      StringBuilder builder = new StringBuilder();
+
+      for (int i = 0; i < names.length; i++)
+      {
+         builder.append(String.format("{%s}", escapeText(names[i])));
+      }
+
+      return builder.toString();
+   }
+
+   /** Gets the standalone short month names for the locale data.
+    * @param cal The calendar
+    * @param locale The locale
+    * @return month names
+    */
+   public String getStandaloneShortMonths(Calendar cal, Locale locale)
+   {
+      Map<String,Integer> map = cal.getDisplayNames(Calendar.MONTH,
+        Calendar.SHORT_STANDALONE, locale);
+
+      // Is the map order? Not sure so save in an array
+
+      String[] names = new String[12];
+
+      for (Map.Entry<String,Integer> entry : map.entrySet())
+      {
+         int idx = entry.getValue().intValue();
+
+         if (idx < names.length)
+         {
+            names[idx] = entry.getKey();
+         }
+      }
+
+      StringBuilder builder = new StringBuilder();
+
+      for (int i = 0; i < names.length; i++)
+      {
+         builder.append(String.format("{%s}", escapeText(names[i])));
+      }
+
+      return builder.toString();
+   }
+
+
+   /** Gets the standalone week day names for the locale data.
+    * @param cal The calendar
+    * @param locale The locale
+    * @return week day names
+    */
+   public String getStandaloneWeekdays(Calendar cal, Locale locale)
+   {
+      Map<String,Integer> map = cal.getDisplayNames(Calendar.DAY_OF_WEEK,
+        Calendar.LONG_STANDALONE, locale);
+
+      String[] names = new String[7];
+
+      for (Map.Entry<String,Integer> entry : map.entrySet())
+      {
+         switch (entry.getValue().intValue())
+         {
+            case Calendar.MONDAY:
+              names[0] = entry.getKey();
+            break;
+            case Calendar.TUESDAY:
+              names[1] = entry.getKey();
+            break;
+            case Calendar.WEDNESDAY:
+              names[2] = entry.getKey();
+            break;
+            case Calendar.THURSDAY:
+              names[3] = entry.getKey();
+            break;
+            case Calendar.FRIDAY:
+              names[4] = entry.getKey();
+            break;
+            case Calendar.SATURDAY:
+              names[5] = entry.getKey();
+            break;
+            case Calendar.SUNDAY:
+              names[6] = entry.getKey();
+            break;
+         }
+      }
+
+      StringBuilder builder = new StringBuilder();
+
+      for (int i = 0; i < names.length; i++)
+      {
+         builder.append(String.format("{%s}", escapeText(names[i])));
+      }
+
+      return builder.toString();
+   }
+
+   /** Gets the standalone short week day names for the locale data.
+    * @param cal The calendar
+    * @param locale The locale
+    * @return week day names
+    */
+   public String getStandaloneShortWeekdays(Calendar cal, Locale locale)
+   {
+      Map<String,Integer> map = cal.getDisplayNames(Calendar.DAY_OF_WEEK,
+        Calendar.SHORT_STANDALONE, locale);
+
+      String[] names = new String[7];
+
+      for (Map.Entry<String,Integer> entry : map.entrySet())
+      {
+         switch (entry.getValue().intValue())
+         {
+            case Calendar.MONDAY:
+              names[0] = entry.getKey();
+            break;
+            case Calendar.TUESDAY:
+              names[1] = entry.getKey();
+            break;
+            case Calendar.WEDNESDAY:
+              names[2] = entry.getKey();
+            break;
+            case Calendar.THURSDAY:
+              names[3] = entry.getKey();
+            break;
+            case Calendar.FRIDAY:
+              names[4] = entry.getKey();
+            break;
+            case Calendar.SATURDAY:
+              names[5] = entry.getKey();
+            break;
+            case Calendar.SUNDAY:
+              names[6] = entry.getKey();
+            break;
+         }
+      }
+
+      StringBuilder builder = new StringBuilder();
+
+      for (int i = 0; i < names.length; i++)
+      {
+         builder.append(String.format("{%s}", escapeText(names[i])));
+      }
+
+      return builder.toString();
+   }
+
+   @Override
+   public void sortFileList(String[] list, File directory, 
+      FileSortType sortType)
+   {
+      Arrays.parallelSort(list, new FileSortComparator(directory, sortType));
+   }
+
+   /**
+    * Main method.
+    * @param args Command line arguments.
+    */
+   public static void main(String[] args)
+   {
+      try
+      {
+         (new TeXOSQueryJRE8()).processArgs(args);
+      }
+      catch (IllegalArgumentException e)
+      {
+         System.err.println(e.getMessage());
+         System.exit(1);
+      }
+   }
+}


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/java/TeXOSQueryJRE8.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/texosquery-jre5.batch
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/texosquery-jre5.batch	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/texosquery-jre5.batch	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,4 @@
+
+ at ECHO OFF
+FOR /F %%I IN ('kpsewhich --progname=texosquery --format=texmfscripts texosquery-jre5.jar') DO SET JARPATH=%%I
+java -jar "%JARPATH%" %*


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/texosquery-jre5.batch
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/texosquery-jre8.batch
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/texosquery-jre8.batch	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/texosquery-jre8.batch	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,4 @@
+
+ at ECHO OFF
+FOR /F %%I IN ('kpsewhich --progname=texosquery --format=texmfscripts texosquery-jre8.jar') DO SET JARPATH=%%I
+java -Djava.locale.providers=CLDR,JRE -jar "%JARPATH%" %*


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/texosquery-jre8.batch
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/texosquery/texosquery.batch
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/texosquery.batch	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/texosquery/texosquery.batch	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,4 @@
+
+ at ECHO OFF
+FOR /F %%I IN ('kpsewhich --progname=texosquery --format=texmfscripts texosquery.jar') DO SET JARPATH=%%I
+java -jar "%JARPATH%" %*


Property changes on: trunk/Master/texmf-dist/source/support/texosquery/texosquery.batch
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/support/texosquery/texosquery.dtx
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/texosquery.dtx	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/texmf-dist/source/support/texosquery/texosquery.dtx	2017-03-24 22:42:34 UTC (rev 43596)
@@ -19,7 +19,7 @@
 %\fi
 % \iffalse
 % Doc-Source file
-% Copyright (C) 2016 Nicola Talbot, all rights reserved.
+% Copyright (C) 2017 Nicola Talbot, all rights reserved.
 % \fi
 % \iffalse
 %<*driver>
@@ -26,32 +26,91 @@
 \documentclass{ltxdoc}
 
 \usepackage[T1]{fontenc}
+\usepackage[utf8]{inputenc}
+\usepackage{etoolbox}
+\usepackage{textcomp}
 \usepackage{tgtermes}
+\usepackage{upquote}
 \usepackage{metalogo}
 \usepackage[colorlinks,hyperindex=false]{hyperref}
+\usepackage[abbreviations,nomain,nonumberlist,nogroupskip]{glossaries-extra}
 
-\CheckSum{269}
+\makeglossaries
 
+\makeatletter% doc.sty interferes with upquote.sty
+\def\@verbatim{\trivlist \item[]\if at minipage\else\vskip\parskip\fi
+      \leftskip\@totalleftmargin\rightskip\z@
+      \parindent\z@\parfillskip\@flushglue\parskip\z@
+      \@@par
+      \@tempswafalse
+ \def\par{\if at tempswa\hbox{}\fi\@tempswatrue\@@par
+          \penalty\interlinepenalty
+   \check at percent}%
+ \obeylines
+ \@noligs
+ \let\do\@makeother \dospecials}
+
+\renewcommand{\meta at font@select}{\rmfamily\itshape}
+\makeatother
+
+\CheckSum{3260}
+
 \RecordChanges
 \PageIndex
 \CodelineNumbered
-\IndexPrologue{}
+\IndexPrologue{\clearpage\phantomsection\section*{Index}\markboth{Index}{Index}%
+\addcontentsline{toc}{section}{Index}}
+\setcounter{IndexColumns}{2}
 
 \renewcommand*{\usage}[1]{\hyperpage{#1}}
 \renewcommand*{\main}[1]{\hyperpage{#1}}
 
+\newcommand*{\qt}[1]{``#1''}
+\newcommand*{\sty}[1]{\textsf{#1}}
+\newcommand*{\app}[1]{\texttt{#1}}
+\newcommand*{\file}[1]{\texttt{#1}}
+\providecommand*{\eTeX}{e\TeX}
+
 \newcommand*{\shortargfmt}[1]{\texttt{-#1}}
 \newcommand*{\longargfmt}[1]{\texttt{-{}-#1}}
 
 \newcommand*{\shortarg}[1]{\shortargfmt{#1}%
- \index{texosquery options=\texttt{texosquery} options>#1=\protect\shortargfmt{-#1}|hyperpage}}
+ \index{texosquery options=\app{texosquery} options>#1=\protect\shortargfmt{-#1}|hyperpage}}
 \newcommand*{\longarg}[1]{\longargfmt{#1}%
- \index{texosquery options=\texttt{texosquery} options>#1=\protect\longargfmt{#1}|hyperpage}}
+ \index{texosquery options=\app{texosquery} options>#1=\protect\longargfmt{#1}|hyperpage}}
 
 \newenvironment{important}
  {\begin{quote}\textbf{Important Note:}}
  {\end{quote}}
 
+\newenvironment{definition}
+ {\begin{flushleft}\ttfamily}
+ {\end{flushleft}}
+
+\setcounter{secnumdepth}{2}
+
+\pdfstringdefDisableCommands{\renewcommand\meta[1]{#1}}
+
+\glssetcategoryattribute{abbreviation}{nohyperfirst}{true}
+
+\setabbreviationstyle[noexpand]{short}
+\newabbreviation[category=noexpand]{IETF}{IETF}{Internet Engineering Task Force}
+\newabbreviation[category=noexpand]{BCP}{BCP}{Best Common Practice}
+\newabbreviation[category=noexpand]{POSIX}{POSIX}{Portable Operating
+System Interface}
+\newabbreviation[category=noexpand]{CTAN}{CTAN}{Comprehensive \TeX\
+Archive Network}
+\newabbreviation[category=noexpand]{UTF}{UTF}{Unicode Transformation
+Format}
+\newabbreviation[category=noexpand]{ASCII}{ASCII}{American Standard
+Code for Information Interchange}
+\newabbreviation[category=noexpand]{ISO}{ISO}{International
+Organization for Standardization}
+
+\newabbreviation{OS}{OS}{operating system}
+\newabbreviation{JRE}{JRE}{Java Runtime Environment}
+\newabbreviation{CLDR}{CLDR}{Unicode Consortium's Common Locale Data Repository}
+
 \begin{document}
 \DocInput{texosquery.dtx}
 \end{document}
@@ -64,73 +123,708 @@
 %\author{Nicola L. C. Talbot\\
 %\href{http://www.dickimaw-books.com/}{\nolinkurl{dickimaw-books.com}}
 %\and Paulo Cereda}
-%\date{2016-07-14 (v1.1)}
+%\date{2017-03-23 (v1.2)}
 %\maketitle
 %
 %\begin{abstract}
-%\texttt{texosquery.jar} is a cross-platform Java application
-%to query certain OS information designed for use in \TeX's
-%shell escape mechanism.
-%The accompanying \TeX\ code provides a simple interface to the
-%\texttt{texosquery} Java application, which may be skipped
-%if you want to explicitly use \cs{input} (but take
-%care of any special characters appearing in the result).
+%The \sty{texosquery} bundle provides the \app{texosquery.jar} application (and
+%variations \app{texosquery-jre8.jar} and \app{texosquery-jre5.jar})
+%This is a cross-platform Java application to query certain
+%\gls{OS} and locale information. The application is
+%specifically designed for use within \TeX's shell escape mechanism, 
+%through the \cs{TeXOSQuery} command provided by the \sty{texosquery} package
+%(\file{texosquery.tex} and \file{texosquery.sty}).
+%
+%The \cs{TeXOSQuery} command performs more than a simple piped input as it 
+%first changes category codes of various problematic characters and locally 
+%defines some short control sequences that are used in the application's result.
+%These commands aren't defined outside of \cs{TeXOSQuery}, so a
+%direct piped input may cause undefined control sequences. If you
+%really want to use this direct method rather than using
+%\cs{TeXOSQuery}, then you will need to run \app{texosquery} in
+%backward compatibility mode~0 or~1 (using \texttt{\longarg{compatible} 1}).
+%The first two versions of \app{texosquery} didn't use those short
+%commands.
 %\end{abstract}
 %
 %\begin{important}
 %You will need \TeX's shell escape enabled,
-%and you will also need the Java Runtime Environment (JRE) 
-%installed to use \texttt{texosquery}.
+%and you will also need the \gls{JRE} installed.
 %\end{important}
 %
-%If you want to rebuild the application, instructions for
-%compiling the source code (including the code for this document)
-%are in the accompanying \texttt{README.md} file.
+%There are three variations of the \app{texosquery} application provided:
+%\begin{itemize}
+%\item \file{texosquery.jar}: requires at least Java~7, has medium locale
+%support, obeys \texttt{openin\_any} but has additional
+%restrictions imposed for security reasons (no listings outside the
+%current working directory path);
+%\item \file{texosquery-jre8.jar}: requires at least Java~8, has best locale
+%support, obeys \texttt{openin\_any} but has additional
+%restrictions imposed for security reasons (no listings outside the
+%current working directory path);
+%\item \file{texosquery-jre5.jar}: requires at least Java~5, has poor locale
+%support (language scripts not recognised), doesn't have the walk
+%action, obeys \texttt{openin\_any} but doesn't have the extra restrictions of the
+%Java 7 and 8 versions for the listing functions. Note that Java~5 and~6
+%are deprecated. Old deprecated versions are considered a security
+%risk.
+%\end{itemize}
+%The default is \file{texosquery.jar}. Throughout this document
+%\app{texosquery} is used to reference the application, regardless
+%which of these three jar files you've chosen to use. See
+%section~\ref{sec:setup} for further details.
 %
+%The aim of the original version of \app{texosquery} was to provide
+%a way of accessing the operating system's locale information.
+%Version 1.3 of the \sty{tracklang} package provides
+%\cs{TrackLangQueryEnv} which uses \app{kpsewhich} to query the
+%appropriate locale environment variable (such as \verb|$LANG|
+%or \verb|LC_ALL|). Unfortunately this doesn't work under Windows as
+%the locale information there is stored in the registry. The Lua
+%\texttt{os.setlocale(nil)} function can simply return \texttt{C} or
+%\texttt{POSIX}, which isn't helpful from \sty{tracklang}'s point of
+%view. Although Java has its drawbacks, it's one of the most
+%ubiquitous platform-independent methods to obtain this information.
+%Since it seemed overkill to write a Java application that simply
+%returned the locale, I decided to add a few extra functions that
+%might be of use, but accessing locale information was, and still
+%is, the primary purpose of this application.
+%
+%Although the \gls{POSIX} environment variables, such as
+%\verb|$LC_ALL|, are easy to read with \app{kpsewhich}, these days 
+%the \gls{IETF} \gls{BCP}~47 language tag is the more appropriate way 
+%of identifying a locale, so version 1.2 has added the \longarg{bcp47} 
+%function to support this.  The \sty{tracklang} package has similarly added
+%\cs{TrackLanguageTag}\marg{IETF tag}.
+%
+%The \sty{locale} package occasionally referenced in this document
+%is still under development at the time of writing. The
+%\longarg{numeric}, \longarg{locale-data}, \longarg{date-time} and 
+%\longarg{time-zones} options are designed to
+%interface with the \sty{locale} package, so although
+%\sty{texosquery} and \sty{locale} will be distributed separately, 
+%version 1.2 of \app{texosquery} is being
+%developed alongside version 1.0 of the \sty{locale} package.
+%The aim of the \sty{locale} package is to use both \sty{tracklang}
+%and \sty{texosquery} to automatically set up the document language.
+%For example, in the following \LaTeX\ document
+%\begin{verbatim}
+%\documentclass{article}
+%\usepackage{locale}
+%\begin{document}
+%Language: \CurrentLocaleLanguageNativeName.
+%Region: \CurrentLocaleRegionNativeName.
+%Today: \CurrentLocaleDate. (Compare with \today.)
+%Time: \CurrentLocaleTime.
+%Currency Symbol: \CurrentLocaleCurrency
+%Integer:
+%\texosqueryfmtnumber{\CurrentLocaleIntegerPattern}{123456}{0}{0}
+%Decimal:
+%\texosqueryfmtnumber{\CurrentLocaleDecimalPattern}{123456}{78}{0}
+%Percentage:
+%\texosqueryfmtnumber{\CurrentLocalePercentPattern}{0}{65}{0}
+%Currency:
+%\texosqueryfmtnumber{\CurrentLocaleCurrencyPattern}{1234567}{0}{0}
+%\end{document}
+%\end{verbatim}
+%the \sty{locale} package will automatically:
+%\begin{itemize}
+%\item load the \sty{textcomp} package for currency symbols (package
+%option \texttt{symbols=fontawesome} will use \sty{fontawesome}
+%instead);
+%\item if \XeLaTeX\ or \LuaLaTeX:
+% \begin{itemize}
+%  \item load \sty{fontspec} (unless option \texttt{fontspec=false}
+%  is used);
+%  \item load \sty{polyglossia} and use \cs{setmainlanguage}
+%  with options that can be determined from the language tag
+%  (use package option \texttt{support=babel} to use \sty{babel}
+%  regardless of the \LaTeX\ format);
+% \end{itemize}
+% otherwise:
+% \begin{itemize}
+%  \item load \sty{inputenc} (default file encoding obtained from
+%  \app{texosquery}'s \longarg{codeset-lcs} action);
+%  \item load \sty{fontenc} (font encoding obtained using
+%  \sty{tracklang} to query the language script);
+%  \item load \sty{babel} with the appropriate language label (use
+%  \texttt{support=none} to prevent this);
+% \end{itemize}
+%\item load \sty{datetime2} with the \texttt{useregional=text}
+%option (use \texttt{datetime2=false} to prevent this).
+%\end{itemize}
+%
+%The generic \texttt{locale.tex} code doesn't load the above packages, but can
+%still obtain information about the locale:
+%\begin{verbatim}
+%\input locale
+
+%Language: \CurrentLocaleLanguageNativeName.
+%Region: \CurrentLocaleRegionNativeName.
+%Today: \CurrentLocaleDate. (Compare with \today.)
+%Time: \CurrentLocaleTime.
+%Currency Symbol: \CurrentLocaleCurrency
+%Integer:
+%\texosqueryfmtnumber{\CurrentLocaleIntegerPattern}{123456}{0}{0}
+%Decimal:
+%\texosqueryfmtnumber{\CurrentLocaleDecimalPattern}{123456}{78}{0}
+%Percentage:
+%\texosqueryfmtnumber{\CurrentLocalePercentPattern}{0}{65}{0}
+%Currency:
+%\texosqueryfmtnumber{\CurrentLocaleCurrencyPattern}{1234567}{0}{0}
+%\bye
+%\end{verbatim}
+%
+%So that's the reasoning behind the new v1.2 actions. Hopefully the
+%new \sty{locale} package will be uploaded to \gls{CTAN} shortly after the
+%new version of \sty{texosquery}.
+%
+%\clearpage
 %\tableofcontents
+%\clearpage
 %
 %\section{texosquery.jar: the Java application}
-%The \texttt{texosquery} Java command line application looks up
+%The \app{texosquery} Java command line application looks up
 %certain system information that may be of use in \TeX\ 
-%documents. All this information can easily be obtained using 
+%documents. This information can be obtained using 
 %native commands, but the Java application allows an 
-%OS-independent approach with results that can easily be
+%\gls{OS}-independent approach with results that can easily be
 %captured by \TeX's shell-escape without having to strip 
-%formatting information.
+%formatting information. It also uses control sequence markup to indicate 
+%whether characters should be interpreted literally (such as in file names) or 
+%if they should obey their current category code (such as
+%punctuation occurring in textual information) or if they should be
+%interpreted in some other way (such as pattern markup). This markup
+%is expanded by \cs{TeXOSQuery} when it performs the piped shell
+%escape.
 %
 %\begin{important}
-%\texttt{texosquery} provides read-only actions, and I don't 
+%\app{texosquery} provides read-only actions, and I don't 
 %intend adding any actions that modify system settings or files.
 %\end{important}
 %
-%Since the application is designed to work with \TeX, each
-%function will display the result on a single line without
-%formatting. (For multiple results, each line is grouped 
-%from v1.1.) A blank line (or empty group) will be displayed
-%if the information isn't available. A forward slash is always 
-%used as a directory divider, regardless of the operating 
-%system, so the result can be used, for example, in \cs{input} or
-%\cs{includegraphics}.
+%Since the application is designed to work with \TeX\ (through
+%\cs{TeXOSQuery} defined in \file{texosquery.tex}) each action (indicated 
+%by a command line switch) will display the result on a single line. 
+%For multiple results, each line is grouped. A blank line (or empty group) 
+%will be displayed if the information isn't available or is prohibited. 
+%A forward slash (\cs{fslh}) is always used as a directory divider, 
+%regardless of the operating system, so the result can be used, for example, 
+%in \cs{input} or \cs{includegraphics}.
 %
+%For example, I have a 64-bit Linux operating system installed on my
+%computer, so I could use \app{uname} in a bash terminal:
+%\begin{verbatim}
+%uname -o -r
+%\end{verbatim}
+%which (for me) produces:
+%\begin{verbatim}
+%4.1.13-100.fc21.x86_64 GNU/Linux
+%\end{verbatim}
+%I could also run \app{texosquery} directly from the bash terminal:
+%\begin{verbatim}
+%texosquery -o -r
+%\end{verbatim}
+%which produces the rather more cryptic:
+%\begin{verbatim}
+%{Linux}
+%{4\fdot 1\fdot 13\fhyn 100\fdot fc21\fdot x86\fusc 64}
+%\end{verbatim}
+%However \app{texosquery} isn't intended for this direct use. It's
+%intended for use with \cs{TeXOSQuery} provided by
+%\file{texosquery.tex}. Here's a plain \TeX\ document:
+%\begin{verbatim}
+%\input texosquery
+%\TeXOSQuery{\result}{-o -r}
+%\def\parseresult#1#2{OS Name: {\tt #1}. OS Version: {\tt #2}.}
+%\ifx\result\empty
+% Query failed!
+%\else
+% \expandafter\parseresult\result
+%\fi
+%\bye
+%\end{verbatim}
+%The markup commands, such as \cs{fusc}, are now converted to
+%literal characters with category code 12 (\qt{other}), so the
+%underscore isn't a problem. This document is now also platform independent 
+%(as long as \app{texosquery} and a recent version of the \gls{JRE} are
+%installed).  Unlike \app{uname}, \app{texosquery} also obeys the order of the
+%command line switches, which makes it easier to define the helper
+%command (\cs{parseresult} in the above) that processes the result.
+%
+%\subsection{Installation and Setup}
+%\label{sec:setup}
+%
+%Installation is best done through your \TeX\ package manager.
+%However if for some reason you need to install this package
+%manually the instructions are below. If you install through your
+%package manager, Windows users will probably find that the
+%\file{.jar} files have been converted to \file{.exe} (with the
+%\file{.bat} files omitted) and Unix-like users may find that the 
+%bash scripts are missing the \file{.sh} extension (these are actually 
+%symbolic links to the distributed \file{.sh} files). See
+%section~\ref{sec:setuptest} to test that the package has been
+%successfully installed.
+%
+%Even if you use your \TeX\ distribution's package manager to
+%install this package, you may still need to edit the
+%\file{texosquery.cfg} file (see step~\ref{itm:cfg} below). If you don't have write permission for
+%this file you can copy it to \meta{TEXMFHOME}\file{/tex/generic/texosquery/}
+%(that directory path may need to be created if it doesn't already
+%exist). You can find the correct value of \meta{TEXMFHOME} using
+%\begin{verbatim}
+%kpsewhich -var-value=TEXMFHOME
+%\end{verbatim}
+%You can find where the package manager has put \file{texosquery.cfg} using
+%\begin{verbatim}
+%kpsewhich texosquery.cfg
+%\end{verbatim}
+%
+%This bundle contains the following files:
+%\begin{itemize}
+%\item \file{texosquery.dtx}
+%
+%The DTX file contains the source code for this
+%document, and also the files:
+%\begin{itemize}
+%\item\file{texosquery.tex} (generic \TeX\ code)
+%\item\file{texosquery.sty} (\LaTeX\ package wrapper)
+%\item\file{texosquery.cfg} (configuration file)
+%\end{itemize}
+%The bash scripts (which will need the extensions removed):
+%\begin{itemize}
+%\item\file{texosquery-jre8.sh}
+%\item\file{texosquery.sh} 
+%\item\file{texosquery-jre5.sh}
+%\end{itemize}
+%Windows batch files (which will need the extensions changed to
+%\file{.bat})
+%\begin{itemize}
+%\item\file{texosquery-jre8.batch} 
+%\item\file{texosquery.batch} 
+%\item\file{texosquery-jre5.batch}
+%\end{itemize}
+%
+%\item \file{texosquery.ins} The driver file used to extract all the
+%above files contained in \file{texosquery.dtx}.
+%
+%\item The three different versions of the \app{texosquery}
+%application: \file{texosquery-jre8.jar}, \file{texosquery.jar} and
+%\file{texosquery-jre5.jar}. The source code for these is contained in
+%the \file{java} sub-directory.
+%
+%\item \file{texosquery.pdf} This PDF document.
+%\item \file{README.md} The README file in markdown format.
+%\item \file{CHANGES} Lists major changes for each version.
+%\end{itemize}
+%
+%To install manually (\meta{TEXMF} indicates the TEXMF directory):
+%\begin{enumerate}
+%\item Run
+%\begin{verbatim}
+%tex texosquery.ins
+%\end{verbatim}
+%to extract the \file{.tex}, \file{.sty}, \file{.cfg}, \file{.sh}
+%and \file{.batch} files.
+%
+%\begin{description}
+%\item[Windows] Change the extension of the \file{.batch} files to
+%\file{.bat} (\TeX\ on Windows prohibits the creation of \file{.bat}
+%files). Move the \file{.bat} files to somewhere on
+%your system's path. (You may omit the \file{.bat} files you don't
+%need.) The \file{.sh} files may be deleted.
+%
+%\item[Unix-like] Make the \file{.sh} files executable:
+%\begin{verbatim}
+%chmod u+x texosquery*.sh
+%\end{verbatim}
+%Move the \file{.sh} files to somewhere on your path \emph{without} the
+%\file{.sh} extension. (If the \file{.sh} extension is retained, you
+%will have to edit the \file{texosquery.cfg} file to include it.)
+%For example (if \verb|~/bin| is included in \verb|$PATH|):
+%\begin{verbatim}
+%mv texosquery-jre8.sh ~/bin/texosquery-jre8
+%\end{verbatim}
+%(You may omit the \file{.sh} files you don't need.)
+%The \file{.batch} files may be deleted.
+%\end{description}
+%
+%\item Move \file{texosquery.tex} to
+%\meta{TEXMF}\file{/tex/generic/texosquery/}
+%
+%\item\label{itm:cfg} Edit \file{texosquery.cfg} so that \cs{TeXOSInvokerName} is
+%defined to the application of your choice. For example, if you have 
+%Java 8 installed:
+%\begin{verbatim}
+%\def\TeXOSInvokerName{texosquery-jre8}
+%\end{verbatim}
+%Or if you only have Java 5 or 6 installed:
+%\begin{verbatim}
+%\def\TeXOSInvokerName{texosquery-jre5}
+%\end{verbatim}
+%You can find out your Java version by running the following in your
+%command prompt or terminal:
+%\begin{verbatim}
+%java -version
+%\end{verbatim}
+%If the version number starts with \texttt{1.8} then you have Java 8
+%installed, if it starts with \texttt{1.7} then you have Java 7,
+%etc.
+%
+%\item Move \file{texosquery.cfg} to
+%\meta{TEXMF}\file{/tex/generic/texosquery/}
+%\item Move \file{texosquery.sty} to
+%\meta{TEXMF}\file{/tex/latex/texosquery/}
+%\item Move the \file{.jar} files to
+%\meta{TEXMF}\file{/scripts/texosquery/}
+%\end{enumerate}
+%
+%\subsection{Installation Test}
+%\label{sec:setuptest}
+%
+%To test the installation:
+%\begin{enumerate}
+%\item In the
+%\href{http://www.dickimaw-books.com/latex/novices/html/terminal.html}{command
+%prompt or terminal} do:
+%\begin{verbatim}
+%texosquery -b
+%\end{verbatim}
+%(Replace \texttt{texosquery} with the command that matches the value
+%of \cs{TeXOSInvokerName} in the \hyperref[itm:cfg]{\file{texosquery.cfg} file}
+%described in section~\ref{sec:setup}.)
+%The above command should display the system's 
+%default locale. For me, this simply displays the line:
+%\begin{verbatim}
+%en-GB
+%\end{verbatim}
+%If you get an \texttt{Unknown option
+%\textquotesingle-b\textquotesingle} error, then your \gls{OS} is
+%picking up an old version of \app{texosquery}. Check the version
+%number with the \shortarg{v} switch.
+%\begin{verbatim}
+%texosquery -v
+%\end{verbatim}
+%If you get a \qt{command not found} or \qt{bad command or file name} error, 
+%then recheck the installation steps in section~\ref{sec:setup} and
+%make sure that the executable file has been placed on your system's
+%path.
+%
+%If this test is successful, try the next step.
+%\item Create the following plain \TeX\ document called \file{test.tex}:
+%\begin{verbatim}
+%\input texosquery
+%\TeXOSQuery{\result}{-b}\result
+%\bye
+%\end{verbatim}
+%and compile using:
+%\begin{verbatim}
+%pdftex --shell-escape test
+%\end{verbatim}
+%
+%Alternatively, create the follow \LaTeX\ document called
+%\file{test.tex}:
+%\begin{verbatim}
+%\documentclass{article}
+%\usepackage{texosquery}
+%\begin{document}
+%\TeXOSQuery{\result}{-b}\result
+%\end{document}
+%\end{verbatim}
+%and compile using:
+%\begin{verbatim}
+%pdflatex --shell-escape test
+%\end{verbatim}
+%
+%In both cases, the resulting PDF file \file{test.pdf} should show the default
+%locale. If not check the transcript \file{test.log} which should
+%include something like \verb"(|texosquery -b)" or  \verb"(|texosquery-jre8 -b)"
+%etc. If it simply has the line:
+%\begin{verbatim}
+%TeXOSQuery: texosquery -b
+%\end{verbatim}
+%(or similar) then the dry run mode was on, which means the shell escape wasn't
+%used. Check that the \longarg{shell-escape} switch was used when
+%calling \app{pdftex} or \app{pdflatex}.
+%
+%If you are using \app{texosquery} or \app{texosquery-jre8} and your
+%chosen application has been added to the restricted list, make sure 
+%that the line
+%\begin{verbatim}
+%\TeXOSQueryAllowRestricted
+%\end{verbatim}
+%hasn't been commented out in the \file{texosquery.cfg} file and try
+%the above example documents in restricted mode. (Note that
+%\app{texosquery-jre5} should not be added to the restricted list as
+%Java 5 and 6 are now deprecated and considered security risks, so
+%the above command should be commented out in the
+%\file{texosquery.cfg} file if \cs{TeXOSInvokerName} has been set to
+%\app{texosquery-jre5}.)
+%\end{enumerate}
+%
+%\subsection{Accessing file information}
+%\label{sec:fileaccess}
 %If an input file name is required (for example, with the
 %\longargfmt{pdfdate} argument described below) then the file may be in
 %the current working directory, relative to the current directory
 %(with forward slash \texttt{/} as the directory divider), an absolute path 
 %(again with forward slash) or on \TeX's path (in
-%which case, \texttt{kpsewhich} is used to locate it).
+%which case, \app{kpsewhich} is used to locate it). As from version
+%1.2, \app{texosquery} honours the \texttt{openin\_any} attribute set in the
+%\file{texmf.cnf} configuration file. This value is fetched using
+%\begin{verbatim}
+%kpsewhich -var-value=openin_any
+%\end{verbatim}
+%(You can find the configuration files using \texttt{kpsewhich -a
+%texmf.cnf}) For example, suppose the file \file{/tmp/.test}
+%exists. If the \texttt{openin\_any} attribute is set to \qt{\texttt{a}} 
+%(any file), then (assuming the operating system allows read-access
+%to that file) the \app{texosquery} file-reading operations will
+%be permitted. For example
+%\begin{verbatim}
+%texosquery --pdfdate /tmp/.test
+%\end{verbatim}
+%will return the file modification date in PDF date-time format. However, if
+%\texttt{openin\_any} is set to \qt{\texttt{r}} (restricted), the read
+%access will be denied because the file is considered hidden so an
+%empty result is returned. Similarly, if \texttt{openin\_any} is set
+%to \qt{\texttt{p}} (paranoid), the read access will be denied again
+%because the file is hidden but also because the file has an
+%absolute path that isn't under \texttt{\$TEXMFOUTPUT} (assuming
+%that environment variable hasn't been set to \file{/tmp}).
 %
-%Command line invocation:
-%\begin{flushleft}\ttfamily
-%texosquery \meta{action} ...
-%\end{flushleft}
-%Available actions (at least one required):
+%\subsection{Return Values}
+%\label{sec:returnvalues}
+%The return values may include literal text where special characters
+%need to have their category code changed to 12 (for example, file names)
+%but the return values may also include \TeX\ code that needs to be
+%processed by \TeX, either during the shell escape or deferred for
+%later (such as date-time or numeric patterns). This means that the
+%result from the shell escape can't be automatically detokenized.
+%
+%Therefore, as from version 1.2, the return values include short
+%control sequences that are locally defined by \cs{TeXOSQuery} and
+%so are only valid within that command's scope. For example,
+%\cs{fcln} expands to a colon (\texttt{:}) with category code 12
+%whereas \cs{tcln} expands to a colon according to its current
+%meaning. Note that this has changed from earlier versions which
+%simply returned the actual characters, which may or may not have
+%had the category code set to 12 at the start of \cs{TeXOSQuery}. To
+%reproduce the original behaviour, use the compatibility mode
+%(\longarg{compatible}) with the level set to 0 or 1.
+%For the full list of shortcut commands, see the
+%definition of \hyperlink{enableshortcs}{\cs{@texosquery at enableshortcs}}.
+%
+%The output produced by the \app{texosquery} application 
+%will be returned using the system's default input
+%encoding.  (For example, \gls{UTF}-8.) You will need to ensure that your \TeX\
+%document uses the same encoding if you want to typeset any of the
+%results that may contain non-ASCII characters. You can determine
+%the default encoding with \texttt{texosquery \shortarg{C}}, which is
+%formatted to match the options used by the \sty{inputenc} package.
+%(For example, \texttt{uft8} for \gls*{UTF}-8.)
+%
+%To test the file encoding rerun the plain \TeX\ or \LaTeX\ test
+%file in section~\ref{sec:setuptest} with
+%\shortarg{N} instead of \shortarg{b}. Most currency symbols are
+%outside the ASCII set, so this should return a non-ASCII character.
+%If you happen to have \$ as your currency,
+%then try \texttt{en-GB} or \texttt{en-IE} which have \pounds\ and
+%\texteuro, respectively. \LaTeX\ users may need to load
+%\sty{inputenc} and \sty{fontenc}. \XeLaTeX\ and \LuaLaTeX\ users may need to load
+%\sty{fontspec}.
+%
+%You can change the default encoding by invoking the Java Virtual
+%Machine with the option \texttt{-Dfile.encoding=}\meta{codeset}.
+%For example, bash users can modify the \file{texosquery} (or
+%\file{texosquery.sh}) script to set the encoding to \gls*{UTF}-8 as follows:
+%\begin{verbatim}
+%#!/bin/sh
+%
+%jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery.jar`
+%java -Dfile.encoding=UTF-8 -jar "$jarpath" "$@"
+%\end{verbatim}
+%Similarly for the corresponding \file{.bat} file for Windows users.
+%
+%If the script file can't be modified or you have only \file{.exe}
+%instead of \file{.jar} files then you can set the
+%\href{https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html#tooloptions}{\texttt{JAVA\_TOOL\_OPTIONS} environment variable}.
+%For example:
+%\begin{verbatim}
+%declare -x JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8
+%\end{verbatim}
+%Note that, unlike the edit to the bash or \file{.bat} file, this will 
+%affect all your Java applications.
+%
+%\subsection{Locales}
+%\label{sec:locales}
+%The options that have a locale identifier as an argument need the
+%identifier formatted as a \emph{regular}
+%\href{https://tools.ietf.org/html/bcp47}{IETF BCP 47 language tag} that uses
+%hyphens as separators. \gls{POSIX} style locales (with underscores
+%replaced by hyphens, for example \texttt{fr-BE.utf8 at euro}) 
+%are only used as a return value in the \longarg{locale} and 
+%\longarg{locale-lcs} options.
+%
+%\href{http://www.oracle.com/technetwork/java/javase/java8locales-2095355.html}{\textbf{Not
+%all locales are supported by Java.}}
+%For example, Irish is supported but Scottish and Welsh aren't supported by 
+%the \gls{JRE}. The \gls{CLDR} can be accessed with Java~8, but
+%\href{http://openjdk.java.net/jeps/252}{the CLDR isn't
+%enabled by default}. It can be turned on using the system property
+%\texttt{java.locale.providers}, which may provide additional
+%support. For example, although Welsh isn't supported by the JRE,
+%it is supported with the \gls{CLDR}, so both Java~8 and the CLDR 
+%locale provider are required for that language. The proposed
+%Java~9 should have the CLDR enabled by default.
+%
+%The bash script \file{texosquery-jre8} (or \file{texosquery-jre8.sh}) 
+%automatically sets \texttt{java.locale.providers} to \texttt{CLDR,JRE}.
+%Alternatively, the \texttt{JAVA\_TOOL\_OPTIONS} environment variable 
+%can be set to
+%\begin{verbatim}
+%-Djava.locale.providers=CLDR,JRE
+%\end{verbatim}
+%which will enable it for all installed Java applications.
+%If you need to set multiple options, these can be combined
+%in the value of \texttt{JAVA\_TOOL\_OPTIONS}.
+%For example
+%\begin{verbatim}
+%-Djava.locale.providers=CLDR,JRE -Dfile.encoding=UTF-8
+%\end{verbatim}
+%
+%You may find that the results are different depending on the data
+%provider. For example with \texttt{java.locale.providers} set to 
+%\texttt{JRE,CLDR} then 
+%\begin{verbatim}
+%texosquery -D en-GB
+%\end{verbatim}
+%displays the long date in the form \qt{06 November 2016} and the
+%medium date in the form \qt{06-Nov-2016}, but with the ordering
+%reversed to \texttt{CLDR,JRE} (so that the \gls{CLDR} is queried first)
+%then the long date is now in the form \qt{6 November 2016} and the 
+%medium date is in the form \qt{6 Nov 2016}.
+%
+%Note that \app{texosquery} can only access locale information
+%provided by Java. For example, Java currently doesn't
+%provide any methods to access telephone codes.
+%
+%\subsection{Command line invocation}
+%The syntax for the command line invocation of \app{texosquery}
+%is:
+%\begin{definition}
+%texosquery \oarg{options} \meta{action} ...
+%\end{definition}
+%The syntax for \app{texosquery-jre8} is exactly the same except
+%for the application name:
+%\begin{definition}
+%texosquery-jre8 \oarg{options} \meta{action} ...
+%\end{definition}
+%Similarly for \app{texosquery-jre5}. (Bash users may need the
+%\file{.sh} extension if it wasn't removed from the script name
+%during the \hyperref[sec:setup]{installation setup}.) Available actions are
+%described below. At least one action is required.
+%
+%Available options (must come before actions):
 %\begin{description}
-%\item[\shortarg{L} or \longarg{locale}] Display the locale
-%information in the form
-%\begin{flushleft}\ttfamily
+%\item[\shortarg{h} or \longarg{help} or \shortarg{help}] Displays help message and
+%exits.
+%\item[\shortarg{v} or \longarg{version} or \shortarg{version}] Displays version
+%information and exits.
+%\item[\longarg{nodebug}] No debugging information. Only command
+%line syntax errors are written to STDERR. (Default.)
+%\item[\longarg{debug} \oarg{n} or \shortarg{debug} \oarg{n}] Set the debugging level, where
+%\meta{n} is a non-negative integer.
+%If \meta{n} is omitted, 3 is assumed. If \meta{n} is 0, then
+%debugging information is suppressed (equivalent to
+%\longarg{nodebug}). If \meta{n} $\geq 1$, error messages are
+%written to STDERR. If \meta{n} $\geq 2$, any exceptions encountered
+%will additionally write the stack trace to STDERR. If \meta{n}
+%$\geq 3$ non-error informational messages are included.
+%\item[\longarg{compatible} \meta{n} or \shortarg{compat} \meta{n}]
+%Set the compatibility mode.
+%The argument should be either a non-negative integer (0 for version
+%1.0, 1 for version 1.1, etc) or the keyword \texttt{latest} to
+%indicate the latest version (default). Note that the compatibility
+%mode only affects the available actions and the display style of the
+%result, and does not change security features. For example, the check for the 
+%\texttt{openin\_any} setting was only introduced to version 1.2, but this 
+%is still checked even if the compatibility mode is set to 0 or 1.
+%\end{description}
+%
+%If multiple actions are given, they will be processed in the
+%order specified in the command line invocation. Each result will
+%be displayed on a separate line. As from v1.1, if there are
+%multiple actions, each result will be grouped. This makes it easier
+%to process the results in \TeX. For example:
+%\begin{verbatim}
+%texosquery -l
+%\end{verbatim}
+%This just produces (for me):
+%\begin{verbatim}
+%en\fhyn GB\fdot utf8
+%\end{verbatim}
+%(which expands to \texttt{en-GB.utf8} when used with \cs{TeXOSQuery}) whereas
+%\begin{verbatim}
+%texosquery -l -o
+%\end{verbatim}
+%produces:
+%\begin{verbatim}
+%{en\fhyn GB\fdot utf8}
+%{Linux}
+%\end{verbatim}
+%To reproduce the v1.0 display use \longarg{compatible}\texttt{ 0}.
+%(This will also explicitly use the punctuation characters rather
+%than replacing them with the control sequence markup, such as
+%\cs{fhyn} or \cs{fdot}.)
+%
+%Note that unavailable information will produce an empty group.
+%For example (assuming \file{nofile} doesn't exist or doesn't have
+%read access):
+%\begin{verbatim}
+%texosquery -l -d nofile
+%\end{verbatim}
+%produces:
+%\begin{verbatim}
+%{en\fhyn GB\fdot utf8}
+%{}
+%\end{verbatim}
+%whereas 
+%\begin{verbatim}
+%texosquery -d nofile
+%\end{verbatim}
+%just displays an empty line.
+%
+%If you're puzzled as to why an empty line has been returned, try
+%rerunning the command with \longarg{debug} for further information.
+%Available actions are listed below.
+%
+%\subsubsection{Action \shortarg{b} or \longarg{bcp47}}
+%(New to version 1.2.) This action displays the \gls{BCP}~47 language tag.
+%For example, my locale is \texttt{en-GB} (English in the United
+%Kingdom), so
+%\begin{verbatim}
+%texosquery -b
+%\end{verbatim}
+%Simply returns:
+%\begin{verbatim}
+%en\fhyn GB
+%\end{verbatim}
+%(which expands to \texttt{en-GB} with \cs{TeXOSQuery})
+%whereas a user whose default locale is set to Swiss German with the
+%new orthography would get:
+%\begin{verbatim}
+%de\fhyn CH\fhyn 1996
+%\end{verbatim}
+%(which expands to \texttt{de-CH-1996} with \cs{TeXOSQuery}).
+%
+%\subsubsection{Action \shortarg{L} or \longarg{locale}}
+%
+%This action displays the locale information in the \gls{POSIX} form
+%\begin{definition}
 %\meta{lang}-\meta{region}.\meta{codeset}@\meta{modifier}
-%\end{flushleft}
-%where \meta{lang} is the ISO code for the language (e.g.\ 
+%\end{definition}
+%where \meta{lang} is the \gls{ISO} code for the language (e.g.\ 
 %\texttt{en}),
 %\meta{region} is the ISO code for the region (e.g.\ \texttt{GB}),
 %\meta{codeset} is the default code set (e.g.\ \texttt{UTF-8})
@@ -137,131 +831,896 @@
 % and \meta{modifier} is the modifier. Elements may be omitted
 % if unavailable. For example, \texttt{en-GB.UTF-8} has the
 % \meta{modifier} omitted, and \texttt{en} has all but the language
-% omitted.
-%\item[\shortarg{l} or \longarg{locale-lcs}] As the above but the
-%codeset (if present) is converted to lower case and any hyphens are
-%stripped. For example, if \longargfmt{locale} returns
-%\texttt{en-GB.UTF-8}, then \longargfmt{locale-lcs} would return
-%\texttt{en-GB.utf8}.
-%\item[\shortarg{c} or \longarg{cwd}] Displays the current working
-%directory.
-%\item[\shortarg{m} or \longarg{userhome}] Displays the user's home
-%directory.
-%\item[\shortarg{t} or \longarg{tmpdir}] Displays the temporary
-%directory.
-%\item[\shortarg{o} or \longarg{osname}] Displays the operating
-%system name.
-%\item[\shortarg{r} or \longarg{osversion}] Displays the operating
-%system version.
-%\item[\shortarg{a} or \longarg{osarch}] Displays the operating
-%system architecture.
-%\item[\shortarg{n} or \longarg{pdfnow}] Displays the current
-% date and time in PDF format. For example 
+% omitted. As above, the punctuation characters will actually be
+% returned using the control sequences \cs{fhyn} (hyphen), \cs{fdot}
+% (dot) and \cs{fatc} (at).
+%
+%\subsubsection{Action \shortarg{l} or \longarg{locale-lcs}}
+%
+%This action is similar to \longarg{locale}, but the codeset is converted to 
+%lower case and any hyphens are stripped. For example, if \longargfmt{locale} 
+%returns \texttt{en-GB.UTF-8}, then \longargfmt{locale-lcs} would return
+%\texttt{en-GB.utf8}. As above, the punctuation characters will actually be
+% returned using the control sequences \cs{fhyn} (hyphen), \cs{fdot}
+% (dot) and \cs{fatc} (at).
+%
+%\subsubsection{Action \shortarg{C} or \longarg{codeset-lcs}}
+%
+%(New to version 1.2.)
+%This action returns just the codeset converted to lower case with hyphens 
+%stripped.  For example, my default file encoding is \gls{UTF}-8, so 
 %\begin{verbatim}
-%D:20160704131006+01'00'
+%texosquery -C
 %\end{verbatim}
-%Note that some, but not all, \TeX\ formats provide
+%returns
+%\begin{verbatim}
+%utf8
+%\end{verbatim}
+%This action is used by the \sty{locale} package to determine the
+%option to use when it needs to automatically load the
+%\sty{inputenc} package.
+%
+%\subsubsection{Action \shortarg{o} or \longarg{osname}}
+%
+%This action displays the operating system name. For example, for me this
+%produces:
+%\begin{verbatim}
+%Linux
+%\end{verbatim}
+%
+%\subsubsection{Action \shortarg{r} or \longarg{osversion}}
+%
+%This action displays the operating system version. For example, for me this
+%produces:
+%\begin{verbatim}
+%4\fdot 1\fdot 13\fhyn 100\fdot fc21\fdot x86\fusc 64
+%\end{verbatim}
+%(which expands to \texttt{4.1.13-100.fc21.x86\_64} when used with
+%\cs{TeXOSQuery}).
+%
+%\subsubsection{Action \shortarg{a} or \longarg{osarch}}
+%
+%This action displays the operating system architecture. For example, for me 
+%this produces:
+%\begin{verbatim}
+%amd64
+%\end{verbatim}
+%
+%\subsubsection{Action \shortarg{M} or \longarg{date-time}}
+%(New to version 1.2.)
+%This action displays all the current date time data in a format
+%suitable for use in \cs{texosqueryfmtdatetime}. (See
+%section~\ref{sec:applydatetimepatterns}.)
+%
+%\subsubsection{Action \shortarg{Z} \oarg{locale} or
+%\longarg{time-zones} \oarg{locale}}
+%(New to version 1.2.)
+%This action displays all of the time zone mappings
+%for the given locale (or the default if \meta{locale} is omitted) in the format
+%\begin{definition}
+%\{\marg{id$_1$}\marg{short name}\marg{long
+%name}\marg{dst short name}\marg{dst long name}\}\ldots
+%\{\marg{id$_{n}$}\marg{short name}\marg{long
+%name}\marg{dst short name}\marg{dst long name}\}
+%\end{definition}
+%The \meta{id} is the unique label used by Java to identify the time
+%zone (such as \texttt{Europe/London}) as used in the time zone
+%information returned by \shortarg{M} (\longarg{date-time}).
+%
+%\subsubsection{Action \shortarg{n} or \longarg{pdfnow}}
+%
+%This action displays the current date and time in PDF format. For example 
+%\begin{verbatim}
+%\pdfd \fcln 20160704131006\fpls 01\fapo 00\fapo
+%\end{verbatim}
+%This uses the shorthand tags \cs{pdfd}, \cs{fcln}, \cs{fpls} and
+%\cs{fapo} that 
+%are locally redefined by
+%\cs{TeXOSQuery} to produce a \texttt{D}, a colon (\texttt{:}), a
+%plus sign (\texttt{+}) and an apostrophe (\texttt{\textquotesingle}) 
+%with the category code set to 12 to make it consistent with 
+%\cs{pdfcreationdate}. This also allows
+%for situations where the punctuation characters have been made
+%active (for example, through \sty{babel}).
+%
+%Some, but not all, \TeX\ formats provide
 %\cs{pdfcreationdate}, which is more efficient than using the shell
 %escape, but this can be used
 %as a fallback method for those that don't (for example, \XeTeX).
-%\item[\shortarg{d} \meta{file} or \longarg{pdfdate} \meta{file}]
-% Displays the last modified time stamp of the given file in PDF format or a blank line
+%
+%Note that versions 1.0 and 1.1 didn't use \cs{pdfd} etc but simply used
+%the actual characters. For example:
+%\begin{verbatim}
+%D:20160704131006+01'00'
+%\end{verbatim}
+%If you want to reproduce this format, use \longarg{compatible}
+%with the level set to 0 or 1.
+%
+%\subsubsection{Action \shortarg{d} \meta{file} or \longarg{pdfdate}
+%\meta{file}}
+%
+%This action displays the last modified time stamp of the given file in PDF format or a blank line
 % if the file doesn't exist or the file permissions prohibit this
 % action.
 %Again some, but not all, \TeX\ formats provide
 %\cs{pdffilemoddate}\marg{file}, which is more efficient than using
 %the shell escape.
-%\item[\shortarg{s} \meta{file} or \longarg{filesize} \meta{file}]
-% Displays the size in bytes of the given file or a blank line
-% if the file doesn't exist or the file permissions prohibit this
-% action.
-%Some, but not all, \TeX\ formats provide
+%
+%As with \longarg{pdfnow} this now uses \cs{pdfd} etc which are converted
+%by \cs{TeXOSQuery} to characters with the category code set to 12.
+%
+%This action obeys the \texttt{openin\_any} setting, so if access to
+%\meta{file} is forbidden by this setting, the result will be empty.
+%
+%\subsubsection{Action \shortarg{s} \meta{file} or \longarg{filesize}
+%\meta{file}}
+%
+%This action displays the size in bytes of the given file or an
+%empty string if the file doesn't exist or the file permissions prohibit this
+%action. Some, but not all, \TeX\ formats provide
 %\cs{pdffilesize}\marg{file}, which is more efficient than using
 %the shell escape.
-%\item[\shortarg{i} \meta{sep} \meta{dir} or \longarg{list}
-%\meta{sep} \meta{dir}]
-%List all files in the given directory with the output on a single
+%
+%This action obeys the \texttt{openin\_any} setting, so if access to
+%\meta{file} is forbidden by this setting, the result will be empty.
+%
+%\subsubsection{Action \shortarg{c} or \longarg{cwd}}
+%
+%This action displays the current working directory. This obeys the
+%\texttt{openin\_any} setting, so this action will return an empty
+%string if this file information is forbidden by that setting.
+%
+%\subsubsection{Action \shortarg{m} or \longarg{userhome}}
+%
+%This action displays the user's home directory. This obeys the
+%\texttt{openin\_any} setting, so this action will return an empty
+%string if this file information is forbidden by that setting.
+%
+%\subsubsection{Action \shortarg{t} or \longarg{tmpdir}}
+%
+%This action displays the temporary directory. This obeys the
+%\texttt{openin\_any} setting, so this action will return an empty
+%string if this file information is forbidden by that setting.
+%
+%\subsubsection{Action \shortarg{i} \meta{sep} \meta{dir} \oarg{sort} or \longarg{list}
+%\meta{sep} \meta{dir} \oarg{sort}}
+%
+%This action lists all files in the given directory with the output on a single
 %line using \meta{sep} as the separator between entries. Note that
 %the list doesn't include the full path, just the file names.
-%\item[\shortarg{f} \meta{sep} \meta{regex} \meta{dir} or
-%\longarg{filterlist} \meta{sep} \meta{regex} \meta{dir}]
-%Like the above but only lists those files whose name matches the
-%regular expression given in \meta{regex}. Note that this tests for a
-%complete match on the file name (not including path). For example,
+%
+%\begin{important}
+%As from v1.2, new restrictions have been placed on the value of \meta{dir}
+%for security reasons. For all three applications,
+%\app{texosquery-jre8}, \app{texosquery} and \app{texosquery-jre5},
+%the \texttt{openin\_any} setting is checked. If read access to
+%\meta{dir} is forbidden by the \texttt{openin\_any} setting, then
+%this action returns an empty string. \emph{Additionally},
+%regardless of \texttt{openin\_any}, the more restrictive
+%applications, \app{texosquery-jre8} and \app{texosquery}, prohibit a
+%value of \meta{dir} that's outside the current working directory
+%path (e.g.\ \texttt{..}) or that has no parent directory (e.g.\ \texttt{/}). 
+%Both \app{texosquery-jre8} and \app{texosquery} check the
+%\emph{canonical path} of \meta{dir}, so if \meta{dir} is a symbolic
+%link, the target path is checked.
+%
+%This is a security feature to prevent
+%any malicious code that might try to recursively list the contents
+%of the entire filing system, which would hog resources, or that
+%might try to discover files outside the current working directory. An
+%exception is made for \app{texosquery-jre5} since that application
+%is already considered insecure (due to Java 5 and 6 being
+%deprecated), so if you really need \meta{dir} as, say \texttt{..} (the
+%parent directory) or \texttt{/} (the root directory), you can use 
+%\app{texosquery-jre5} (by redefining \cs{TeXOSInvokerName} before
+%using \cs{TeXOSQuery}) although this isn't recommended. It will
+%still obey the \texttt{openin\_any} setting, so the listing still
+%won't work with \app{texosquery-jre5} if the \texttt{openin\_any}
+%setting is set to \texttt{p} (paranoid).
+%\end{important}
+%
+%As from version 1.2, there is now an optional argument \meta{sort},
+%which indicates how the returned list should be sorted. If omitted
+%\texttt{default} is assumed. Available values of \meta{sort}:
+%\begin{description}
+%\item[\texttt{default}] Use the default order. This is typically in
+%alphabetical order, but depends on the operating system or
+%\gls{JRE}.
+%\item[\texttt{date-ascending}] Order by file modified date from
+%oldest to newest. This option has synonyms \texttt{date} and
+%\texttt{date-asc}.
+%\item[\texttt{date-descending}] Order by file modified date from
+%newest to oldest. You may use the shorter \texttt{date-des}
+%value instead.
+%\item[\texttt{size-ascending}] Order by file size from
+%smallest to largest. This option has synonyms \texttt{size} and
+%\texttt{size-asc}.
+%\item[\texttt{size-descending}] Order by file size from
+%largest to smallest. You may use the shorter \texttt{size-des}
+%value instead.
+%\item[\texttt{name-ascending}] Order by file name (case-sensitive) 
+%alphabetically. This option has synonyms \texttt{name} and
+%\texttt{name-asc}.
+%\item[\texttt{name-descending}] Order by file name (case-sensitive) 
+%in reverse alphabetic order. You may use the shorter
+%\texttt{name-des} value instead.
+%\item[\texttt{iname-ascending}] Order by file name (case-insensitive) 
+%alphabetically. This option has synonyms \texttt{iname} and
+%\texttt{iname-asc}.
+%\item[\texttt{iname-descending}] Order by file name (case-insensitive) 
+%in reverse alphabetic order. You may use the shorter
+%\texttt{iname-des} value instead.
+%\item[\texttt{ext-ascending}] Order by file extension (case-sensitive) 
+%alphabetically. If files have the same extension, they are ordered
+%by name. This option has synonyms \texttt{ext} and
+%\texttt{ext-asc}.
+%\item[\texttt{ext-descending}] Order by file extension (case-sensitive) 
+%in reverse alphabetic order.  If files have the same extension, they are 
+%ordered by name (reverse alphabetic order). You may use the shorter
+%\texttt{ext-des} value instead.
+%\end{description}
+%
+%This action obeys the \texttt{openin\_any} setting for all the
+%listed files as well as for the directory \meta{dir}, so if access to
+%a file in the directory is forbidden, the file will be omitted from
+%the list. (This action is equivalent to the following with
+%\meta{regex} set to \texttt{.*} to match all files.)
+%
+%If you want to excluded hidden dot files (where they aren't
+%automatically excluded by \texttt{openin\_any}), use the
+%\longarg{filterlist} action described below with \meta{regex} set
+%to \verb|[^\.].*|. (Remember that you'll need to use \cs{string}
+%when using the shell escape, as noted below.)
+%
+%\begin{important}
+%Unlike most of the return values the \meta{sep} part here isn't
+%escaped, so take care if \meta{sep} contains any commands. For
+%example, if you want to use \verb|\\| as the separator, you'll need
+%to use \verb|\string\noexpand\string\\| in the \meta{sep} part
+%within \cs{TeXOSQuery}.
+%\end{important}
+%
+%For example:
+%\begin{verbatim}
+%\TeXOSQueryFileList{\result}{\string\noexpand\string\\}{.}
+%\end{verbatim}
+%calls (through the shell escape):
+%\begin{verbatim}
+%texosquery -i '\noexpand\\' '.'
+%\end{verbatim}
+%(the two \cs{string} commands have detokenized their arguments)
+%so \app{texosquery} uses \verb|\noexpand\\| as the separator in the
+%returned list, but this list is expanded as it's read in. However
+%\cs{noexpand} prevents the \verb|\\| from being expanded, so the
+%separator becomes just \verb|\\| which may be (re)defined before the
+%resulting list is processed.
+%
+%Note that \cs{TeXOSQueryFileList} automatically adds the single
+%quotes around the arguments. If \cs{TeXOSQuery} is used explicitly,
+%these quotes would need to be added as appropriate.
+%
+%\subsubsection{Action \shortarg{id} \meta{sep} \meta{dir}
+%\oarg{sort} or \longarg{list-dir}
+%\meta{sep} \meta{dir} \oarg{sort}}
+%
+%This action is like \longarg{list} but only includes sub-directories
+%of \meta{dir}. The caveats and security notes for \longarg{list} also apply
+%here.
+%
+%\subsubsection{Action \shortarg{ir} \meta{sep} \meta{dir}
+%\oarg{sort} or \longarg{list-regular}
+%\meta{sep} \meta{dir} \oarg{sort}}
+%
+%This action is like \longarg{list} but only includes regular files. 
+%The caveats and security notes for \longarg{list} also apply here.
+%
+%\subsubsection{Action \shortarg{f} \meta{sep} \meta{regex} \meta{dir} 
+%\oarg{sort} or \longarg{filterlist} \meta{sep} \meta{regex} \meta{dir} 
+%\oarg{sort}}
+%
+%This action is like \longarg{list} but only lists those files whose name 
+%matches the
+%\href{http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html}{regular expression} given in \meta{regex}. Note that
+%since this uses Java's \texttt{String.matches} method this tests for a
+%\emph{complete} match on the file name (not including directory path). For example,
 %if \meta{regexp} is \texttt{foo.*}, it will only match files whose
 %name starts with \texttt{foo} (for example, \texttt{foobar} will
-%match but \texttt{barfoo} won't).
-%\item[\shortarg{u} \meta{file} or \longarg{uri} \meta{file}]
-%Displays the URI of the given file or a blank line if the file
-%doesn't exist or the file permissions prohibit this action.
-%Note that this may include in a percent character in the result. The \TeX\ 
-%command \cs{TeXOSQuery} protects against this by changing the
-%category code, but if you explicitly call \texttt{texosquery}
-%using the shell escape, you'll need to be careful of this.
-%\item[\shortarg{p} \meta{file} or \longarg{path} \meta{file}]
-%Displays the canonical path of the given file or a blank line if
-%the file doesn't exist or the file permissions prohibit this
-%action.
-%\item[\shortarg{e} \meta{file} or \longarg{dirname} \meta{file}]
+%match but \texttt{barfoo} won't). Use \texttt{.*foo.*} to match all
+%files that contain \texttt{foo} in the name (so \texttt{foobar} and
+%\texttt{barfoo} will both match).
+%
+%\begin{important}
+%You can't have an empty regular expression. You can use the regular
+%expression \texttt{.*} to match all files (which is what
+%\longarg{list} does).
+%\end{important}
+%
+%As from version 1.2, this action now has an optional argument
+%\meta{sort}, which indicates how to sort the returned list. The
+%available values for \meta{sort} are the same as for
+%\longarg{list}, described above.
+%
+%The caveats and security notes for \longarg{list} also apply here.
+%
+%\subsubsection{Action \shortarg{fd} \meta{sep} \meta{regex} \meta{dir} 
+%\oarg{sort} or \longarg{filterlist-dir} \meta{sep} \meta{regex} \meta{dir} 
+%\oarg{sort}}
+%
+%This action is like \longarg{filterlist} but only includes
+%sub-directories of \meta{dir}. 
+%
+%The caveats and security notes for \longarg{list} also apply here.
+%
+%\subsubsection{Action \shortarg{fr} \meta{sep} \meta{regex} \meta{dir} 
+%\oarg{sort} or \longarg{filterlist-regular} \meta{sep} \meta{regex} \meta{dir} 
+%\oarg{sort}}
+%
+%This action is like \longarg{filterlist} but only includes
+%regular files. 
+%
+%The caveats and security notes for \longarg{list} also apply here.
+%
+%\subsubsection{Action \shortarg{w} \meta{sep} \meta{regex} \meta{dir}
+%\oarg{sort} or \longarg{walk}
+%\meta{sep} \meta{regex} \meta{dir} \oarg{sort}}
+%
+%(New to version 1.2. Not available with \app{texosquery-jre5}.)
+%
+%This action starts from the directory \meta{dir} \emph{which must
+%be on the current working directory's path} and returns a list
+%separated by \meta{sep} of all the regular files whose basename matches
+%the regular expression \meta{regex} (as for the filtered file
+%listings described above), recursively descending
+%sub-directories. Any files or sub-directories that are hidden, unreadable
+%or symbolic links are skipped. The list is sorted
+%according to \meta{sort}, which is as for the file listing actions
+%described above. Note that \meta{dir} is first converted to its
+%canonical path, so if \meta{dir} is a symbolic link, the
+%security check will test if the \emph{target} path is on the
+%current working directory path.
+%
+%As with the above file listings, the separator \meta{sep} isn't
+%escaped so take care if \meta{sep} contains any commands. The
+%resulting list will consist of paths relative to \meta{dir}.
+%
+%\begin{important}
+%This action requires at least Java 7 so it's not available with
+%\file{texosquery-jre5.jar}.
+%\end{important}
+%
+%\subsubsection{Action \shortarg{u} \meta{file} or \longarg{uri}
+%\meta{file}}
+%
+%This action displays the URI of the given file or an empty string if the file
+%doesn't exist or if the file permissions or the
+%\texttt{openin\_any} setting prohibit read access.
+%
+%\subsubsection{Action \shortarg{p} \meta{file} or \longarg{path}
+%\meta{file}}
+%
+%This action displays the canonical path of the given file or an
+%empty string if the file doesn't exist or if the file permissions
+%or the \texttt{openin\_any} setting prohibit this action.
+%
+%\subsubsection{Action \shortarg{e} \meta{file} or \longarg{dirname}
+%\meta{file}}
+%
 %(New to v1.1.)
-%Displays the canonical path of the given file's parent (that is, the
-%directory containing \meta{file}) or a blank line if
-%the file doesn't exist or the file permissions prohibit this
+%This action displays the canonical path of the given file's parent (that is, the
+%directory containing \meta{file}) or an empty string if
+%the file doesn't exist or if the file permissions or the
+%\texttt{openin\_any} setting prohibits this
 %action. Note that this is different to the Unix-like 
-%\texttt{dirname} command, which will return a relative path if
+%\app{dirname} command, which will return a relative path if
 %\meta{file} isn't an absolute path.
-%\item[\shortarg{h} or \longarg{help}] Displays help message and
-%exits.
-%\item[\shortarg{v} or \longarg{version}] Displays version
-%information and exits.
-%\end{description}
 %
-%If multiple options are given, they will be processed in the
-%order specified in the command line invocation. Each result will
-%be displayed on a separate line. As from v1.1, if there are
-%multiple actions, each result will be grouped. This makes it easier
-%to process the results in \TeX. For example:
+%\subsubsection{Action \shortarg{N} \oarg{language tag} or \longarg{numeric}
+%\oarg{language tag}}
+%
+%(New to v1.2.) This action displays:
+%\begin{definition}
+%\marg{locale tag}\marg{group sep}\marg{decimal sep}\marg{exp
+%sep}\marg{use group}\marg{currency code}\marg{regional currency
+%code}\marg{currency sym}\marg{\TeX\ currency}\marg{currency sep} 
+%\end{definition}
+%for the \meta{language tag} given in the optional argument. If omitted, the
+%default locale is assumed. The returned values are:
+%\begin{itemize}
+%\item \meta{tag} the language tag.
+%\item \meta{group sep} the numeric group separator.
+%\item \meta{decimal sep} the decimal separator.
+%\item \meta{exp sep} the exponent separator.
+%\item \meta{use group} \texttt{1} if the locale uses number
+%grouping otherwise \texttt{0}.
+%\item \meta{currency code} the ISO 4217 currency code.
+%\item \meta{regional currency code} either the ISO 4217 currency
+%code or an unofficial code. The only unofficial codes returned are:
+%GGP (Guernsey pound), JEP (Jersey pound), IMP (Isle of Man
+%pound), KID (Kiribati dollar) and TVD (Tuvaluan dollar).
+%\item \meta{currency sym} the currency symbol. (This may sometimes be
+%the same as \meta{currency code}.) Non-ASCII characters will be
+%marked up with \cs{twrp} (see below).
+%\item \meta{\TeX\ currency} the currency symbol using \TeX\ code
+%provided by \sty{texosquery}.
+%This is obtained by substituting known Unicode
+%currency symbols occurring in \meta{currency sym} with
+%\cs{texosquerycurrency}\marg{xxx}, which expands to the control
+%sequence given by the name \texttt{texosquerycurrency}\meta{xxx}.
+%These commands are defined in \file{texosquery.tex}. Since there are no generic \TeX\ commands
+%available for all these symbols (except \$), these commands will need to be
+%redefined as appropriate but are provided in the event that there's
+%no UTF-8 support. There is a limited check for some known currency
+%commands, such as \cs{texteuro} or \cs{euro}, but if an appropriate
+%currency command can't be found, the
+%\cs{texosquerycurrency}\meta{xxx} commands will be defined to
+%simply the currency label (usually the same as the \meta{xxx}
+%part).
+%
+%\item \meta{currency sep} the currency decimal separator.
+%\end{itemize}
+%The language tag should conform to \gls{IETF} \gls{BCP}~47. See
+%\url{http://docs.oracle.com/javase/8/docs/api/java/util/Locale.html}
+%for further details. If you are using \app{texosquery-jre5},
+%only the language, region and variant elements will be recognised
+%since the language tag support was introduced in Java~7.
+%
+%For example:
 %\begin{verbatim}
-%texosquery -l
+%texosquery -N en-GB
 %\end{verbatim}
-%This just produces (for me):
+%produces
 %\begin{verbatim}
-%en-GB.utf8
+%{en-GB}{,}{.}{E}{1}{GBP}{GBP}{\twrp{£}}{\texosquerycurrency{pound}}{.}
 %\end{verbatim}
-%whereas
+%The \cs{twrp} command is used by \app{texosquery} to markup a
+%non-\gls{ASCII} character. This command is one of the shorthands only
+%defined within \cs{TeXOSQuery}. In this case it's a shortcut for
+%the command \cs{texosquerynonasciiwrap}. By default this just does its
+%argument, but it may be redefined to perform some other action such
+%as converting from one encoding to another.
+%
+%In most cases the \meta{regional currency code} will be the same
+%as \meta{currency} code. A few non-ambiguous unofficial codes
+%are known by \app{texosquery} and may be used if the country code
+%is recognised. For example, 
 %\begin{verbatim}
-%texosquery -l -n
+%texosquery -N en-IM
 %\end{verbatim}
-%produces:
+%produces
 %\begin{verbatim}
-%{en-GB.utf8}
-%{D:20160714112732+01'00'}
+%{en-IM}{,}{.}{E}{1}{GBP}{IMP}{M\twrp{£}}{M\texosquerycurrency{pound}}{.}
 %\end{verbatim}
-%Note that unavailable information will produce an empty group.
-%For example (assuming \texttt{nofile} doesn't exist):
+%
+%If Java doesn't support the given locale, the currency code will
+%appear as \texttt{XXX} with the symbol \textcurrency\ (generic
+%currency sign).
+%
+%\begin{important}
+%This option and the following (\longarg{locale-data}) are best used
+%with \XeTeX\ or \LuaTeX\ to deal with the non-\gls{ASCII} characters. 
+%Make sure the file encoding used by Java matches the \TeX\ file.
+%\end{important}
+%
+%(See section~\ref{sec:locales} for the difference in locale
+%providers.)
+%
+%\subsubsection{Action \shortarg{D} \oarg{language tag} or
+%\longarg{locale-data} \oarg{language tag}}
+%
+%(New to v1.2.) This action provides more
+%extensive information than \longarg{numeric}.
+%The result has nested groups to assist parsing.
+%Again the \meta{language tag} may be omitted. For example, 
 %\begin{verbatim}
-%texosquery -l -d nofile -n
+%texosquery --locale-data
 %\end{verbatim}
-%produces:
+%For the default locale or 
 %\begin{verbatim}
-%{en-GB.utf8}
-%{}
-%{D:20160714112732+01'00'}
+%texosquery --locale-data en-GB
 %\end{verbatim}
-%whereas 
+%for the locale identified by \texttt{en-GB}.
+%As with all the other actions, the result is written to STDOUT on a
+%single line. Its overall length and the use of the shortcut
+%commands used by \app{texosquery} to markup certain elements mean
+%that it's not particularly human-readable, but it's designed to be
+%easy for \TeX\ to interpret. The information is returned in the
+%following format:
+%\begin{definition}
+%\marg{locale block}\marg{current date block}\marg{date pattern
+%block}\marg{current time block}\allowbreak\marg{time pattern
+%block}\marg{current date time block}\marg{date time pattern block}\marg{days
+%of the week block}\marg{abbreviated dates of the week
+%block}\marg{month names block}\marg{abbreviated month names
+%block}\marg{standalone days of the week block}\marg{abbreviated
+%standalone days of the week block}\marg{standalone month names
+%block}\marg{abbreviated standalone month names block}\marg{numeric
+%block}\marg{numeric patterns block}
+%\end{definition}
+%There may seem to be some repetition here with the month and week
+%day names, but with \app{texosquery-jre8}, the second set are the
+%standalone version (for example, for a column header). In some
+%languages, these may be different from the names used in the date
+%format. Since this is new to Java 8, it's not supported in
+%\file{texosquery.jar} or \file{texosquery-jre5.jar} and they simply reproduce
+%the non-standalone names.
+%
+%The information supplied with this option is quite complex,
+%but it's used by the \sty{locale} package to set up all the 
+%required information for each locale used in the document. 
+%Any non-\gls{ASCII} characters are marked up with \cs{twrp},
+%which is locally defined by \cs{TeXOSQuery} to expand to
+%\cs{texosquerynonasciiwrap}. This may be redefined to deal with the
+%characters if necessary. For example, if the character needs to be
+%converted from one encoding to another.
+%
+%The blocks are:
+%\begin{description}
+%\item \meta{locale block}
+%
+%The locale information in the form:
+%\begin{definition}
+%\marg{tag}\marg{language name}\marg{locale language
+%name}\marg{region name}\marg{locale region name}\marg{variant
+%name}\marg{locale variant name}
+%\end{definition}
+%The \meta{tag} is the language tag (the same format as \longarg{bcp47}).
+%
+%The \meta{language name} is the language name in the operating
+%system's default locale.
+%
+%The \meta{locale language name} is the language name in
+%the locale's language.
+%
+%For example, my locale is \texttt{en-GB}, so if I use
 %\begin{verbatim}
-%texosquery -d nofile
+%texosquery -D en-GB
 %\end{verbatim}
-%just displays an empty line.
+%then both \meta{language name} and \meta{locale language name} will
+%be \texttt{English}, but if I use:
+%\begin{verbatim}
+%texosquery -D fr-GB
+%\end{verbatim}
+%then \meta{language name} will be \texttt{French} and the \meta{locale
+%language name} will be \texttt{fran\cs{twrp}\char`\{\c{c}\char`\}ais} (note the non-ASCII
+%character has been marked up). The locale tag \verb|fr-GB|
+%indicates that I'm writing in French but I'm in the United Kingdom
+%(so the currency should be GBP).
 %
+%The \meta{region name} is the region's name in the operating
+%system's default language.
+%
+%The \meta{locale region name} is the region's name in the locale's language.
+%
+%So for me with \texttt{-D en-GB} I get
+%\verb|United\tspc Kingdom| for both \meta{region name} and
+%\meta{locale region name}. This illustrates another of the
+%shorthand commands that \app{texosquery} uses that's only locally
+%defined within \cs{TeXOSQuery}. In this case, \cs{tspc} just expands
+%to a space. This is used to avoid accidentally discarding any
+%intentional spaces that might follow a command name or any
+%intentional consecutive spaces.
+%
+%If, however, I use \texttt{-D fr-GB} I still get 
+%\verb|United\tspc Kingdom| in \meta{region name}, but \meta{locale
+%region name} is now \verb|Royaume-Uni|.
+%
+%The \meta{variant name} is the language's variant. For example,
+%with \verb|de-CH-1996| (Swiss German using the new orthography),
+%the variant is 1996. There's no variant in \verb|en-GB| so this
+%value is empty for me.
+%
+%The \meta{locale variant name} is the variant in the locale's
+%language. In the case of \verb|de-CH-1996| this is still 1996.
+%
+%\item \meta{current date block}
+%
+%This returns the current date in four different formats and also an
+%integer that indicates the first day of the week in the given
+%locale:
+%\begin{definition}
+%\marg{full date}\marg{long date}\marg{medium date}\marg{short
+%date}\marg{first day}
+%\end{definition}
+%The actual date formats depend on the locale. For example, with
+%\texttt{en-GB} the \meta{full date} is (assuming today is
+%2016-11-08):
+%\begin{verbatim}
+%Tuesday,\tspc 8\tspc November\tspc 2016
+%\end{verbatim}
+%(Tuesday, 8 November 2016).
+%The \meta{long date} is 
+%\begin{verbatim}
+%08\tspc November\tspc 2016
+%\end{verbatim}
+%(08 November 2016).
+%The \meta{medium date} is
+%\begin{verbatim}
+%08\thyn Nov\thyn 2016
+%\end{verbatim}
+%(08-Nov-2016).
+%The \meta{short date} is
+%\begin{verbatim}
+%08\tslh 11\tslh 16
+%\end{verbatim}
+%(08/11/2016).
+%Note that there's a difference between using the \gls{CLDR} locale data
+%and the JRE data. If I'm using the Java~7 compatible
+%\app{texosquery.jar} which only uses JRE locale data, then I get
+%the above results, but if I use \file{texosquery-jre8.sh} which
+%sets \texttt{java.locale.providers} to \texttt{CLDR,JRE} then I get
+%a slightly different result. The \meta{long date} is
+%\begin{verbatim}
+%8\tspc November\tspc 2016
+%\end{verbatim}
+%(8 November 2016)
+%and the \meta{medium date} is
+%\begin{verbatim}
+%8\tspc Nov\tspc 2016
+%\end{verbatim}
+%(8 Nov 2016).
+%The \meta{medium date} may be numeric or may be an abbreviated
+%form of \meta{long date}, depending on the language and the locale
+%provider. Some languages aren't supported by \gls{JRE} but are supported
+%by \gls{CLDR}. (Some aren't supported by either, but there's a 
+%chance that those languages will eventually be added to the CLDR.)
+%For example, if I use \texttt{-D cy-GB} with the JRE as the locale
+%provider I just get the \texttt{en-GB} dates, but if I use the CLDR
+%provider I get Welsh dates. 
+%
+%Note that the proposed Java~9 should automatically use the CLDR as
+%the locale provider, which is being increasingly adopted by
+%applications as a common data repository.
+%
+%The first day of the week index is zero-based starting with Monday.
+%This is done in order to be compatible with \sty{pgfcalendar}. For
+%example, with \texttt{-D en-GB} \meta{first day} is 0 (Monday), but
+%with \texttt{pt-BR} \meta{first day} is 6 (Sunday). The
+%\sty{locale} package provides a way of converting the index to
+%Monday=1 or Sunday=1 indexing.
+%
+%\item \meta{date pattern block}
+%
+%The pattern used to format the full date, long date, medium
+%date and short date. This is in the form:
+%
+%\marg{full pattern}\marg{long pattern}\marg{medium
+%pattern}\marg{short pattern}
+%
+%Each pattern uses shorthand mark-up that's only locally defined
+%within \cs{TeXOSQuery}. These short commands are expanded to longer
+%commands provided by \file{texosquery.tex} to avoid name clashing
+%with other packages. When used directly in the document text, these
+%expand to reproduce the pattern.
+%
+%For example, with \texttt{-D en-GB} I get the following 
+%pattern for the short date:
+%\begin{verbatim}
+%\patdtf{2}{d}\tslh \patdtf{2}{M}\tslh \patdtf{2}{y}
+%\end{verbatim}
+%When parsed by \cs{TeXOSQuery}, this is internally converted to
+%\begin{verbatim}
+%\texosquerydtf{2}{d}/\texosquerydtf{2}{M}/\texosquerydtf{2}{y}
+%\end{verbatim}
+%But default this simply expands to \texttt{dd/MM/yy} but may be
+%used in the first argument of \cs{texosqueryfmtdatetime}. See
+%sections~\ref{sec:patternformats} and \ref{sec:applydatetimepatterns} for
+%further details.
+%
+%\item \meta{current time block}
+%
+%The current time provided in various formats suitable to the
+%given locale:
+%\begin{definition}
+%\marg{full time}\marg{long time}\marg{medium time}\marg{short time}
+%\end{definition}
+%As with the current date, the actual format depends on the locale
+%and the locale provider. For example, with \texttt{en-GB} I get:
+%\begin{verbatim}
+%{15:59:41\tspc o\csq clock\tspc GMT}{15:59:41\tspc GMT}{15:59:41}{15:59}
+%\end{verbatim}
+%with the \gls{JRE}. If I switch to \gls{CLDR} (\file{texosquery-jre8.sh}) I get:
+%\begin{verbatim}
+%{16:00:51\tspc Greenwich\tspc Mean\tspc Time}{16:00:51\tspc GMT}{16:00:51}{16:00}
+%\end{verbatim}
+%
+%\item \meta{time pattern block}
+%
+%The pattern used to format the full time, long time, medium
+%time and short time.
+%
+%\marg{full time pattern}\marg{long time pattern}\marg{medium time
+%pattern}\marg{short time pattern}
+%
+%Again, when used with \cs{TeXOSQuery}, the short commands, such as
+%\cs{patdtf}, are internally converted.
+%They're not defined outside that scope.
+%
+%\item \meta{current date time block}
+%
+%The current date and time provided in various formats suitable to the
+%given locale:
+%\begin{definition}
+%\marg{full date time}\marg{long date time}\marg{medium date
+%time}\marg{short date time}
+%\end{definition}
+%This may simply be the date and time from above separated by 
+%a space.
+%
+%\item \meta{date time pattern block}
+%
+%The pattern used to format the full date time, long date time, medium
+%date time and short date time. This may simply be the date and
+%time patterns from above separated by a space.
+%\begin{definition}
+%\marg{full date time pattern}\marg{long date time
+%pattern}\marg{medium date time pattern}\marg{short date time pattern}
+%\end{definition}
+%
+%\item \meta{days of the week block}
+%
+%The week day names (starting with Monday for consistency with
+%\sty{pgfcalendar}) in the locale's language. Non-\gls{ASCII} characters are marked up with
+%\cs{twrp}.
+%\begin{definition}
+%\marg{Monday}\marg{Tuesday}\marg{Wednesday}\marg{Thursday}\marg{Friday}\marg{Saturday}\marg{Sunday}
+%\end{definition}
+%\item \meta{abbreviated days of the week block}
+%
+%As above, but abbreviated.
+%
+%\item \meta{month names block}
+%
+%The month names.
+%
+%\item \meta{abbreviated month names block}
+%
+%The abbreviated month names.
+%
+%\item \meta{standalone days of the week block}
+%
+%The week day names when used in a standalone context (for example, a
+%column header). This may be the same as the earlier \meta{days of
+%the week block} (and will be the same for \file{texosquery.jar} and
+%\file{texosquery-jre5.jar}). The standalone support was 
+%introduced to Java~8.
+%
+%\item \meta{abbreviated standalone days of the week block}
+%
+%As above, but abbreviated.
+%
+%\item \meta{standalone month names block}
+%
+%The month names when used in a standalone context (for example, a
+%column header). This may be the same as the earlier \meta{month
+%names block} (and will be the same for \file{texosquery.jar} and
+%\file{texosquery-jre5.jar}). The standalone support was 
+%introduced to Java~8.
+%
+%\item \meta{abbreviated standalone month names block}
+%
+%As above but abbreviated.
+%
+%\item \meta{numeric block}
+%
+%The numeric data similar to \longarg{numeric} but it's
+%missing the \meta{tag} (which is provided in the earlier
+%\meta{locale block}) and there are two extra items:
+%\begin{definition}
+%\marg{group sep}\marg{decimal sep}\marg{exp
+%sep}\marg{use group}\marg{currency code}\marg{regional currency
+%code}\marg{currency sym}\marg{currency tex}\marg{currency sep}
+%\marg{percent sym}\marg{per mill sym}
+%\end{definition}
+%See above for the elements that are also provided in
+%\longarg{numeric}. The additional elements are \meta{percent sym}
+%and \meta{per mill sym}, which are the percent and
+%per-mill symbols, respectively. The percent symbol \verb|%| has its
+%category code changed to 12 by \cs{TeXOSQuery}. As with other
+%non-ASCII characters, the per-mill symbol will be marked up with
+%\cs{twrp}.
+%
+%\item \meta{numeric patterns block}
+%
+%The patterns used to format decimals, integers, currency and
+%percentages.
+%\begin{definition}
+%\marg{decimal pattern}\marg{integer pattern}\marg{currency
+%pattern}\marg{percentages pattern}
+%\end{definition}
+%As with the date and time patterns, when used with \cs{TeXOSQuery}, the
+%short commands, such as \cs{patdgt}, are internally converted.
+%They're not defined outside that scope.
+%
+%If a pattern is used directly in the text, it will expand to the
+%original pattern padded to ten digits. (Eleven digit integers are outside
+%\TeX's maximum number range.)
+%
+%Any of these numeric patterns may be used in the first argument of
+%the low-level user command \cs{texosqueryfmtnumber} described in 
+%section~\ref{sec:applynumpatterns}. This command uses the following
+%macros:
+%\begin{definition}
+%\cs{texosquerypatfmtcurrencysign}
+%\end{definition}
+%The currency sign (defaults to \verb|\$|). For example, when parsing the previous
+%\meta{numeric block}, this command can be redefined to the \marg{currency sym} or
+%\marg{currency tex} elements.
+%
+%\begin{definition}
+%\cs{texosquerypatfmtgroupsep}
+%\end{definition}
+%The group separator (defaults to \verb|,|). For example, when parsing the previous
+%\meta{numeric block}, this command can be redefined to the
+%\marg{group sep} element.
+%
+%\begin{definition}
+%\cs{texosquerypatfmtdecsep}
+%\end{definition}
+%The decimal separator (defaults to \verb|.|). For example, when parsing the previous
+%\meta{numeric block}, this command can be redefined to the
+%\marg{dec sep} element.
+%
+%\begin{definition}
+%\cs{texosquerypatfmtcurdecsep}
+%\end{definition}
+%The monetary decimal separator (defaults to \verb|.|). For example, when parsing the previous
+%\meta{numeric block}, this command can be redefined to the
+%\marg{currency sep} element.
+%
+%\begin{definition}
+%\cs{texosquerypatfmtexp}
+%\end{definition}
+%The exponent sign (defaults to \texttt{E}). For example, when parsing the previous
+%\meta{numeric block}, this command can be redefined to the
+%\marg{exp sep} element.
+%
+%\begin{definition}
+%\cs{texosquerypatfmtpercentsign}
+%\end{definition}
+%The percent symbol. For example, when parsing the previous
+%\meta{numeric block}, this command can be redefined to the
+%\marg{percent sym} element.
+%
+%\begin{definition}
+%\cs{texosquerypatfmtpermillsign}
+%\end{definition}
+%The per-mill symbol. For example, when parsing the previous
+%\meta{numeric block}, this command can be redefined to the
+%\marg{per-mill sym} element.
+%
+%\begin{definition}
+%\cs{texosquerypatfmticurrencysign}
+%\end{definition}
+%The international currency sign. This is defined as \texttt{¤} by
+%default, unless the command \cs{textcurrency} has been defined, in
+%which case that's used instead. If the UTF-8 character ¤ is
+%available and \cs{textcurrency} hasn't been defined before 
+%\sty{texosquery} was input, then you will need to redefine this
+%command as appropriate.
+%
+%\begin{definition}
+%\cs{texosquerypatfmtminus}
+%\end{definition}
+%The minus sign.
+%
+%\begin{definition}
+%\cs{texosquerypatfmtplus}
+%\end{definition}
+%The plus sign.
+%
+%\end{description}
+%
 %\section{texosquery.tex: generic \TeX\ code}
-%You can run \texttt{texosquery} directly from \TeX's shell escape.
+%\label{sec:tex}
+%You can run \app{texosquery} directly from \TeX's shell escape.
 %For example:
 %\begin{verbatim}
 %\input|"texosquery --locale"
 %\end{verbatim}
-%However, \texttt{texosquery.tex} provides generic \TeX\ code to do
-%this for you and store the result in a control sequence.
+%However, \app{texosquery} uses markup commands in some of
+%the results which need to be defined first. The file
+%\file{texosquery.tex} provides generic \TeX\ code to do
+%this for you and stores the result in a control sequence.
 %
 %Plain \TeX\ users can input this file through the usual \cs{input}
 %method:
@@ -281,58 +1740,74 @@
 %The commands described below are all fragile.
 %\end{important}
 %
-%The basic command to run \texttt{texosquery} and capture its output
+%The basic command to run \app{texosquery} and capture its output
 %in a control sequence is:
 %\DescribeMacro\TeXOSQuery
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQuery}\marg{cs}\marg{args}
-%\end{flushleft}
+%\end{definition}
 %where \meta{cs} is the control sequence in which to store the
 %result and \meta{args} are the command line arguments to pass to 
-%\texttt{texosquery}. This first locally changes the category code
-%of some problematic characters that may appear in the result.
-%The only special characters that aren't changed are the backslash
-%\verb|\|, curly braces \verb|{| and \verb|}|, and hash \verb|#|.
-%(\texttt{texosquery.jar} will replace \verb|#| with \verb|\#| in places
-%where it might possibly occur in the result, but in general it's
-%best to avoid these characters in file names.)
-%
-%There are some short cut commands for convenience, described below.
-%If any of these commands cause an error message in the form:
+%\app{texosquery}. This first locally changes the category code
+%of some problematic characters and defines the short markup
+%commands that \app{texosquery} uses to identify characters that
+%need to be interpreted literally (for example, in file names).
+%These commands will automatically be expanded by \cs{TeXOSQuery}
+%when the result is input. For example
 %\begin{verbatim}
-%I can't find file `|texosquery'.
+%texosquery -n
 %\end{verbatim}
-%then check that you have the shell escape on. If the error 
-%persists with the shell escape enabled
-%(and not restricted), check that \texttt{texosquery} is on 
-%your system's path. To do this, open a command prompt or terminal and
-%type \texttt{texosquery}. If it isn't installed correctly, there will be a
-%message like:
+%produces
 %\begin{verbatim}
-%`texosquery' is not recognised
+%\pdfd \fcln 20161129221559\fpls 00\fapo 00\fapo 
 %\end{verbatim}
-%or
+%but when used with
 %\begin{verbatim}
-%texosquery: command not found
+%\TeXOSQuery{\result}{texosquery -n}
 %\end{verbatim}
-%If this happens, check the installation. (Instructions are
-%in the accompanying \texttt{README.md} file.)
+%the \cs{result} command will be set to
+%\begin{verbatim}
+%D:20161129221559+00'00' 
+%\end{verbatim}
+%where the characters \texttt{D} \text{:} \texttt{+} and
+%\texttt{\textquotesingle} all have category code 12 (other).
 %
-%Dry run mode is determined by the conditional
-%\DescribeMacro\ifTeXOSQueryDryRun
+%If the command failed, \meta{cs} will be set to empty. It's best to
+%always test for success after using \cs{TeXOSQuery} (or one of the
+%shortcut commands described below). For example:
 %\begin{verbatim}
-%\ifTeXOSQueryDryRun
+%\TeXOSQuery{\result}{-b}
+%\ifx\result\empty
+% Failed!
+%\else
+% Result: \result.
+%\fi
 %\end{verbatim}
-%If true, the shell escape won't be used and the requested command
-%invocation will be printed in the transcript file prefixed with
+%
+%Failure can occur because the dry run mode was on, or it can occur
+%if the query was denied (for example, forbidden file access),
+%or if there's a syntax error in the system call. As from 
+%version 1.2, \app{texosquery} checks the \texttt{openin\_any}
+%setting, which may forbid read access. Java's security manager
+%or the filing system may also forbid read access.
+%
+%To determine the cause of the error, first inspect the log file to
+%check if the shell escape was used. In the above example, if 
+%the shell escape was permitted, then the log file should include
 %\begin{verbatim}
-%TeXOSQuery:
+%(|texosquery -b)
 %\end{verbatim}
-%(the control sequence \meta{cs} will be set to empty).
-%This conditional will automatically be switched on unless
-%\cs{shellescape} or \cs{pdfshellescape} is 1. (If
-%\texttt{texosquery.jar} is later allowed on the restricted list,
-%newer versions may change this default.)
+%Copy and paste the system call (\verb|texosquery -b| in 
+%the above case) into your
+%\href{http://www.dickimaw-books.com/latex/novices/html/terminal.html}{command
+%prompt or terminal} and insert 
+%the \longarg{debug} switch at the start of the argument list. For
+%example:
+%\begin{verbatim}
+%texosquery --debug -b
+%\end{verbatim}
+%This should help determine whether it's a syntax error or a query forbidden 
+%by the operating system.
 %
 %If multiple queries are required, it's more efficient to
 %perform them all in one go. For example:
@@ -351,118 +1826,297 @@
 %\end{verbatim}
 %(Make sure you have at least v1.1 for this to work correctly.)
 %
+%\begin{important}
+%Take care of characters that have a special meaning to your shell.
+%For example, bash interprets \verb|#| as a comment. For example, if
+%you have a file called \texttt{image\#1.png}, then you can't simply
+%do
+%\begin{verbatim}
+%\TeXOSQuery{\result}{-p image#1.png}
+%\end{verbatim}
+%since bash will pass this as
+%\begin{verbatim}
+%texosquery.sh -p image
+%\end{verbatim}
+%(The \verb|#1.png| part is treated as a comment.) Nor can you do
+%\begin{verbatim}
+%\TeXOSQuery{\result}{-p image\#1.png}
+%\end{verbatim}
+%as \TeX\ will replace the \verb|\#| with \verb|#| when passing the
+%command invocation to the shell. The only way to deal with this
+%situation is to do
+%\begin{verbatim}
+%\TeXOSQuery{\result}{-p image\string\#1.png}
+%\end{verbatim}
+%to protect the \verb|#| character from both \TeX\ and the shell.
+%\end{important}
+%
+%Dry run mode is determined by the conditional
+%\DescribeMacro\ifTeXOSQueryDryRun
+%\begin{verbatim}
+%\ifTeXOSQueryDryRun
+%\end{verbatim}
+%If true, the shell escape won't be used and the requested command
+%invocation will be printed in the transcript file prefixed with
+%\begin{verbatim}
+%TeXOSQuery:
+%\end{verbatim}
+%(the control sequence \meta{cs} will be set to empty).
+%
+%\begin{important}
+%Remember that a query can still fail even if the dry run mode is
+%off.
+%\end{important}
+%
+%Note that if you switch off the dry run mode when the
+%shell escape setting forbids the execution of \app{texosquery},
+%then you'll get the rather annoying error:
+%\begin{verbatim}
+%runpopen command not allowed: texosquery
+%
+%! I can't find file `"|texosquery -b"'.
+%\TeXOSQueryInvoker ...TeXOSInvokerName \space #1" 
+%                                                  
+%\TeXOSQuery ...noexpand #1{\TeXOSQueryInvoker {#2}
+%                                                  }}\x \fi 
+%l.5 \TeXOSQuery{\result}{-b}
+%                              ^^M
+%(Press Enter to retry, or Control-D to exit)
+%\end{verbatim}
+%By default, the dry run mode is only switched off if the
+%unrestricted shell escape mode is on (detected through
+%\cs{shellescape} or \cs{pdfshellescape}).
+%
+%If \app{texosquery} is added to the restricted list, you can add
+%\begin{verbatim}
+%\TeXOSQueryAllowRestricted
+%\end{verbatim}
+%to the \file{texosquery.cfg} file. (This command can't be used
+%outside of that file.)
+%
+%If you get the above error, then:
+%\begin{itemize}
+%\item make sure you don't have
+%\cs{TeXOSQueryAllowRestricted} in your \file{texosquery.cfg}
+%file; 
+%\item make sure you run \TeX\ with the shell escape enabled;
+%\item check the definition of \cs{TeXOSInvokerName};
+%\item try using the application directly from the command prompt or
+%terminal. For example, in the above message, the bit between 
+%\texttt{\textasciigrave\textquotedbl\textbar} and
+%\texttt{\textquotedbl\textquotesingle} (that is, \texttt{texosquery-jre8 -b})
+%shows the attempted system call. Copy and paste it directly
+%into your operating system's 
+%\href{http://www.dickimaw-books.com/latex/novices/html/terminal.html}{command
+%prompt or terminal} and to check the application has been installed
+%correctly.
+%\end{itemize}
+%
+%\DescribeMacro\TeXOSInvokerName
+%The \cs{TeXOSQuery} command uses \cs{TeXOSInvokerName} to reference the
+%application name. This defaults to \app{texosquery} but needs to be
+%redefined to reflect the particular system call that's required.
+%For example, \texttt{texosquery.sh} (Unix-like with Java~7) or
+%\texttt{texosquery-jre8} (Windows with Java~8). This redefinition
+%can be done in the configuration file \file{texosquery.cfg} for a
+%system-wide setting. See section~\ref{sec:setup} for further
+%details.
+%
+%\begin{important}
+%Some of the shortcut commands listed below require extra arguments after the
+%relevant switch. These are automatically enclosed in single-quotes
+%to protect any spaces. If the argument actually contains any single-quote
+%characters, make sure you use \verb|\string\'| to prevent
+%interference.
+%
+%Since a file name reference may need to be obtained from \cs{jobname},
+%which sometimes includes double-quotes, the first double-quote pair
+%found is stripped in file name arguments. Any other double-quotes
+%will need to be protected in the same manner as single-quotes
+%(but this shouldn't be an issue if you use a safe file naming scheme). 
+%All paths should use a forward slash for the directory divider.
+%\end{important}
+%
+%\subsection{Locale}
 %The locale (\shortarg{l} or \longarg{locale-lcs}) information can be
 %obtained using:
 %\DescribeMacro\TeXOSQueryLocale
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQueryLocale}\marg{cs}
-%\end{flushleft}
+%\end{definition}
 %Note that this uses the lower case codeset form, which has a better
-%chance of matching the encoding names used by the \texttt{inputenc}
+%chance of matching the encoding names used by the \sty{inputenc}
 %package. If you want the unprocessed codeset name, you can do:
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQuery}\marg{cs}\{\shortarg{L}\}
-%\end{flushleft}
+%\end{definition}
+%If you just want the codeset in the same form as
+%\longarg{locale-lcs} you can do:
+%\begin{definition}
+%\cs{TeXOSQuery}\marg{cs}\{\shortarg{C}\}
+%\end{definition}
 %
-%The current working directory (\shortarg{c} or \longarg{cwd}) can
-%be obtained using:
-%\DescribeMacro\TeXOSQueryCwd
-%\begin{flushleft}\ttfamily
-%\cs{TeXOSQueryCwd}\marg{cs}
-%\end{flushleft}
+%The \gls{IETF} \gls{BCP}~47 language tag (\shortarg{b} or \longarg{bcp47}) 
+%can be obtained using:
+%\DescribeMacro\TeXOSQueryLangTag
+%\begin{definition}
+%\cs{TeXOSQueryLangTag}\marg{cs}
+%\end{definition}
 %
-%The home directory (\shortarg{m} or \longarg{userhome}) can
-%be obtained using:
-%\DescribeMacro\TeXOSQueryHome
-%\begin{flushleft}\ttfamily
-%\cs{TeXOSQueryHome}\marg{cs}
-%\end{flushleft}
+%The numeric separators and currency symbols (\shortarg{N} or
+%\longarg{numeric}) can be obtained using
+%\DescribeMacro\TeXOSQueryNumeric
+%\begin{definition}
+%\cs{TeXOSQueryNumeric}\marg{cs}\marg{locale}
+%\end{definition}
+%The \meta{locale} should be a valid language tag or may be empty
+%for the system's default locale. Similarly for the command below.
 %
-%The temporary directory (\shortarg{t} or \longarg{tmpdir}) can
-%be obtained using:
-%\DescribeMacro\TeXOSQueryTmpDir
-%\begin{flushleft}\ttfamily
-%\cs{TeXOSQueryTmpDir}\marg{cs}
-%\end{flushleft}
+%All the locale data (\shortarg{D} or \longarg{locale-data}) can be
+%obtained using
+%\DescribeMacro\TeXOSQueryLocaleData
+%\begin{definition}
+%\cs{TeXOSQueryLocaleData}\marg{cs}\marg{locale}
+%\end{definition}
 %
+%\subsection{Operating System Information}
 %The OS name (\shortarg{o} or \longarg{osname}) can
 %be obtained using:
 %\DescribeMacro\TeXOSQueryName
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQueryName}\marg{cs}
-%\end{flushleft}
+%\end{definition}
 %
 %The OS version (\shortarg{r} or \longarg{osversion}) can
 %be obtained using:
 %\DescribeMacro\TeXOSQueryVersion
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQueryVersion}\marg{cs}
-%\end{flushleft}
+%\end{definition}
 %
 %The OS architecture (\shortarg{a} or \longarg{osarch}) can
 %be obtained using:
 %\DescribeMacro\TeXOSQueryArch
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQueryArch}\marg{cs}
-%\end{flushleft}
+%\end{definition}
 %
+%\subsection{Dates and Times}
+%The current date and time information (\shortarg{M} or
+%\longarg{date-time}) can be obtained using:
+%\DescribeMacro\TeXOSQueryDateTime
+%\begin{definition}
+%\cs{TeXOSQueryDateTime}\marg{cs}
+%\end{definition}
+%Example usage:
+%\begin{verbatim}
+%\texosquerydefpattern{\pattern}{\%2d/\%2M/\%4y \%2H:\%2m:\%2s}
+%
+%\TeXOSQueryDateTime{\datetimedata}
+%
+%\ifx\datetimedata\empty
+% Query Failed!
+%\else
+% \expandafter\texosqueryfmtdatetime\expandafter\pattern\datetimedata
+%\fi
+%\end{verbatim}
+%Note that commands such as \cs{texosqueryfmtpatMMM} will need to be
+%defined to produce textual elements. See
+%sections~\ref{sec:patternformats} and \ref{sec:applydatetimepatterns} for
+%further details.
+%
+%The time zone mappings (\shortarg{Z} or
+%\longarg{time-zones}) can be obtained using:
+%\DescribeMacro\TeXOSQueryTimeZones
+%\begin{definition}
+%\cs{TeXOSQueryTimeZones}\marg{cs}\marg{locale}
+%\end{definition}
+%Leave \meta{locale} empty if the default locale is required.
+%
 %The current date-time stamp in PDF format (\shortarg{n} or
 %\longarg{pdfnow}) can be obtained using:
 %\DescribeMacro\TeXOSQueryNow
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQueryNow}\marg{cs}
-%\end{flushleft}
+%\end{definition}
 %This is provided for the benefit of users who don't have
 %\cs{pdfcreationdate} defined by their \TeX\ format (for example,
-%\XeTeX). As from v1.1, this ensures that the initial \texttt{D} has
-%category code 12 (which won't happen if \cs{TeXOSQuery} is used
-%explicitly).
+%\XeTeX).
 %
-%\begin{important}
-%The remaining commands all require extra arguments after the
-%relevant switch. These are automatically enclosed in single-quotes
-%to protect any spaces. If the argument actually contains any single-quote
-%characters, make sure you use \verb|\string\'| to prevent
-%interference. \emph{However, in general it's a very bad idea to use
-%quotes as part of a file name (rather than using them as
-%delimiters).}
-%Since the file name may need to be obtained from \cs{jobname},
-%which sometimes includes double-quotes, the first double-quote pair
-%found is stripped in file name arguments. Any other double-quotes
-%will need to be protected in the same manner as single-quotes
-%(but, again, this shouldn't be an issue if you use a safe
-%file naming scheme). Any paths should use a
-%forward slash for the directory divider.
-%\end{important}
-%
 %The modification date-time stamp in PDF format for a file
 %(\shortarg{d} or \longarg{pdfdate}) can be obtained using:
 %\DescribeMacro\TeXOSQueryFileDate
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQueryFileDate}\marg{cs}\marg{filename}
-%\end{flushleft}
+%\end{definition}
 %where \meta{filename} is the name of the file.
 %This is provided for the benefit of users who don't have
-%\cs{pdffilemoddate} defined by their \TeX\ format. As from v1.1,
-%this ensures that the initial \texttt{D} has category code 12 (which 
-%won't happen if \cs{TeXOSQuery} is used explicitly).
+%\cs{pdffilemoddate} defined by their \TeX\ format.
 %
+%\subsection{File Operations}
+%The current working directory (\shortarg{c} or \longarg{cwd}) can
+%be obtained using:
+%\DescribeMacro\TeXOSQueryCwd
+%\begin{definition}
+%\cs{TeXOSQueryCwd}\marg{cs}
+%\end{definition}
+%
+%The home directory (\shortarg{m} or \longarg{userhome}) can
+%be obtained using:
+%\DescribeMacro\TeXOSQueryHome
+%\begin{definition}
+%\cs{TeXOSQueryHome}\marg{cs}
+%\end{definition}
+%
+%The temporary directory (\shortarg{t} or \longarg{tmpdir}) can
+%be obtained using:
+%\DescribeMacro\TeXOSQueryTmpDir
+%\begin{definition}
+%\cs{TeXOSQueryTmpDir}\marg{cs}
+%\end{definition}
+%
 %The size in bytes of a file
 %(\shortarg{s} or \longarg{filesize}) can be obtained using:
 %\DescribeMacro\TeXOSQueryFileSize
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQueryFileSize}\marg{cs}\marg{filename}
-%\end{flushleft}
+%\end{definition}
 %where \meta{filename} is the name of the file.
 %This is provided for the benefit of users who don't have
 %\cs{pdffilesize} defined by their \TeX\ format.
 %
+%The URI of a file
+%(\shortarg{u} or \longarg{uri}) can be obtained using:
+%\DescribeMacro\TeXOSQueryFileURI
+%\begin{definition}
+%\cs{TeXOSQueryFileURI}\marg{cs}\marg{filename}
+%\end{definition}
+%where \meta{filename} is the name of the file.
+%(Any percent symbols \verb|%| contained in the URI will have
+%their category code set to 12.)
+%
+%The canonical path of a file
+%(\shortarg{p} or \longarg{path}) can be obtained using:
+%\DescribeMacro\TeXOSQueryFilePath
+%\begin{definition}
+%\cs{TeXOSQueryFilePath}\marg{cs}\marg{filename}
+%\end{definition}
+%where \meta{filename} is the name of the file.
+%
+%The canonical path of a file's parent
+%(\shortarg{e} or \longarg{dirname}) can be obtained using:
+%\DescribeMacro\TeXOSQueryDirName
+%\begin{definition}
+%\cs{TeXOSQueryDirName}\marg{cs}\marg{filename}
+%\end{definition}
+%where \meta{filename} is the name of the file.
+%
 %The list of files in a given directory
 %(\shortarg{i} or \longarg{list}) can be obtained using:
 %\DescribeMacro\TeXOSQueryFileList
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQueryFileList}\marg{cs}\marg{sep}\marg{dir}
-%\end{flushleft}
+%\end{definition}
 %where \meta{sep} is the separator and \meta{dir} is the directory name.
 %For example:
 %\begin{verbatim}
@@ -471,12 +2125,23 @@
 %will store a comma-separated list of all the files contained in the
 %current directory in the control sequence \cs{result}.
 %
+%To omit directories (\shortarg{ir} or \longarg{list-regular}):
+%\DescribeMacro\TeXOSQueryRegularFileList
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileList}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%To omit regular files (\shortarg{id} or \longarg{list-dir}):
+%\DescribeMacro\TeXOSQuerySubDirFileList
+%\begin{definition}
+%\cs{TeXOSQuerySubDirList}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%
 %A filtered list of files in a given directory
 %(\shortarg{f} or \longarg{filterlist}) can be obtained using:
 %\DescribeMacro\TeXOSQueryFilterFileList
-%\begin{flushleft}\ttfamily
+%\begin{definition}
 %\cs{TeXOSQueryFilterFileList}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
-%\end{flushleft}
+%\end{definition}
 %where \meta{regex} is a regular expression. \emph{Take care of any backslashes
 %in the regular expression!}
 %For example, to list only those files that have an extension:
@@ -484,42 +2149,406 @@
 %\TeXOSQueryFilterFileList{\result}{,}{.+\string\..*}{.}
 %\end{verbatim}
 %Note the use of \verb|\string\.| to ensure that \cs{.} isn't
-%interpreted as a command. Another example, list only \texttt{.png}
-%and \texttt{.jpg} files in the directory called \texttt{images}:
+%interpreted as a command. Another example, list only \file{.png}
+%and \file{.jpg} files in the directory called \file{images}:
 %\begin{verbatim}
 %\TeXOSQueryFilterFileList{\result}{,}{.+\string\.(jpg|png)}{images}
 %\end{verbatim}
 %
-%The URI of a file
-%(\shortarg{u} or \longarg{uri}) can be obtained using:
-%\DescribeMacro\TeXOSQueryFileURI
-%\begin{flushleft}\ttfamily
-%\cs{TeXOSQueryFileURI}\marg{cs}\marg{filename}
-%\end{flushleft}
-%where \meta{filename} is the name of the file.
-%(Any percent symbols \verb|%| contained in the URI will have
-%their category code set to 12.)
+%\begin{important}
+%Unlike most of the return values the \meta{sep} part here isn't
+%escaped, so take care if \meta{sep} contains any commands. For
+%example, if you want to use \verb|\\| as the separator, you'll need
+%to use \verb|\string\noexpand\string\\| in the \meta{sep} part.
+%\begin{verbatim}
+%\TeXOSQueryFilterFileList{\result}{\string\noexpand\string\\}{.*\string\.tex}{.}
+%\end{verbatim}
+%\end{important}
 %
-%The canonical path of a file
-%(\shortarg{p} or \longarg{path}) can be obtained using:
-%\DescribeMacro\TeXOSQueryFilePath
-%\begin{flushleft}\ttfamily
-%\cs{TeXOSQueryFilePath}\marg{cs}\marg{filename}
-%\end{flushleft}
-%where \meta{filename} is the name of the file.
+%If you want the list sorted, you can use the following which set
+%the optional \meta{sort} argument.
 %
-%The canonical path of a file's parent
-%(\shortarg{e} or \longarg{dirname}) can be obtained using:
-%\DescribeMacro\TeXOSQueryDirName
-%\begin{flushleft}\ttfamily
-%\cs{TeXOSQueryDirName}\marg{cs}\marg{filename}
-%\end{flushleft}
-%where \meta{filename} is the name of the file.
+%Order by last modified date starting with the oldest (\texttt{date-ascending}):
+%\DescribeMacro\TeXOSQueryFileListDateAsc
+%\begin{definition}
+%\cs{TeXOSQueryFileListDateAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the regular files only list:
+%\DescribeMacro\TeXOSQueryRegularFileListDateAsc
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileListDateAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the sub-directories only list:
+%\DescribeMacro\TeXOSQuerySubDirListDateAsc
+%\begin{definition}
+%\cs{TeXOSQuerySubDirListDateAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or for the filtered list:
+%\DescribeMacro\TeXOSQueryFilterFileListDateAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterFileListDateAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or for the filtered regular files only list:
+%\DescribeMacro\TeXOSQueryFilterRegularFileListDateAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListDateAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or for the filtered sub-directories only list:
+%\DescribeMacro\TeXOSQueryFilterSubDirListDateAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterSubDirListDateAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
 %
-%\StopEventually{\phantomsection
+%Order by last modified date starting with the newest (\texttt{date-descending}):
+%\DescribeMacro\TeXOSQueryFileListDateDes
+%\begin{definition}
+%\cs{TeXOSQueryFileListDateDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the regular files only list:
+%\DescribeMacro\TeXOSQueryRegularFileListDateDes
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileListDateDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the sub-directories only list:
+%\DescribeMacro\TeXOSQuerySubDirListDateDes
+%\begin{definition}
+%\cs{TeXOSQuerySubDirListDateDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or for the filtered list:
+%\DescribeMacro\TeXOSQueryFilterFileListDateDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterFileListDateDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered regular files only list:
+%\DescribeMacro\TeXOSQueryFilterRegularFileListDateDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListDateDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered sub-directories only list:
+%\DescribeMacro\TeXOSQueryFilterSubDirListDateDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListDateDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%Order by file size starting with the smallest (\texttt{size-ascending}):
+%\DescribeMacro\TeXOSQueryFileListSizeAsc
+%\begin{definition}
+%\cs{TeXOSQueryFileListSizeAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the regular files only list:
+%\DescribeMacro\TeXOSQueryRegularFileListSizeAsc
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileListSizeAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the sub-directories only list:
+%\DescribeMacro\TeXOSQuerySubDirListSizeAsc
+%\begin{definition}
+%\cs{TeXOSQuerySubDirListSizeAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or for the filtered list:
+%\DescribeMacro\TeXOSQueryFilterFileListSizeAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterFileListSizeAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered regular files only list:
+%\DescribeMacro\TeXOSQueryFilterRegularFileListSizeAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListSizeAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered sub-directories only list:
+%\DescribeMacro\TeXOSQueryFilterSubDirListSizeAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterSubDirListSizeAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%Order by file size starting with the largest (\texttt{size-descending}):
+%\DescribeMacro\TeXOSQueryFileListSizeDes
+%\begin{definition}
+%\cs{TeXOSQueryFileListSizeDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the regular files only list:
+%\DescribeMacro\TeXOSQueryRegularFileListSizeDes
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileListSizeDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the sub-directories only list:
+%\DescribeMacro\TeXOSQuerySubDirListSizeDes
+%\begin{definition}
+%\cs{TeXOSQuerySubDirListSizeDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or for the filtered list:
+%\DescribeMacro\TeXOSQueryFilterFileListSizeDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterFileListSizeDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the filtered regular files only list:
+%\DescribeMacro\TeXOSQueryFilterRegularFileListSizeDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListSizeDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the filtered sub-directories only list:
+%\DescribeMacro\TeXOSQueryFilterSubDirListSizeDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterSubDirListSizeDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%
+%Order by file name in alphabetical order (\texttt{name-ascending}):
+%\DescribeMacro\TeXOSQueryFileListNameAsc
+%\begin{definition}
+%\cs{TeXOSQueryFileListNameAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the regular files only list:
+%\DescribeMacro\TeXOSQueryRegularFileListNameAsc
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileListNameAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the sub-directories only list:
+%\DescribeMacro\TeXOSQuerySubDirListNameAsc
+%\begin{definition}
+%\cs{TeXOSQuerySubDirListNameAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or for the filtered list:
+%\DescribeMacro\TeXOSQueryFilterFileListNameAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterFileListNameAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered regular files only list:
+%\DescribeMacro\TeXOSQueryFilterRegularFileListNameAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListNameAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered sub-directories only list:
+%\DescribeMacro\TeXOSQueryFilterSubDirListNameAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterSubDirListNameAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%Order by file name in reverse alphabetical order (\texttt{name-descending}):
+%\DescribeMacro\TeXOSQueryFileListNameDes
+%\begin{definition}
+%\cs{TeXOSQueryFileListNameDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the regular files only list:
+%\DescribeMacro\TeXOSQueryRegularFileListNameDes
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileListNameDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the sub-directories only list:
+%\DescribeMacro\TeXOSQuerySubDirListNameDes
+%\begin{definition}
+%\cs{TeXOSQuerySubDirListNameDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or for the filtered list:
+%\DescribeMacro\TeXOSQueryFilterFileListNameDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterFileListNameDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the filtered regular files only list:
+%\DescribeMacro\TeXOSQueryFilterRegularFileListNameDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListNameDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the filtered sub-directories only list:
+%\DescribeMacro\TeXOSQueryFilterSubDirListNameDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterSubDirListNameDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%
+%Order by file name in case-insensitive alphabetical order
+%(\texttt{iname-ascending}):
+%\DescribeMacro\TeXOSQueryFileListNameIgnoreCaseAsc
+%\begin{definition}
+%\cs{TeXOSQueryFileListNameIgnoreCaseAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the regular files only list:
+%\DescribeMacro\TeXOSQueryRegularFileListNameIgnoreCaseAsc
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileListNameIgnoreCaseAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the sub-directories only list:
+%\DescribeMacro\TeXOSQuerySubDirListNameIgnoreCaseAsc
+%\begin{definition}
+%\cs{TeXOSQuerySubDirListNameIgnoreCaseAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or for the filtered list:
+%\DescribeMacro\TeXOSQueryFilterFileListNameIgnoreCaseAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterFileListNameIgnoreCaseAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered regular files only list:
+%\DescribeMacro\TeXOSQueryFilterRegularFileListNameIgnoreCaseAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListNameIgnoreCaseAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered sub-directories only list:
+%\DescribeMacro\TeXOSQueryFilterSubDirListNameIgnoreCaseAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterSubDirListNameIgnoreCaseAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%Order by file name in reverse case-insensitive alphabetical order 
+%(\texttt{iname-descending}):
+%\DescribeMacro\TeXOSQueryFileListNameIgnoreCaseDes
+%\begin{definition}
+%\cs{TeXOSQueryFileListNameIgnoreCaseDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the regular files only list:
+%\DescribeMacro\TeXOSQueryRegularFileListNameIgnoreCaseDes
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileListNameIgnoreCaseDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the sub-directories only list:
+%\DescribeMacro\TeXOSQuerySubDirListNameIgnoreCaseDes
+%\begin{definition}
+%\cs{TeXOSQuerySubDirListNameIgnoreCaseDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or for the filtered list:
+%\DescribeMacro\TeXOSQueryFilterFileListNameIgnoreCaseDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterFileListNameIgnoreCaseDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered regular files only list:
+%\DescribeMacro\TeXOSQueryFilterRegularFileListNameIgnoreCaseDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListNameIgnoreCaseDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered sub-directories only list:
+%\DescribeMacro\TeXOSQueryFilterSubDirListNameIgnoreCaseDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterSubDirListNameIgnoreCaseDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%Order by file extension in alphabetical order (\texttt{ext-ascending}):
+%\DescribeMacro\TeXOSQueryFileListExtAsc
+%\begin{definition}
+%\cs{TeXOSQueryFileListExtAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the regular files only list:
+%\DescribeMacro\TeXOSQueryRegularFileListExtAsc
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileListExtAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the sub-directories only list:
+%\DescribeMacro\TeXOSQuerySubDirListExtAsc
+%\begin{definition}
+%\cs{TeXOSQuerySubDirListExtAsc}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or for the filtered list:
+%\DescribeMacro\TeXOSQueryFilterFileListExtAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterFileListExtAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered regular files only list:
+%\DescribeMacro\TeXOSQueryFilterRegularFileListExtAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListExtAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered sub-directories only list:
+%\DescribeMacro\TeXOSQueryFilterSubDirListExtAsc
+%\begin{definition}
+%\cs{TeXOSQueryFilterSubDirListExtAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%Order by file extension in reverse alphabetical order (\texttt{ext-descending}):
+%\DescribeMacro\TeXOSQueryFileListExtDes
+%\begin{definition}
+%\cs{TeXOSQueryFileListExtDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the regular files only list:
+%\DescribeMacro\TeXOSQueryRegularFileListExtDes
+%\begin{definition}
+%\cs{TeXOSQueryRegularFileListExtDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or the sub-directories only list:
+%\DescribeMacro\TeXOSQuerySubDirListExtDes
+%\begin{definition}
+%\cs{TeXOSQuerySubDirListExtDes}\marg{cs}\marg{sep}\marg{dir}
+%\end{definition}
+%or for the filtered list:
+%\DescribeMacro\TeXOSQueryFilterFileListExtDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterFileListExtDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered regular files only list:
+%\DescribeMacro\TeXOSQueryFilterRegularFileListExtDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterRegularFileListExtDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or the filtered sub-directories only list:
+%\DescribeMacro\TeXOSQueryFilterSubDirListExtDes
+%\begin{definition}
+%\cs{TeXOSQueryFilterSubDirListExtDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%A recursive filtered list of regular files starting from a given directory
+%on the current working path
+%(\shortarg{w} or \longarg{alk}) can be obtained using:
+%\DescribeMacro\TeXOSQueryWalk
+%\begin{definition}
+%\cs{TeXOSQueryWalk}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%where \meta{regex} is as for the filtered listings described above.
+%
+%To sort according to last modified date:
+%\DescribeMacro\TeXOSQueryWalkDateAsc
+%\begin{definition}
+%\cs{TeXOSQueryWalkDateAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or in reverse order:
+%\DescribeMacro\TeXOSQueryWalkDateDes
+%\begin{definition}
+%\cs{TeXOSQueryWalkDateDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%To sort according to file size:
+%\DescribeMacro\TeXOSQueryWalkSizeAsc
+%\begin{definition}
+%\cs{TeXOSQueryWalkSizeAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or in reverse order:
+%\DescribeMacro\TeXOSQueryWalkSizeDes
+%\begin{definition}
+%\cs{TeXOSQueryWalkSizeDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%To sort according to path name (case-sensitive):
+%\DescribeMacro\TeXOSQueryWalkNameAsc
+%\begin{definition}
+%\cs{TeXOSQueryWalkNameAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or in reverse order:
+%\DescribeMacro\TeXOSQueryWalkNameDes
+%\begin{definition}
+%\cs{TeXOSQueryWalkNameDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%To sort according to path name (case-insensitive):
+%\DescribeMacro\TeXOSQueryWalkNameIgnoreCaseAsc
+%\begin{definition}
+%\cs{TeXOSQueryWalkNameIgnoreCaseAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or in reverse order:
+%\DescribeMacro\TeXOSQueryWalkNameIgnoreCaseDes
+%\begin{definition}
+%\cs{TeXOSQueryWalkNameIgnoreCaseDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%To sort according to file extension:
+%\DescribeMacro\TeXOSQueryWalkExtAsc
+%\begin{definition}
+%\cs{TeXOSQueryWalkExtAsc}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%or in reverse order:
+%\DescribeMacro\TeXOSQueryWalkExtDes
+%\begin{definition}
+%\cs{TeXOSQueryWalkExtDes}\marg{cs}\marg{sep}\marg{regex}\marg{dir}
+%\end{definition}
+%
+%\setcounter{secnumdepth}{3}
+%\StopEventually{\clearpage\printabbreviations
+%\clearpage\phantomsection
 %\addcontentsline{toc}{section}{Change History}%
 %\PrintChanges
-%\addcontentsline{toc}{section}{\indexname}%
 %\PrintIndex
 %}
 %
@@ -544,14 +2573,91 @@
 %    \end{macrocode}
 % Check if already loaded.
 %    \begin{macrocode}
-\ifx\TeXOSQuery\undefined
-\else
+\ifx\TeXOSQuery\undefined \else
   \@texosquery at restore@at
   \expandafter\endinput
 \fi
 %    \end{macrocode}
+% Version info.
+%    \begin{macrocode}
+\expandafter\def\csname ver at texosquery.tex\endcsname{2017/03/23 v1.2 (NLCT)}
+%    \end{macrocode}
+%
+%\begin{macro}{\@texosquery at warn}
+%\changes{1.2}{2017-03-23}{added check for tracklang's warning command}
+%Generate warning message. Use \sty{tracklang}'s warning if
+%available (so that the warnings can be disabled for both packages
+%at the same time).
+%    \begin{macrocode}
+\ifx\@tracklang at pkgwarn\undefined
+  \ifx\PackageWarning\undefined
+    \def\@texosquery at warn#1{%
+      {%
+        \newlinechar=`\^^J
+        \def\MessageBreak{^^J}%
+        \message{^^Jtexosquery Warning: #1 on line \the\inputlineno.^^J}%
+      }%
+    }
+  \else
+    \def\@texosquery at warn#1{%
+      \PackageWarning{texosquery}{#1}%
+    }
+  \fi
+\else
+  \def\@texosquery at warn#1{%
+    \@tracklang at pkgwarn{texosquery}{#1}%
+  }
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at err}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\PackageError\undefined
+  \def\@texosquery at err#1#2{%
+    \errhelp{#2}%
+    \errmessage{texosquery: #1}}
+\else
+  \def\@texosquery at err#1#2{\PackageError{texosquery}{#1}{#2}}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at ifundef}
+%This is defined in the same way as \sty{tracklang}'s
+%\cs{@tracklang at ifundef}. (Can't assume \sty{tracklang} has been
+%loaded.)
+%    \begin{macrocode}
+\long\def\@texosquery at ifundef#1#2#3{%
+  \ifcsname#1\endcsname
+    \expandafter\ifx\csname #1\endcsname\relax
+      #2%
+    \else
+      #3%
+    \fi
+  \else
+    \expandafter\ifx\csname #1\endcsname\relax
+      #2%
+    \else
+      #3%
+    \fi
+  \fi
+}
+\ifx\ifcsname\undefined
+  \long\def\@texosquery at ifundef#1#2#3{%
+    \expandafter\ifx\csname #1\endcsname\relax
+      #2%
+    \else
+      #3%
+    \fi
+  }
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
 %\begin{macro}{\TeXOSInvokerName}
-%The name of the \texttt{texosquery} application.
+%The name of the \app{texosquery} application.
 %    \begin{macrocode}
 \def\TeXOSInvokerName{texosquery}
 %    \end{macrocode}
@@ -571,32 +2677,899 @@
 %
 %\begin{macro}{\ifTeXOSQueryDryRun}
 %Provide a dry-run mode.
-%\changes{1.1}{2016-07-14}{dry run mode only false by default if with
-%unrestricted mode}
+%\changes{1.1}{2016-07-14}{dry run mode only false by default if
+%used in unrestricted mode}
 %    \begin{macrocode}
-\newif\ifTeXOSQueryDryRun
-\TeXOSQueryDryRuntrue
+\newif\ifTeXOSQueryDryRun \TeXOSQueryDryRuntrue
 %    \end{macrocode}
 %\end{macro}
 %
-%If shell escape is unrestricted, automatically switch off dry-run mode.
+%\begin{macro}{\TeXOSQueryAllowRestricted}
+%\changes{1.2}{2017-03-23}{new}
+%The default behaviour only switches off the dry-run mode if the
+%shell escape is unrestricted. The configuration file may override
+%this with \cs{TeXOSQueryAllowRestricted}, which will allow
+%the dry run mode to be switched off if restricted mode is detected. 
 %    \begin{macrocode}
+\def\TeXOSQueryAllowRestricted{%
+ \def\@texosquery at allowrestricted##1##2{##1}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryDenyRestricted}
+%\changes{1.2}{2017-03-23}{new}
+%Switch it off. 
+%    \begin{macrocode}
+\def\TeXOSQueryDenyRestricted{%
+ \def\@texosquery at allowrestricted##1##2{##2}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at allowrestricted}
+%\changes{1.2}{2017-03-23}{new}
+%Initialise to prevent shell escape in restricted mode.
+%    \begin{macrocode}
+\def\@texosquery at allowrestricted#1#2{#2}%
+%    \end{macrocode}
+%\end{macro}
+%
+%Load the configuration file if it exists.
+%\changes{1.2}{2017-03-23}{added texosquery.cfg}
+%    \begin{macrocode}
+\openin0=texosquery.cfg \ifeof0\relax \else
+  \closein0\relax
+  \begingroup
+    \newlinechar=`\^^J
+    \message{^^JTeXOSQuery: reading configuration file^^J}%
+  \endgroup
+  \input texosquery.cfg
+\fi
+%    \end{macrocode}
+%Disable cfg-only commands:
+%    \begin{macrocode}
+\def\TeXOSQueryAllowRestricted{%
+  \@texosquery at warn{\string\TeXOSQueryAllowRestricted\space
+   ignored (only allowed in texosquery.cfg)}%
+}
+\def\TeXOSQueryDenyRestricted{%
+  \@texosquery at warn{\string\TeXOSQueryDenyRestricted\space
+   ignored (only allowed in texosquery.cfg)}%
+}
+%    \end{macrocode}
+%
+%If shell escape is unrestricted, automatically switch off dry-run
+%mode, unless the cfg file has allowed it.
+%    \begin{macrocode}
 \ifx\shellescape\undefined
   \ifx\pdfshellescape\undefined
   \else
     \ifnum\pdfshellescape=1\relax
       \TeXOSQueryDryRunfalse
+    \else
+      \@texosquery at allowrestricted
+      {%
+        \ifnum\pdfshellescape=2\relax
+          \TeXOSQueryDryRunfalse
+        \fi
+      }
+      {}
     \fi
   \fi
 \else
   \ifnum\shellescape=1\relax
     \TeXOSQueryDryRunfalse
+  \else
+    \@texosquery at allowrestricted
+    {%
+      \ifnum\shellescape=2\relax
+        \TeXOSQueryDryRunfalse
+      \fi
+    }
+    {}
   \fi
 \fi
 %    \end{macrocode}
 %
+%\begin{macro}{\@texosquery at edef}
+%Need to provide some protection (if available) against non-ASCII characters 
+%that have been made active by \sty{inputenc} when reading in the
+%results of the shell escape. This command may be defined before loading
+%\sty{texosquery}, otherwise it's set to \cs{protected at edef}, if
+%defined, or \cs{edef}.
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\@texosquery at edef\undefined
+  \ifx\protected at edef\undefined
+    \let\@texosquery at edef\edef
+  \else
+    \let\@texosquery at edef\protected at edef
+  \fi
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%Provide some utility commands. (Can't use \cs{@gobble} etc, as we
+%may not be using \LaTeX.)
+%\begin{macro}{\@texosquery at gobble}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at gobble#1{}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@texosquery at firstofone}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at firstofone#1{#1}
+%    \end{macrocode}
+%\end{macro}
+%
+%The results obtained from \app{texosquery} may be file names for
+%use in commands like \cs{input} or \cs{includegraphics} or they may
+%be text that needs typesetting (such as month names) or they may be
+%date-time patterns or numeric patterns or they may be PDF date-time
+%strings, which may need to have the category code of the initial
+%\qt{D} set to 12 for parsing commands that include this character
+%in the argument syntax.
+%
+%This means that we need to take special characters into account,
+%but the way they are dealt with vary according to context. For
+%example, \verb|#| needs to have the category code set to 12 if it's
+%part of a file name. If an image file is called, say,
+%\verb|test_imagefile#.png| then the following doesn't work:
+%\begin{verbatim}
+%\includegraphics{test\_imagefile\#}
+%\end{verbatim}
+%It needs to be
+%\begin{verbatim}
+%\includegraphics{test\string_imagefile\string#}
+%\end{verbatim}
+%or
+%\begin{verbatim}
+%\includegraphics{\detokenize{test_imagefile#}}
+%\end{verbatim}
+%The first two versions of \sty{texosquery} try to deal with this by
+%simply changing the category code of \verb|_| to 12 and getting
+%\app{texosquery} to replace all instances of \verb|#| with
+%\verb|\#|. This hash substitution doesn't work with the above image
+%example so version 1.2 introduced a new command that
+%\app{texosquery} could use instead of \verb|\#| that expands to
+%\verb|\string#|. This now solves the problem for file names that
+%are obtained through \app{texosquery}, but \app{texosquery} doesn't
+%solely return file names. It also returns text that needs
+%typesetting and it also returns numeric patterns, which in their
+%raw form include \verb|#| as a digit identifier.
+%
+%This means that we can't simply detokenize the result from
+%\app{texosquery}. Instead \app{texosquery} replaces problematic
+%characters with control sequences \emph{according to context}.
+%For example, \cs{texosqueryhash} is used in a file name context,
+%\cs{texosquerytexthash} is used in a textual context and
+%\cs{texosquerypatdigitnozero} in a numeric pattern context.
+%
+%These long control sequence names clutter the results when testing
+%the application directly in a terminal, so the Java code uses short
+%forms that are locally defined by \cs{TeXOSQuery} to expand to the
+%longer forms.
+%
+%\begin{macro}{\texosquerynonasciiwrap}
+%\changes{1.2}{2017-03-23}{new}
+%Allow a way to deal with non-ASCII characters returned by
+%\app{texosquery}. \cs{TeXOSQuery} locally defines \cs{twrp}
+%to this command. By default this just does its argument
+%but may be redefined. For example, if the document uses a different
+%file encoding to Java, then this command might need to be redefined
+%to perform the appropriate conversion.
+%    \begin{macrocode}
+\def\texosquerynonasciiwrap#1{#1}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerynonasciidetokwrap}
+%\changes{1.2}{2017-03-23}{new}
+%We also need to allow for non-ASCII characters in file names. In
+%this case the argument needs detokenizing. With \eTeX, we can
+%simply use \cs{detokenize} but we need to allow for plain
+%non-extended \TeX, so check for the existence of \cs{detokenize}
+%first.
+%    \begin{macrocode}
+\ifx\detokenize\undefined
+%    \end{macrocode}
+%This won't work for characters consisting of multiple octets,
+%but if users want UTF-8 support then they really need \eTeX\ at the
+%very least (but ideally \XeTeX\ or \LuaTeX).
+%    \begin{macrocode}
+  \def\texosquerynonasciidetokwrap#1{\string#1}
+\else
+  \def\texosquerynonasciidetokwrap#1{\detokenize{#1}}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%Now define commands used in \cs{TeXOSQuery} for various escaped characters.
+%The literal versions are for file names. The textual versions are
+%for use within the document text. For completeness, all the ASCII
+%punctuation characters have both a literal and textual version.
+%This helps to protect against \sty{babel} shorthands etc.
+%
+%\begin{macro}{\texosquerybackslash}
+%\changes{1.2}{2017-03-23}{new}
+%Literal backslash.
+%    \begin{macrocode}
+\edef\texosquerybackslash{\expandafter\@texosquery at gobble\string\\}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextbackslash}
+%\changes{1.2}{2017-03-23}{new}
+%Textual backslash.
+%    \begin{macrocode}
+\ifx\textbackslash\undefined
+  \def\texosquerytextbackslash{\texosquerybackslash}
+\else
+  \def\texosquerytextbackslash{\noexpand\textbackslash}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryleftbrace}
+%\changes{1.2}{2017-03-23}{new}
+%Literal left brace.
+%    \begin{macrocode}
+\edef\texosqueryleftbrace{\expandafter\@texosquery at gobble\string\{}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextleftbrace}
+%\changes{1.2}{2017-03-23}{new}
+%Textual left brace.
+%    \begin{macrocode}
+\def\texosquerytextleftbrace{\{}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryrightbrace}
+%\changes{1.2}{2017-03-23}{new}
+%Literal right brace.
+%    \begin{macrocode}
+\edef\texosqueryrightbrace{\expandafter\@texosquery at gobble\string\}}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextrightbrace}
+%\changes{1.2}{2017-03-23}{new}
+%Textual right brace.
+%    \begin{macrocode}
+\def\texosquerytextrightbrace{\}}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryhash}
+%\changes{1.2}{2017-03-23}{new}
+%Literal hash.
+%    \begin{macrocode}
+\edef\texosqueryhash{\expandafter\@texosquery at gobble\string\#}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytexthash}
+%\changes{1.2}{2017-03-23}{new}
+%Textual hash.
+%    \begin{macrocode}
+\def\texosquerytexthash{\#}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryunderscore}
+%\changes{1.2}{2017-03-23}{new}
+%Literal underscore.
+%    \begin{macrocode}
+\edef\texosqueryunderscore{\expandafter\@texosquery at gobble\string\_}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextunderscore}
+%\changes{1.2}{2017-03-23}{new}
+%Textual underscore.
+%    \begin{macrocode}
+\def\texosquerytextunderscore{\_}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerybacktick}
+%\changes{1.2}{2017-03-23}{new}
+%Literal grave.
+%    \begin{macrocode}
+\edef\texosquerybacktick{\string`}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextbacktick}
+%\changes{1.2}{2017-03-23}{new}
+%Textual open quote.
+%    \begin{macrocode}
+\def\texosquerytextbacktick{`}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryclosequote}
+%\changes{1.2}{2017-03-23}{new}
+%Literal apostrophe.
+%    \begin{macrocode}
+\edef\texosqueryclosequote{\string'}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextclosequote}
+%\changes{1.2}{2017-03-23}{new}
+%Textual apostrophe / single closing quote.
+%    \begin{macrocode}
+\def\texosquerytextclosequote{'}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerydoublequote}
+%\changes{1.2}{2017-03-23}{new}
+%Literal double-quote.
+%    \begin{macrocode}
+\edef\texosquerydoublequote{\string"}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextdoublequote}
+%\changes{1.2}{2017-03-23}{new}
+%Textual double-quote.
+%    \begin{macrocode}
+\def\texosquerytextdoublequote{"}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycolon}
+%\changes{1.2}{2017-03-23}{new}
+%Literal colon.
+%    \begin{macrocode}
+\edef\texosquerycolon{\string:}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextcolon}
+%\changes{1.2}{2017-03-23}{new}
+%Textual colon.
+%    \begin{macrocode}
+\def\texosquerytextcolon{:}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerysemicolon}
+%\changes{1.2}{2017-03-23}{new}
+%Literal semi-colon.
+%    \begin{macrocode}
+\edef\texosquerysemicolon{\string;}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextsemicolon}
+%\changes{1.2}{2017-03-23}{new}
+%Textual semi-colon.
+%    \begin{macrocode}
+\def\texosquerytextsemicolon{;}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryequals}
+%\changes{1.2}{2017-03-23}{new}
+%Literal equals.
+%    \begin{macrocode}
+\edef\texosqueryequals{\string=}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextequals}
+%\changes{1.2}{2017-03-23}{new}
+%Textual equals.
+%    \begin{macrocode}
+\def\texosquerytextequals{=}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryslash}
+%\changes{1.2}{2017-03-23}{new}
+%Literal slash.
+%    \begin{macrocode}
+\edef\texosqueryslash{\string/}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextslash}
+%\changes{1.2}{2017-03-23}{new}
+%Textual slash.
+%    \begin{macrocode}
+\def\texosquerytextslash{/}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryhyphen}
+%\changes{1.2}{2017-03-23}{new}
+%Literal hyphen.
+%    \begin{macrocode}
+\edef\texosqueryhyphen{\string-}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytexthyphen}
+%\changes{1.2}{2017-03-23}{new}
+%Textual hyphen.
+%    \begin{macrocode}
+\def\texosquerytexthyphen{-}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryplus}
+%\changes{1.2}{2017-03-23}{new}
+%Literal plus.
+%    \begin{macrocode}
+\edef\texosqueryplus{\string+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextplus}
+%\changes{1.2}{2017-03-23}{new}
+%Textual plus.
+%    \begin{macrocode}
+\def\texosquerytextplus{+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryperiod}
+%\changes{1.2}{2017-03-23}{new}
+%Literal period.
+%    \begin{macrocode}
+\edef\texosqueryperiod{\string.}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextperiod}
+%\changes{1.2}{2017-03-23}{new}
+%Textual period.
+%    \begin{macrocode}
+\def\texosquerytextperiod{.}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycomma}
+%\changes{1.2}{2017-03-23}{new}
+%Literal comma.
+%    \begin{macrocode}
+\edef\texosquerycomma{\string,}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextcomma}
+%\changes{1.2}{2017-03-23}{new}
+%Textual comma.
+%    \begin{macrocode}
+\def\texosquerytextcomma{,}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryopenparen}
+%\changes{1.2}{2017-03-23}{new}
+%Literal open bracket.
+%    \begin{macrocode}
+\edef\texosqueryopenparen{\string(}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextopenparen}
+%\changes{1.2}{2017-03-23}{new}
+%Textual open bracket.
+%    \begin{macrocode}
+\def\texosquerytextopenparen{(}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycloseparen}
+%\changes{1.2}{2017-03-23}{new}
+%Literal close bracket.
+%    \begin{macrocode}
+\edef\texosquerycloseparen{\string)}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextcloseparen}
+%\changes{1.2}{2017-03-23}{new}
+%Textual close bracket.
+%    \begin{macrocode}
+\def\texosquerytextcloseparen{)}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryopensq}
+%\changes{1.2}{2017-03-23}{new}
+%Literal open square bracket.
+%    \begin{macrocode}
+\edef\texosqueryopensq{\string[}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextopensq}
+%\changes{1.2}{2017-03-23}{new}
+%Textual open square bracket.
+%    \begin{macrocode}
+\def\texosquerytextopensq{[}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryclosesq}
+%\changes{1.2}{2017-03-23}{new}
+%Literal close square bracket.
+%    \begin{macrocode}
+\edef\texosqueryclosesq{\string]}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextclosesq}
+%\changes{1.2}{2017-03-23}{new}
+%Textual close square bracket.
+%    \begin{macrocode}
+\def\texosquerytextclosesq{]}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryasterisk}
+%\changes{1.2}{2017-03-23}{new}
+%Literal asterisk.
+%    \begin{macrocode}
+\edef\texosqueryasterisk{\string*}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextasterisk}
+%\changes{1.2}{2017-03-23}{new}
+%Textual asterisk.
+%    \begin{macrocode}
+\def\texosquerytextasterisk{*}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryatchar}
+%\changes{1.2}{2017-03-23}{new}
+%Literal at character.
+%    \begin{macrocode}
+\edef\texosqueryatchar{\string @}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextatchar}
+%\changes{1.2}{2017-03-23}{new}
+%Textual at character.
+%    \begin{macrocode}
+\def\texosquerytextatchar{@}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerybar}
+%\changes{1.2}{2017-03-23}{new}
+%Literal bar.
+%    \begin{macrocode}
+\edef\texosquerybar{\string|}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextbar}
+%\changes{1.2}{2017-03-23}{new}
+%Textual bar.
+%    \begin{macrocode}
+\ifx\undefined\textbar
+  \def\texosquerytextbar{|}
+\else
+  \def\texosquerytextbar{\ifmmode|\else\textbar\fi}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerylessthan}
+%\changes{1.2}{2017-03-23}{new}
+%Literal less than.
+%    \begin{macrocode}
+\edef\texosquerylessthan{\string<}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextlessthan}
+%\changes{1.2}{2017-03-23}{new}
+%Textual less than.
+%    \begin{macrocode}
+\ifx\undefined\textless
+  \def\texosquerytextlessthan{<}
+\else
+  \def\texosquerytextlessthan{\ifmmode<\else\textless\fi}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerygreaterthan}
+%\changes{1.2}{2017-03-23}{new}
+%Literal greater than.
+%    \begin{macrocode}
+\edef\texosquerygreaterthan{\string>}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextgreaterthan}
+%\changes{1.2}{2017-03-23}{new}
+%Textual greater than.
+%    \begin{macrocode}
+\ifx\undefined\textgreater
+  \def\texosquerytextgreaterthan{>}
+\else
+  \def\texosquerytextgreaterthan{\ifmmode<\else\textgreater\fi}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytilde}
+%\changes{1.2}{2017-03-23}{new}
+%Literal tilde.
+%    \begin{macrocode}
+\edef\texosquerytilde{\string~}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytexttilde}
+%\changes{1.2}{2017-03-23}{new}
+%Textual tilde.
+%    \begin{macrocode}
+\ifx\textasciitilde\undefined
+  \def\texosquerytexttilde{\string~}
+\else
+  \def\texosquerytexttilde{\textasciitilde}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycircum}
+%\changes{1.2}{2017-03-23}{new}
+%Literal circumflex.
+%    \begin{macrocode}
+\edef\texosquerycircum{\string^}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextcircum}
+%\changes{1.2}{2017-03-23}{new}
+%Textual circumflex.
+%    \begin{macrocode}
+\ifx\textasciicircum\undefined
+  \def\texosquerytextcircum{\string^}
+\else
+  \def\texosquerytextcircum{\textasciicircum}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryampersand}
+%\changes{1.2}{2017-03-23}{new}
+%Literal ampersand.
+%    \begin{macrocode}
+\edef\texosqueryampersand{\string&}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextampersand}
+%\changes{1.2}{2017-03-23}{new}
+%Textual ampersand.
+%    \begin{macrocode}
+\def\texosquerytextampersand{\&}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerydollar}
+%\changes{1.2}{2017-03-23}{new}
+%Literal dollar. (This could just be defined as \verb|\string$|, but
+%that plays havoc with the syntax highlighting!)
+%    \begin{macrocode}
+\edef\texosquerydollar{\expandafter\@texosquery at gobble\string\$}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextdollar}
+%\changes{1.2}{2017-03-23}{new}
+%Textual dollar.
+%    \begin{macrocode}
+\def\texosquerytextdollar{\$}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerypercent}
+%\changes{1.2}{2017-03-23}{new}
+%Literal percent.
+%    \begin{macrocode}
+\edef\texosquerypercent{\expandafter\@texosquery at gobble\string\%}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextpercent}
+%\changes{1.2}{2017-03-23}{new}
+%Textual percent.
+%    \begin{macrocode}
+\def\texosquerytextpercent{\%}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryexclam}
+%\changes{1.2}{2017-03-23}{new}
+%Literal exclamation.
+%    \begin{macrocode}
+\edef\texosqueryexclam{\string!}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextexclam}
+%\changes{1.2}{2017-03-23}{new}
+%Textual exclamation.
+%    \begin{macrocode}
+\def\texosquerytextexclam{!}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryquestion}
+%\changes{1.2}{2017-03-23}{new}
+%Literal question mark.
+%    \begin{macrocode}
+\edef\texosqueryquestion{\string?}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextquestion}
+%\changes{1.2}{2017-03-23}{new}
+%Textual question mark.
+%    \begin{macrocode}
+\def\texosquerytextquestion{?}
+%    \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\texosqueryliteralspace}
+%\changes{1.2}{2017-03-23}{new}
+%Literal space.
+%    \begin{macrocode}
+\edef\texosqueryliteralspace{\expandafter\string\space}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytextspace}
+%\changes{1.2}{2017-03-23}{new}
+%Textual space. (Don't allow it to expand while it's being fetched
+%from \cs{texosquery} just in case it disappears.)
+%    \begin{macrocode}
+\def\texosquerytextspace{\noexpand\space}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at D}
+%\changes{1.2}{2017-03-23}{new}
+%The \verb|D| identifier in PDF date-time formats need to have
+%category code 12. This is only used by methods that return results
+%in the form:
+%
+%\verb|D:|\meta{YYYY}\meta{MM}\marg{DD}\meta{HH}\meta{mm}\meta{ss}\meta{TZh}\verb|'|\meta{TZm}\verb|'|
+%    \begin{macrocode}
+\edef\@texosquery at D{\string D}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at enableshortcs}
+%\changes{1.2}{2017-03-23}{new}
+%\hypertarget{enableshortcs}{Enable shortcut commands.}
+%    \begin{macrocode}
+\def\@texosquery at enableshortcs{%
+%    \end{macrocode}
+%Thesre are for the date-time and numeric patterns.
+%    \begin{macrocode}
+     \def\patdtf{\noexpand\texosquerydtf}%
+     \def\patpmnumfmt{\noexpand\texosquerypatplusminus}%
+     \def\patnumfmt{\noexpand\texosquerypatnum}%
+     \def\patsinumfmt{\noexpand\texosquerypatsinum}%
+     \def\patdecfmt{\noexpand\texosquerypatdec}%
+     \def\patpcur{\noexpand\texosquerypatprefixcurrency}%
+     \def\patpicur{\noexpand\texosquerypatprefixicurrency}%
+     \def\patscur{\noexpand\texosquerypatsuffixcurrency}%
+     \def\patsicur{\noexpand\texosquerypatsuffixicurrency}%
+     \def\patstr{\noexpand\texosquerypatstr}%
+     \def\patapo{\noexpand\texosquerypatquote}%
+     \def\patdgt{\noexpand\texosquerypatdigit}%
+     \def\patdgtnz{\noexpand\texosquerypatdigitnozero}%
+     \def\patmsg{\noexpand\texosquerypatminus}%
+     \def\patngp{\noexpand\texosquerypatgroupsep}%
+     \def\patppct{\noexpand\texosquerypatprefixpercent}%
+     \def\patspct{\noexpand\texosquerypatsuffixpercent}%
+     \def\patppml{\noexpand\texosquerypatprefixpermill}%
+     \def\patspml{\noexpand\texosquerypatsuffixpermill}%
+%    \end{macrocode}
+%Hook to adjust the processing of non-ASCII characters.
+%    \begin{macrocode}
+     \def\twrp{\texosquerynonasciiwrap}%
+     \def\fwrp{\texosquerynonasciidetokwrap}%
+%    \end{macrocode}
+%Locally redefine some more commands that may occur in 
+%\app{texosquery}'s return value (via the \texttt{escapeSpChars}
+%method in \file{TeXOSQuery.java}). The \texttt{t} prefix indicates
+%textual commands and the \texttt{f} prefix indicates literal
+%characters, for example, in file names.
+%    \begin{macrocode}
+     \let\fbks\texosquerybackslash
+     \let\tbks\texosquerytextbackslash
+     \let\flbr\texosqueryleftbrace
+     \let\tlbr\texosquerytextleftbrace
+     \let\frbr\texosqueryrightbrace
+     \let\trbr\texosquerytextrightbrace
+     \let\fhsh\texosqueryhash
+     \let\thsh\texosquerytexthash
+     \let\fusc\texosqueryunderscore
+     \let\tusc\texosquerytextunderscore
+     \let\fgrv\texosquerybacktick
+     \let\tgrv\texosquerytextbacktick
+     \let\fapo\texosqueryclosequote
+     \let\tapo\texosquerytextclosequote
+     \let\fdqt\texosquerydoublequote
+     \let\tdqt\texosquerytextdoublequote
+     \let\fspc\texosqueryliteralspace
+     \let\tspc\texosquerytextspace
+     \let\fcln\texosquerycolon
+     \let\tcln\texosquerytextcolon
+     \let\fscl\texosquerysemicolon
+     \let\tscl\texosquerytextsemicolon
+     \let\feql\texosqueryequals
+     \let\teql\texosquerytextequals
+     \let\fhyn\texosqueryhyphen
+     \let\thyn\texosquerytexthyphen
+     \let\fpls\texosqueryplus
+     \let\tpls\texosquerytextplus
+     \let\ftld\texosquerytilde
+     \let\ttld\texosquerytexttilde
+     \let\fcir\texosquerycircum
+     \let\tcir\texosquerytextcircum
+     \let\famp\texosqueryampersand
+     \let\tamp\texosquerytextampersand
+     \let\fslh\texosqueryslash
+     \let\tslh\texosquerytextslash
+     \let\fpct\texosquerypercent
+     \let\tpct\texosquerytextpercent
+     \let\fexc\texosqueryexclam
+     \let\texc\texosquerytextexclam
+     \let\fque\texosqueryquestion
+     \let\tque\texosquerytextquestion
+     \let\fles\texosquerylessthan
+     \let\tles\texosquerytextlessthan
+     \let\fgre\texosquerygreaterthan
+     \let\tgre\texosquerytextgreaterthan
+     \let\fdol\texosquerydollar
+     \let\tdol\texosquerytextdollar
+     \let\fdot\texosqueryperiod
+     \let\tdot\texosquerytextperiod
+     \let\fcom\texosquerycomma
+     \let\tcom\texosquerytextcomma
+     \let\fopb\texosqueryopenparen
+     \let\topb\texosquerytextopenparen
+     \let\fclb\texosquerycloseparen
+     \let\tclb\texosquerytextcloseparen
+     \let\fosb\texosqueryopensq
+     \let\tosb\texosquerytextopensq
+     \let\fcsb\texosqueryclosesq
+     \let\tcsb\texosquerytextclosesq
+     \let\fast\texosqueryasterisk
+     \let\tast\texosquerytextasterisk
+     \let\fatc\texosqueryatchar
+     \let\tatc\texosquerytextatchar
+     \let\pdfd\@texosquery at D
+}
+%    \end{macrocode}
+%\end{macro}
+%
 %\begin{macro}{\TeXOSQuery}
-%Use \texttt{texosquery} with the option given in the second
+%Use \app{texosquery} with the option given in the second
 %argument and store the result in control sequence given in the
 %first argument.
 %    \begin{macrocode}
@@ -611,11 +3584,16 @@
     \begingroup
     \endlinechar=-1\relax
 %    \end{macrocode}
-%Just in case the result contains any awkward characters that have
-%some special meaning to \TeX. (Can't really protect against hash,
-%backslash or curly braces, but they're unlikely to occur unless
-%the user has a very wacky and inappropriate file naming scheme.)
+%Locally redefine short commands used by \app{texosquery}
 %    \begin{macrocode}
+    \@texosquery at enableshortcs
+%    \end{macrocode}
+%Change the category code of some potentially awkward characters. 
+%(This should no longer be an issue with the new commands that 
+%are now used in the returned text, but \app{texosquery} might be run with the 
+%backward compatibility mode on, so this is
+%still needed just in case.)
+%    \begin{macrocode}
     \catcode`\-=12\relax
     \catcode`\_=12\relax
     \catcode`\^=12\relax
@@ -622,20 +3600,376 @@
     \catcode`\~=12\relax
     \catcode`\$=12\relax
     \catcode`\&=12\relax
-    \catcode`\"=12\relax
-    \catcode`\'=12\relax
     \catcode`\.=12\relax
     \catcode`\/=12\relax
     \catcode`\:=12\relax
+    \catcode`\"=12\relax
+    \catcode`\'=12\relax
     \catcode`\;=12\relax
     \catcode`\%=12\relax
     \everyeof{\noexpand}\relax
-    \edef\x{\endgroup\def\noexpand#1{\TeXOSQueryInvoker{#2}}}\x
+    \@texosquery at edef\x{\endgroup\def\noexpand#1{\TeXOSQueryInvoker{#2}}}\x
   \fi
 }
 %    \end{macrocode}
 %\end{macro}
 %
+%\subsubsection{Currency}
+%The \meta{\TeX\ currency} element of \longarg{numeric} and
+%\longarg{locale-data} identifies the currency symbol using
+%\begin{definition}
+%\cs{texosquerycurrency}\marg{label}
+%\end{definition}
+%which simply expands to the appropriate command.
+%\begin{macro}{\texosquerycurrency}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrency#1{%
+ \expandafter\noexpand\csname texosquerycurrency#1\endcsname
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%Provide the currency commands that may be returned
+%\app{texosquery} (on expansion of \cs{texosquerycurrency}).
+%Most of these will need redefining as there's no appropriate
+%generic code to use as a default.
+%The \sty{fontawesome} package has the most support for currency
+%symbols, so these are checked first.
+%\begin{macro}{\texosquerycurrencydollar}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\faDollar\undefined
+  \def\texosquerycurrencydollar{\$}
+\else
+  \def\texosquerycurrencydollar{\faDollar}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencycent}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\textcent\undefined
+  \def\texosquerycurrencycent{cent}
+\else
+  \def\texosquerycurrencycent{\textcent}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencypound}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\faGbp\undefined
+  \ifx\pounds\undefined
+    \def\texosquerycurrencypound{pound}
+  \else
+    \def\texosquerycurrencypound{\pounds}
+  \fi
+\else
+  \def\texosquerycurrencypound{\faGbp}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencysign}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\textcurrency\undefined
+  \def\texosquerycurrencysign{currency-sign}
+\else
+  \def\texosquerycurrencysign{\textcurrency}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyyen}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\faYen\undefined
+  \ifx\textyen\undefined
+    \def\texosquerycurrencyyen{yen}
+  \else
+    \def\texosquerycurrencyyen{\textyen}
+  \fi
+\else
+  \def\texosquerycurrencyyen{\faYen}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyecu}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencyecu{ecu}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencycolon}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencycolon{colon}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencycruzeiro}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencycruzeiro{cruzeiro}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyfranc}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencyfranc{franc}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencylira}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\textlira\undefined
+  \def\texosquerycurrencylira{lira}
+\else
+  \def\texosquerycurrencylira{\textlira}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencymill}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencymill{mill}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencynaira}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\textnaira\undefined
+  \def\texosquerycurrencynaira{naira}
+\else
+  \def\texosquerycurrencynaira{\textnaira}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencypeseta}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencypeseta{peseta}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyrupee}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\faRupee\undefined
+  \def\texosquerycurrencyrupee{rupee}
+\else
+  \def\texosquerycurrencyrupee{\faRupee}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencywon}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\faWon\undefined
+  \ifx\textwon\undefined
+    \def\texosquerycurrencywon{won}
+  \else
+    \def\texosquerycurrencywon{\textwon}
+  \fi
+\else
+  \def\texosquerycurrencywon{\faWon}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencynewsheqel}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\faSheqel\undefined
+  \def\texosquerycurrencynewsheqel{newsheqel}
+\else
+  \def\texosquerycurrencynewsheqel{\faSheqel}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencydong}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\textdong\undefined
+  \def\texosquerycurrencydong{dong}
+\else
+  \def\texosquerycurrencydong{\textdong}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyeuro}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\faEuro\undefined
+  \ifx\texteuro\undefined
+    \ifx\euro\undefined
+      \def\texosquerycurrencyeuro{euro}
+    \else
+      \def\texosquerycurrencyeuro{\euro}
+    \fi
+  \else
+    \def\texosquerycurrencyeuro{\texteuro}
+  \fi
+\else
+  \def\texosquerycurrencyeuro{\faEuro}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencykip}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencykip{kip}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencytugrik}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencytugrik{tugrik}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencydrachma}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencydrachma{drachma}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencygermanpenny}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencygermanpenny{german-penny}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencypeso}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\textpeso\undefined
+  \def\texosquerycurrencypeso{peso}
+\else
+  \def\texosquerycurrencypeso{\textpeso}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyguarani}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\textguarani\undefined
+  \def\texosquerycurrencyguarani{guarani}
+\else
+  \def\texosquerycurrencyguarani{\textguarani}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyaustral}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencyaustral{austral}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyhryvnia}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencyhryvnia{hryvnia}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencycedi}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\textcolonmonetary\undefined
+  \def\texosquerycurrencycedi{cedi}
+\else
+  \def\texosquerycurrencycedi{\textcolonmonetary}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencylivretournois}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencylivretournois{livre-tournois}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyspesmilo}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencyspesmilo{spesmilo}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencytenge}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencytenge{tenge}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyrupee}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencyrupee{rupee}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyturkishlira}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\faTurkishLira\undefined
+  \def\texosquerycurrencyturkishlira{turkish-lira}
+\else
+  \def\texosquerycurrencyturkishlira{\faTurkishLira}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencynordicmark}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencynordicmark{nordic-mark}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencymanat}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerycurrencymanat{manat}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerycurrencyruble}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\ifx\faRuble\undefined
+  \def\texosquerycurrencyruble{ruble}
+\else
+  \def\texosquerycurrencyruble{\faRuble}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\subsubsection{Shortcut Commands}
 %Now for some convenient shortcuts so the user doesn't have to
 %remember the command line options. \cs{string} is used in
 %case the hyphen character has been made active.
@@ -647,6 +3981,37 @@
 %    \end{macrocode}
 %\end{macro}
 %
+%\begin{macro}{\TeXOSQueryLangTag}
+%Query the language tag and store the result in the control sequence
+%provided in the argument.
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\TeXOSQueryLangTag#1{\TeXOSQuery{#1}{\string-b}}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryNumeric}
+%Query the numeric settings for the locale given in the second
+%argument and store the result in the control sequence
+%provided in the argument. Leave the second argument empty for the
+%default locale.
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\TeXOSQueryNumeric#1#2{\TeXOSQuery{#1}{\string-N #2}}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryLocaleData}
+%Query the data for the locale given in the second
+%argument and store the result in the control sequence
+%provided in the argument. Leave the second argument empty for the
+%default locale.
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\TeXOSQueryLocaleData#1#2{\TeXOSQuery{#1}{\string-D #2}}
+%    \end{macrocode}
+%\end{macro}
+%
 %\begin{macro}{\TeXOSQueryCwd}
 %Query the current working directory.
 %    \begin{macrocode}
@@ -689,6 +4054,27 @@
 %    \end{macrocode}
 %\end{macro}
 %
+%\begin{macro}{\TeXOSQueryDateTime}
+%\changes{1.2}{2017-03-23}{new}
+%Query the current date and time.
+%    \begin{macrocode}
+\def\TeXOSQueryDateTime#1{%
+  \TeXOSQuery{#1}{\string-M}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryTimeZones}
+%\changes{1.2}{2017-03-23}{new}
+%Query the current time zone mappings. Leave the second argument
+%empty for the default locale.
+%    \begin{macrocode}
+\def\TeXOSQueryTimeZones#1#2{%
+  \TeXOSQuery{#1}{\string-Z #2}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
 %\begin{macro}{\TeXOSQueryNow}
 %\changes{1.1}{2016-07-14}{changed catcode of D to 12}
 %Query the current time stamp.
@@ -695,12 +4081,9 @@
 %    \begin{macrocode}
 \def\TeXOSQueryNow#1{%
 %    \end{macrocode}
-% The \texttt{D} needs category code 12. (Don't need to worry about
-% \texttt{Z} as \texttt{texosquery.jar} uses \texttt{+00'00'} for
-% UTC+0.) This change can't be done with the other catcode changes
-% in \cs{TeXOSQuery}, as this is only appropriate for the PDF dates.
-% Save and restore the catcode rather than fiddle around with
-% scoping.
+% The \texttt{D} needs category code 12 just in case
+% \app{texosquery} is running in a backward compatibility mode that
+% doesn't use \cs{pdfd}. 
 %    \begin{macrocode}
   \edef\@texosquery at restore@D{%
     \noexpand\catcode`\noexpand\D=\the\catcode`\D\relax}%
@@ -733,6 +4116,11 @@
 %Query the time stamp of the file given in the second argument.
 %    \begin{macrocode}
 \def\TeXOSQueryFileDate#1#2{%
+%    \end{macrocode}
+% The \texttt{D} needs category code 12 just in case
+% \app{texosquery} is running in a backward compatibility mode that
+% doesn't use \cs{pdfd}. 
+%    \begin{macrocode}
   \edef\@texosquery at restore@D{%
     \noexpand\catcode`\noexpand\D=\the\catcode`\D\relax}%
   \catcode`\D=12\relax
@@ -750,16 +4138,357 @@
 %    \end{macrocode}
 %\end{macro}
 %
+%\begin{macro}{\@texosquery at filelist}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at filelist#1#2#3#4#5{\TeXOSQuery{#1}{%
+ \string#2 \string'#3\string' 
+ \string'\texosquerystripquotes{#4}\string' #5}}
+%    \end{macrocode}
+%\end{macro}
+%
 %\begin{macro}{\TeXOSQueryFileList}
 %List all files in the directory given in the third argument,
 %separated by the second argument.
 %    \begin{macrocode}
-\def\TeXOSQueryFileList#1#2#3{\TeXOSQuery{#1}{%
- \string-i \string'#2\string' 
- \string'\texosquerystripquotes{#3}\string'}}
+\def\TeXOSQueryFileList#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{}%
+}
 %    \end{macrocode}
 %\end{macro}
 %
+%\begin{macro}{\TeXOSQueryFileListDateAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by date.
+%    \begin{macrocode}
+\def\TeXOSQueryFileListDateAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{date}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFileListDateDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by date in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFileListDateDes#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{date\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFileListSizeAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by size.
+%    \begin{macrocode}
+\def\TeXOSQueryFileListSizeAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{size}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFileListSizeDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by size in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFileListSizeDes#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{size\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFileListNameAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by name.
+%    \begin{macrocode}
+\def\TeXOSQueryFileListNameAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{name}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFileListNameDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFileListNameDes#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{name\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFileListNameIgnoreCaseAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by case-insensitive name.
+%    \begin{macrocode}
+\def\TeXOSQueryFileListNameIgnoreCaseAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{iname}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFileListNameIgnoreCaseDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by case-insensitive name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFileListNameIgnoreCaseDes#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{iname\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFileListExtAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by extension.
+%    \begin{macrocode}
+\def\TeXOSQueryFileListExtAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{ext}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFileListExtDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by extension in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFileListExtDes#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{ext\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileList}
+%List all regular files.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileList#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirList}
+%List all sub-directories.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirList#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileListDateAsc}
+%\changes{1.2}{2017-03-23}{new}
+%List all regular files sorted by date.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileListDateAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{date}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirListDateAsc}
+%\changes{1.2}{2017-03-23}{new}
+%List all sub-directories sorted by date.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirListDateAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{date}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileListDateDes}
+%\changes{1.2}{2017-03-23}{new}
+%List all regular files sorted by date in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileListDateDes#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{date\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirListDateDes}
+%\changes{1.2}{2017-03-23}{new}
+%List all sub-directories sorted by date in descending order.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirListDateDes#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{date\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileListSizeAsc}
+%\changes{1.2}{2017-03-23}{new}
+%List all regular files sorted by size.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileListSizeAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{size}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirListSizeAsc}
+%\changes{1.2}{2017-03-23}{new}
+%List all sub-directories sorted by size.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirListSizeAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{size}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileListSizeDes}
+%\changes{1.2}{2017-03-23}{new}
+%List all regular files sorted by size in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileListSizeDes#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{size\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirListSizeDes}
+%\changes{1.2}{2017-03-23}{new}
+%List all sub-directories sorted by size in descending order.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirListSizeDes#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{size\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileListNameAsc}
+%\changes{1.2}{2017-03-23}{new}
+%List all regular files sorted by file name.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileListNameAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{name}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirListNameAsc}
+%\changes{1.2}{2017-03-23}{new}
+%List all sub-directories sorted by file name.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirListNameAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{name}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileListNameDes}
+%\changes{1.2}{2017-03-23}{new}
+%List all regular files sorted by file name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileListNameDes#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{name\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirListNameDes}
+%\changes{1.2}{2017-03-23}{new}
+%List all sub-directories sorted by name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirListNameDes#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{name\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileListNameIgnoreCaseAsc}
+%\changes{1.2}{2017-03-23}{new}
+%List all regular files sorted by file case-insensitive name.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileListNameIgnoreCaseAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{iname}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirListNameIgnoreCaseAsc}
+%\changes{1.2}{2017-03-23}{new}
+%List all sub-directories sorted by file case-insensitive name.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirListNameIgnoreCaseAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{iname}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileListNameIgnoreCaseDes}
+%\changes{1.2}{2017-03-23}{new}
+%List all regular files sorted by file case-insensitive name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileListNameIgnoreCaseDes#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{iname\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirListNameIgnoreCaseDes}
+%\changes{1.2}{2017-03-23}{new}
+%List all sub-directories sorted by case-insensitive name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirListNameIgnoreCaseDes#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{iname\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileListExtAsc}
+%\changes{1.2}{2017-03-23}{new}
+%List all regular files sorted by file extension.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileListExtAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{ext}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirListExtAsc}
+%\changes{1.2}{2017-03-23}{new}
+%List all sub-directories sorted by file extension.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirListExtAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{ext}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryRegularFileListExtDes}
+%\changes{1.2}{2017-03-23}{new}
+%List all regular files sorted by file extension in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryRegularFileListExtDes#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{ext\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQuerySubDirListExtDes}
+%\changes{1.2}{2017-03-23}{new}
+%List all sub-directories sorted by extension in descending order.
+%    \begin{macrocode}
+\def\TeXOSQuerySubDirListExtDes#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{ext\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\@texosquery at filterfilelist}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at filterfilelist#1#2#3#4#5#6{%
+ \TeXOSQuery{#1}%
+ {%
+   \string#2 \string'#3\string' \string'#4\string'
+   \string'\texosquerystripquotes{#5}\string' #6%
+ }%
+}
+%    \end{macrocode}
+%\end{macro}
+%
 %\begin{macro}{\TeXOSQueryFilterFileList}
 %Filtered list files in the directory given in the fourth argument,
 %separated by the second argument. The third argument is the regular
@@ -766,12 +4495,458 @@
 %expression used to filter the list. \emph{Take care of backslashes
 %in the regular expression!}
 %    \begin{macrocode}
-\def\TeXOSQueryFilterFileList#1#2#3#4{\TeXOSQuery{#1}{%
- \string-f \string'#2\string' \string'#3\string' 
- \string'\texosquerystripquotes{#4}\string'}}
+\def\TeXOSQueryFilterFileList#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{}%
+}
 %    \end{macrocode}
 %\end{macro}
 %
+%\begin{macro}{\TeXOSQueryFilterFileListDateAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by date.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterFileListDateAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{date}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterFileListDateDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by date in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterFileListDateDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{date\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterFileListSizeAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by size.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterFileListSizeAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{size}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterFileListSizeDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by size in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterFileListSizeDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{size\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterFileListNameAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file name.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterFileListNameAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{name}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterFileListNameDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterFileListNameDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{name\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterFileListNameIgnoreCaseAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file name (case-insensitive).
+%    \begin{macrocode}
+\def\TeXOSQueryFilterFileListNameIgnoreCaseAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{iname}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterFileListNameIgnoreCaseDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by name in descending order (case-insensitive).
+%    \begin{macrocode}
+\def\TeXOSQueryFilterFileListNameIgnoreCaseDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{iname\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterFileListExtAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file extension.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterFileListExtAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{ext}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterFileListExtDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by extension in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterFileListExtDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{ext\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileList}
+%Filtered list or regular files.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileList#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirList}
+%Filtered list of sub-directories.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirList#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirListDateAsc}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of sub-directories by file date.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirListDateAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{date}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileListDateAsc}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of regular files by file date.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileListDateAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{date}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirListDateDes}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of sub-directories by file date in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirListDateDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{date\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileListDateDes}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of regular files by file date in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileListDateDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{date\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirListSizeAsc}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of sub-directories by file size.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirListSizeAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{size}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileListSizeAsc}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of regular files by file size.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileListSizeAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{size}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirListSizeDes}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of sub-directories by file size in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirListSizeDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{size\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileListSizeDes}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of regular files by file size in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileListSizeDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{size\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirListNameAsc}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of sub-directories by file name.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirListNameAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{name}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileListNameAsc}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of regular files by file name.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileListNameAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{name}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirListNameDes}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of sub-directories by file name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirListNameDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{name\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileListNameDes}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of regular files by file name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileListNameDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{name\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirListNameIgnoreCaseAsc}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of sub-directories by case-insensitive file name.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirListNameIgnoreCaseAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{iname}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileListNameIgnoreCaseAsc}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of regular files by case-insensitive file name.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileListNameIgnoreCaseAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{iname}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirListNameIgnoreCaseDes}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of sub-directories by case-insensitive file name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirListNameIgnoreCaseDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{iname\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileListNameIgnoreCaseDes}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of regular files by case-insensitive file name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileListNameIgnoreCaseDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{iname\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirListExtAsc}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of sub-directories by file extension. (Added for
+%completeness as directories don't tend to have extensions.)
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirListExtAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{ext}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileListExtAsc}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of regular files by file extension.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileListExtAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{ext}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterSubDirListExtDes}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of sub-directories by file extension in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterSubDirListExtDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{ext\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryFilterRegularFileListExtDes}
+%\changes{1.2}{2017-03-23}{new}
+%Filtered sort of regular files by file extension in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryFilterRegularFileListExtDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{ext\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at walk}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at walk#1#2#3#4#5{%
+ \TeXOSQuery{#1}%
+ {%
+   \string-w \string'#2\string' \string'#3\string'
+   \string'\texosquerystripquotes{#4}\string' #5%
+ }%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalk}
+%\changes{1.2}{2017-03-23}{new}
+%Recursive filtered listing of regular files.
+%    \begin{macrocode}
+\def\TeXOSQueryWalk#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalkDateAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by date.
+%    \begin{macrocode}
+\def\TeXOSQueryWalkDateAsc#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{date}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalkDateDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by date in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryWalkDateDes#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{date\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalkSizeAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file size.
+%    \begin{macrocode}
+\def\TeXOSQueryWalkSizeAsc#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{size}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalkSizeDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file size in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryWalkSizeDes#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{size\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalkNameAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file name.
+%    \begin{macrocode}
+\def\TeXOSQueryWalkNameAsc#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{name}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalkNameDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file name in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryWalkNameDes#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{name\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalkNameIgnoreCaseAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file name (case-insensitive).
+%    \begin{macrocode}
+\def\TeXOSQueryWalkNameIgnoreCaseAsc#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{iname}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalkNameIgnoreCaseDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file name (case-insensitive) in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryWalkNameIgnoreCaseDes#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{iname\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalkExtAsc}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file extension.
+%    \begin{macrocode}
+\def\TeXOSQueryWalkExtAsc#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{ext}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\TeXOSQueryWalkExtDes}
+%\changes{1.2}{2017-03-23}{new}
+%As above, but sort by file extension in descending order.
+%    \begin{macrocode}
+\def\TeXOSQueryWalkExtDes#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{ext\string-des}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
 %\begin{macro}{\TeXOSQueryFileURI}
 %Get the URI of the file given in the second argument.
 %    \begin{macrocode}
@@ -798,6 +4973,2550 @@
 %    \end{macrocode}
 %\end{macro}
 %
+%\subsubsection{Pattern Formats}
+%\label{sec:patternformats}
+%There are two basic types of patterns: date/time or numeric.
+%A pattern is stored in a control sequence using custom markup
+%that's easier for \TeX\ to parse than it would be to parse
+%strings in the form \verb|YYYY-MM| or \verb|#,##0|. This internal
+%pattern format can be obtained through capturing the output
+%of \app{texosquery}'s \shortarg{D} action, but patterns can also be
+%constructed using
+%\begin{definition}
+%\cs{texosquerydefpattern}\marg{cs}\marg{pattern specs}
+%\end{definition}
+%The pattern is stored in \meta{cs}. The \meta{pattern specs} depend
+%on whether a date-time or numeric pattern is required.
+%For a date-time pattern, each date/time element is identified 
+%using
+%\begin{definition}
+%\cs{texosquerydtf}\marg{n}\marg{identifier}
+%\end{definition}
+%where \meta{identifier} identifies the element type (such as
+%\verb|M| for month or \verb|s| for seconds) and \meta{n}
+%indicates how the element should be formatted, where \meta{n}
+%is an integer from 1 to 4. For example if \meta{n} is 2
+%and \meta{identifier} is \verb|M|, then this indicates the
+%\verb|MM| format, which produces a two-digit number.
+%
+%Since it's rather cumbersome to keep typing \cs{texosquerydtf}
+%and it can make for rather hard to read code,
+%\cs{texosquerydefpattern} locally redefines \verb|\%| to expand to
+%\cs{texosquerydtf}. This means that if you do, for example:
+%\begin{verbatim}
+%\texosquerydefpattern{\pattern}{\%2d/\%2M/\%4y}
+%\end{verbatim}
+%then \cs{pattern} is defined to
+%\begin{verbatim}
+%\texosquerydtf 2d/\texosquerydtf 2M/\texosquerydtf 4y 
+%\end{verbatim}
+%When simply used within the document, this just expands to the
+%pattern format. For example:
+%\begin{verbatim}
+%Pattern: \pattern.
+%\end{verbatim}
+%will display \qt{Pattern: dd/MM/yyyy} in the PDF. However,
+%when used with \cs{texosqueryfmtdatetime}, the definition
+%of \cs{texosquerydtf} changes to reproduce the required 
+%date/time element.
+%
+%For example:
+%\begin{verbatim}
+%\texosquerydefpattern{\pattern}{\%2d/\%2M/\%4y \%2H:\%2m:\%2s \%2Z}
+%
+%Pattern: \pattern.
+%
+%\TeXOSQueryDateTime{\datetimedata}
+%
+%\ifx\datetimedata\empty
+% Query Failed!
+%\else
+% \expandafter\texosqueryfmtdatetime\expandafter\pattern\datetimedata
+%\fi
+%\end{verbatim}
+%
+%The numeric patterns are rather more complicated. The
+%\meta{pattern specs} now needs to use the following formats:
+%
+%\begin{definition}
+%\cs{texosquerypatnum}\marg{+ve/-ve numeric pattern}
+%\end{definition}
+%This is a numeric pattern applied to a number regardless of
+%whether the number is positive or negative. (If negative, the
+%minus sign is automatically inserted.) This is rather a long
+%and cumbersome command to type, so \cs{texosquerydefpattern}
+%locally defines \cs{numfmt} to expand to it.
+%
+%\begin{definition}
+%\cs{texosquerypatplusminus}\marg{+ve numeric pattern}\marg{-ve numeric
+%pattern}
+%\end{definition}
+%This provides a pattern \meta{+ve numeric pattern} to use if the
+%number is positive and a patter \meta{-ve numeric pattern} to use
+%if the number is negative. Again \cs{texosquerydefpattern}
+%locally defines a shortcut, \cs{pmnumfmt}, to expand to this
+%command.
+%
+%\begin{definition}
+%\cs{texosquerypatsinum}\marg{decimal pattern}\marg{mantissa
+%pattern}
+%\end{definition}
+%This provides a pattern to use for SI numbers where \meta{decimal
+%pattern} is a pattern for the decimal number part (before the
+%exponent symbol) and \meta{mantissa} is the pattern for the integer
+%part in the mantissa (after the exponent symbol).
+%The locally defined shortcut is \cs{sinumfmt}. The \meta{decimal
+%pattern} will typically be in the form:
+%\begin{definition}
+%\cs{texosquerypatdec}\marg{integer pattern}\marg{fraction pattern}
+%\end{definition}
+%This indicates a decimal pattern where the \meta{integer pattern}
+%is applied to the part before the decimal separator and
+%\meta{fraction pattern} is applied to the part after the separator. The shortcut is \cs{decfmt}.
+%
+%\begin{definition}
+%\cs{texosquerypatprefixcurrency}\marg{decimal pattern}\marg{text}
+%\end{definition}
+%This indicates a currency pattern with a prefixed currency symbol where \meta{text} is inserted
+%before the currency symbol. The shortcut is \cs{pcur}.
+%The \meta{decimal pattern} will typically use
+%\cs{texosquerypatdec}\marg{int}\meta{frac}. (Similarly for the
+%following.)
+%
+%\begin{definition}
+%\cs{texosquerypatprefixicurrency}\marg{decimal pattern}\marg{text}
+%\end{definition}
+%This indicates an international currency pattern with a prefixed
+%international currency symbol where \meta{text} is inserted
+%before the symbol. The shortcut is \cs{picur}.
+%
+%\begin{definition}
+%\cs{texosquerypatsuffixcurrency}\marg{decimal pattern}\marg{text}
+%\end{definition}
+%This indicates a currency pattern with a suffixed international
+%currency symbol where \meta{text} is inserted
+%after the currency symbol. The shortcut is \cs{scur}.
+%
+%\begin{definition}
+%\cs{texosquerypatsuffixicurrency}\marg{decimal pattern}\marg{text}
+%\end{definition}
+%This indicates an international currency pattern with a suffixed
+%international currency symbol where \meta{text} is inserted
+%after the symbol. The shortcut is \cs{sicur}.
+%
+%\begin{definition}
+%\cs{texosquerypatprefixpercent}\marg{decimal pattern}\marg{text}
+%\end{definition}
+%This indicates a percentage pattern with a prefixed percent symbol where \meta{text} is inserted
+%before the symbol. The shortcut is \cs{ppct}.
+%
+%\begin{definition}
+%\cs{texosquerypatsuffixpercent}\marg{decimal pattern}\marg{text}
+%\end{definition}
+%This indicates a percentage pattern with a suffixed percent symbol where \meta{text} is inserted
+%after the symbol. The shortcut is \cs{spct}.
+%
+%\begin{definition}
+%\cs{texosquerypatprefixpermill}\marg{decimal pattern}\marg{text}
+%\end{definition}
+%This indicates a per-mill pattern with a prefixed per-mill symbol where \meta{text} is inserted
+%before the symbol. The shortcut is \cs{ppml}.
+%
+%\begin{definition}
+%\cs{texosquerypatsuffixpermill}\marg{decimal pattern}\marg{text}
+%\end{definition}
+%This indicates a per-mill pattern with a suffixed per-mill symbol where \meta{text} is inserted
+%after the symbol. The shortcut is \cs{spml}.
+%
+%\begin{important}
+%The integer parts \meta{integer part}, \meta{fraction part}
+%and \meta{mantissa} must have \emph{exactly} ten digit identifiers.
+%(\TeX\ can't reach 11 digit numbers.)
+%\end{important}
+%
+%There are two types of digit identifiers:
+%\begin{definition}
+%\cs{texosquerypatdigit}
+%\end{definition}
+%This indicates a digit that must be displayed, even if it's not
+%significant (for example a leading zero). The shortcut command is \verb|\0| (backslash zero).
+%
+%\begin{definition}
+%\cs{texosquerypatdigitnozero}
+%\end{definition}
+%This indicates a digit that should only be displayed if it's
+%significant. (For example, if it's a leading zero, it's not shown.)
+%The shortcut command is \verb|\#| (backslash hash).
+%
+%The number group separator can be inserted using
+%\begin{definition}
+%\cs{texosquerypatgroupsep}
+%\end{definition}
+%The shortcut command is \verb|\,| (backslash comma).
+%
+%The sign can be inserted using
+%\begin{definition}
+%\cs{texosquerypatminus}
+%\end{definition}
+%This ensures the sign is displayed even if the number is positive.
+%The shortcut command is \verb|\-| (backslash hyphen).
+%
+%Here's an example of a decimal pattern:
+%\begin{verbatim}
+%\texosquerydefpattern{\numpattern}{%
+% \numfmt{\decfmt{\#\,\#\#\#\,\#\#\#\,\#\#\0}{\0\#\#\#\#\#\#\#\#\#}}}
+%\end{verbatim}
+%The pattern can be applied to a number using \cs{texosqueryfmtnumber}:
+%\begin{verbatim}
+%\texosqueryfmtnumber{\numpattern}{123}{4567}{2}
+%\end{verbatim}
+%which produces: 12,345.67 (the group and decimal separators can be
+%redefined as appropriate).
+%
+%Here's an example of a scientific number:
+%\begin{verbatim}
+%\texosquerydefpattern{\sinumpattern}{%
+% \sinumfmt
+% {\decfmt{\#\,\#\#\#\,\#\#\#\,\#\#\0}{\0\#\#\#\#\#\#\#\#\#}}%
+% {\-\#\#\#\#\#\#\#\#\0\0}%
+%}
+%\end{verbatim}
+%The pattern can be applied to a number:
+%\begin{verbatim}
+%\texosqueryfmtnumber{\sinumpattern}{1}{234567}{3}
+%\end{verbatim}
+%which produces: 1.234567E+03
+%
+%Here's an integer pattern:
+%\begin{verbatim}
+%\texosquerydefpattern{\intpattern}{%
+% \patnumfmt{\#\,\#\#\#\,\#\#\#\,\#\#\0}}
+%\end{verbatim}
+%The pattern applied to a number:
+%\begin{verbatim}
+%\texosqueryfmtnumber{\intpattern}{123}{4567}{2}
+%\end{verbatim}
+%which produces: 12,345 (the fractional part has been omitted).
+%
+%Here's a currency pattern that applies a different format for
+%positive and negative numbers:
+%\begin{verbatim}
+%\texosquerydefpattern{\curpattern}{%
+% \pmnumfmt
+% {\pcur{\decfmt{\#\,\#\#\#\,\#\#\#\,\#\#\0}{\0\0\#\#\#\#\#\#\#\#}}{}}%
+% {\pcur{\decfmt{\#\,\#\#\#\,\#\#\#\,\#\#\0}{\0\0\#\#\#\#\#\#\#\#}}{\-}}}
+%\end{verbatim}
+%This uses the \meta{text} part of \cs{pcur} to insert the sign
+%before the currency symbol (but only for negative values).
+%\begin{verbatim}
+%\texosqueryfmtnumber{\curpattern}{-1234567}{0}{0}
+%\end{verbatim}
+%This produces: $-$\$12,345,678.00 (again the symbol and separators
+%can be redefined as appropriate).
+%
+%Here's an example of a percentage pattern:
+%\begin{verbatim}
+%\texosquerydefpattern{\pcpattern}{%
+% \numfmt{\spct{\#\,\#\#\#\,\#\#\#\,\#\#\0}{}}}
+%\end{verbatim}
+%The pattern can similarly be applied to a number using
+%\cs{texosqueryfmtnumber}.
+%
+%\begin{macro}{\texosquerydtf}
+%\changes{1.2}{2017-03-23}{new}
+%Date/time format placeholder. The second argument is the
+%placeholder character and the first argument is the number of
+%occurrences of that character in the placeholder. The default
+%definition just converts it back to pattern format used by
+%Java's
+%\href{http://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html}{SimpleDateFormat
+%class}. The pattern interprets $\ge4$ as a single case, so this
+%will only produce a maximum of four characters.
+%    \begin{macrocode}
+\def\texosquerydtf#1#2{%
+  \ifcase#1
+  \or
+   #2%
+  \or
+   #2#2%
+  \or
+   #2#2#2%
+  \else
+   #2#2#2#2%
+  \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%The following commands are used to display the pattern in the
+%document text to reproduce the pattern string recognised by Java.
+%This is provided for debugging to check the pattern. In most cases
+%the pattern will be applied to a number rather than simply
+%displayed.
+%
+%\begin{macro}{\texosquerypatstr}
+%\changes{1.2}{2017-03-23}{new}
+%Quoted string contained in number format.
+%    \begin{macrocode}
+\def\texosquerypatstr#1{'#1'}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatquote}
+%\changes{1.2}{2017-03-23}{new}
+%Literal quote contained in number format.
+%    \begin{macrocode}
+\def\texosquerypatquote{''}
+%    \end{macrocode}
+%\end{macro}
+%Number format place holders.
+%\begin{macro}{\texosquerypatplusminus}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatplusminus#1#2{#1;#2}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatnum}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatnum#1{#1}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatsinum}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatsinum#1#2{#1E#2}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatdec}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatdec#1#2{#1.#2}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatprefixcurrency}
+%\changes{1.2}{2017-03-23}{new}
+%First argument is a number, the second is optional text before the
+%currency symbol. This will require UTF-8 support otherwise it will
+%need redefining as appropriate. (Similarly for the other currency
+%commands and for the per-mill commands.)
+%    \begin{macrocode}
+\def\texosquerypatprefixcurrency#1#2{#2¤#1}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatprefixicurrency}
+%\changes{1.2}{2017-03-23}{new}
+%As above but use international currency symbol.
+%    \begin{macrocode}
+\def\texosquerypatprefixicurrency#1#2{#2¤¤#1}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatsuffixcurrency}
+%\changes{1.2}{2017-03-23}{new}
+%First argument is a number, the second is optional text after the
+%currency symbol.
+%    \begin{macrocode}
+\def\texosquerypatsuffixcurrency#1#2{#1¤#2}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatsuffixicurrency}
+%\changes{1.2}{2017-03-23}{new}
+%As above but use international currency symbol.
+%    \begin{macrocode}
+\def\texosquerypatsuffixicurrency#1#2{#1¤¤#2}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatdigit}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatdigit{0}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatdigitnozero}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatdigitnozero{\#}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatminus}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatminus{-}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatgroupsep}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatgroupsep{,}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatprefixpercent}
+%\changes{1.2}{2017-03-23}{new}
+%The first argument is the value, the second argument is optional
+%text before the percent symbol.
+%    \begin{macrocode}
+\def\texosquerypatprefixpercent#1#2{#2\%#1}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatsuffixpercent}
+%\changes{1.2}{2017-03-23}{new}
+%The first argument is the value, the second argument is optional
+%text after the percent symbol.
+%    \begin{macrocode}
+\def\texosquerypatsuffixpercent#1#2{#1\%#2}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatprefixpermill}
+%\changes{1.2}{2017-03-23}{new}
+%The first argument is the value, the second argument is optional
+%text before the per-mill symbol.
+%    \begin{macrocode}
+\def\texosquerypatprefixpermill#1#2{#2‰#1}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatsuffixpermill}
+%\changes{1.2}{2017-03-23}{new}
+%The first argument is the value, the second argument is optional
+%text after the per-mill symbol.
+%    \begin{macrocode}
+\def\texosquerypatsuffixpermill#1#2{#1‰#2}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at pattern@shortcuts}
+%Provide much shorter cuts for the convenience of directly defining
+%patterns with \cs{texosquerydefpattern}.
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at pattern@shortcuts{%
+   \def\%{\noexpand\texosquerydtf}%
+   \def\0{\noexpand\texosquerypatdigit}%
+   \def\#{\noexpand\texosquerypatdigitnozero}%
+   \def\-{\noexpand\texosquerypatminus}%
+   \def\,{\noexpand\texosquerypatgroupsep}%
+   \def\numfmt{\noexpand\texosquerypatnum}%
+   \def\pmnumfmt{\noexpand\texosquerypatplusminus}%
+   \def\sinumfmt{\noexpand\texosquerypatsinum}%
+   \def\decfmt{\noexpand\texosquerypatdec}%
+   \def\pcur{\noexpand\texosquerypatprefixcurrency}%
+   \def\picur{\noexpand\texosquerypatprefixicurrency}%
+   \def\scur{\noexpand\texosquerypatsuffixcurrency}%
+   \def\sicur{\noexpand\texosquerypatsuffixicurrency}%
+   \def\ppct{\noexpand\texosquerypatprefixpercent}%
+   \def\spct{\noexpand\texosquerypatsuffixpercent}%
+   \def\ppml{\noexpand\texosquerypatprefixpermill}%
+   \def\spml{\noexpand\texosquerypatsuffixpermill}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerydefpattern}
+%Define a new pattern using the shortcut markup. The first argument
+%is the name of the control sequence in which to store the pattern
+%provided in the second argument. Be careful of any fragile commands
+%within the second argument. They will need protecting!
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerydefpattern#1#2{%
+ \begingroup
+  \@texosquery at pattern@shortcuts
+  \@texosquery at edef\x{\endgroup\def\noexpand#1{#2}}\x
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%
+%\subsubsection{Applying Date-Time Patterns}
+%\label{sec:applydatetimepatterns}
+%In order to apply date-time patterns, we need all the information about the
+%date or time we're trying to format.
+%\begin{enumerate}
+%\item Era needed by the \texttt{G} designator. Java
+%identifies the era by an integer (0 = BC and 1 = AD).
+%\item Era text (e.g. AD) can be supplied by a macro.
+%\item Year needed by the \texttt{y} designator.
+%\item Week year needed by the \texttt{Y} designator.
+%\item Month in year needed by the \texttt{M} or \texttt{L}
+%designators.
+%\item Month name needed by the \texttt{M} or \texttt{L}
+%designators. This can be provided as macros that convert the month
+%number to the name. Four macros are needed: short, full, standalone
+%short and standalone full.
+%\item Week in year needed by the \texttt{w} designator.
+%\item Week in month needed by the \texttt{W} designator.
+%\item Day in year needed by the \texttt{D} designator.
+%\item Day in month needed by the \texttt{d} designator.
+%\item Day of week in month needed by the \texttt{F} designator.
+%\item Day name in week needed by the \texttt{E} designator.
+%This can be provided as a macros that accepts the day of week
+%number. The full form is needed for 4 letter patterns otherwise a
+%short form.
+%\item Day number of week (1 = Monday, 7 = Sunday) needed by the
+%\texttt{u} designator. This means that
+%the above day of week name macros needs to use Monday=1 base indexing.
+%This means that \cs{pgfcalendarweekdayname} can't be used directly.
+%\item AM/PM identifier needed by the \texttt{a}
+%designator. Assume 0 = AM and 1 = PM to match Java.
+%\item AM/PM text can be provided by a macro.
+%\item Hour of the day (0-23) needed by the \texttt{H}
+%designator.
+%\item Hour in day (1-24) needed by the \texttt{k}
+%designator.
+%\item Hour in am/pm (0-11) needed by the \texttt{K} designator.
+%\item Hour in am/pm (1-12) needed by the \texttt{h} designator.
+%\item Minute in hour needed by the \texttt{m} designator.
+%\item Second in minute needed by the \texttt{s} designator.
+%\item Millisecond needed by the \texttt{S} designator.
+%\item Time zone needed by the \texttt{z}, \texttt{Z} and \texttt{X}
+%designators. This will require macros for converting the time zone
+%to each of those formats.
+%\end{enumerate}
+%Supply a general utility command that has enough arguments to pass
+%all the above information. A higher level user command can then be
+%provided that determines all the arguments to provide an easier
+%interface.
+%
+%The arguments need to be the pattern followed by
+%\marg{era id}\marg{year}\marg{week year}\marg{month}\marg{week in 
+%year}\marg{week in month}\marg{day in year}\marg{day in month}\marg{day of 
+%week in month}\marg{day number of week}\marg{am/pm id}\marg{hour of day 
+%(H)}\marg{hour in day (k)}\marg{hour in am/pm (K)}\marg{hour in
+%am/pm (h)}\marg{minute in hour}\marg{second in minute}\marg{millisecond}\marg{time zone}
+%The arguments must all be integers except for the time zone which
+%must be in the form
+%\marg{TZh}\marg{TZm}\marg{id}\marg{dst flag}. These are the time zone hour and
+%min offsets, time zone ID and daylight saving flag (1 if daylight
+%saving in effect otherwise 0). These arguments can all be
+%obtained using the \longarg{date-time} / \shortarg{M} action.
+%
+%We'll need some helper macros to get around the nine argument
+%maximum limit.
+%
+%\begin{macro}{\texosqueryfmtdatetime}
+%\changes{1.2}{2017-03-23}{new}
+%The general utility command to format a pattern. The first argument
+%is the pattern. After that are the date-time data arguments.
+%    \begin{macrocode}
+\def\texosqueryfmtdatetime#1{%
+  \def\@texosquery at fmt@dt at pattern{#1}%
+  \@texosquery at fmt@getera
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%All the remaining arguments except for the time zone must be
+%integers. These are padded using \cs{@texosquery at paddigits}.
+%
+%\begin{macro}{\@texosquery at fmt@getera}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getera#1{%
+  \edef\@texosquery at fmt@G{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getyear
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getyear}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getyear#1{%
+  \edef\@texosquery at fmt@y{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getweekyear
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getweekyear}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getweekyear#1{%
+  \edef\@texosquery at fmt@Y{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getmonth
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getmonth}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getmonth#1{%
+  \edef\@texosquery at fmt@M{\@texosquery at paddigits{#1}}%
+  \let\@texosquery at fmt@L\@texosquery at fmt@M
+  \@texosquery at fmt@getweekinyear
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getweekinyear}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getweekinyear#1{%
+  \edef\@texosquery at fmt@w{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getweekinmonth
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getweekinmonth}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getweekinmonth#1{%
+  \edef\@texosquery at fmt@W{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getdayinyear
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getdayinyear}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getdayinyear#1{%
+  \edef\@texosquery at fmt@D{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getdayinmonth
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getdayinmonth}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getdayinmonth#1{%
+  \edef\@texosquery at fmt@d{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getdayofweekinmonth
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getdayofweekinmonth}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getdayofweekinmonth#1{%
+  \edef\@texosquery at fmt@F{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getdaynumberofweek
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getdaynumberofweek}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getdaynumberofweek#1{%
+  \edef\@texosquery at fmt@u{\@texosquery at paddigits{#1}}%
+  \let\@texosquery at fmt@E\@texosquery at fmt@u
+  \@texosquery at fmt@getampm
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getampm}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getampm#1{%
+  \edef\@texosquery at fmt@a{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@gethourindayH
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@gethourindayH}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@gethourindayH#1{%
+  \edef\@texosquery at fmt@H{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@gethourindayk
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@gethourindayk}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@gethourindayk#1{%
+  \edef\@texosquery at fmt@k{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@gethourinampmK
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@gethourinampmK}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@gethourinampmK#1{%
+  \edef\@texosquery at fmt@K{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@gethourinampmh
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@gethourinampmh}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@gethourinampmh#1{%
+  \edef\@texosquery at fmt@h{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getminute
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getminute}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getminute#1{%
+  \edef\@texosquery at fmt@m{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getsecond
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getsecond}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getsecond#1{%
+  \edef\@texosquery at fmt@s{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getmillisecond
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@getmillisecond}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@getmillisecond#1{%
+  \edef\@texosquery at fmt@S{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@gettimezone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@gettimezone}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@gettimezone#1{%
+  \def\@texosquery at fmt@Z{#1}%
+  \def\@texosquery at fmt@z{#1}%
+  \def\@texosquery at fmt@X{#1}%
+%    \end{macrocode}
+%All data now supplied. Temporarily redefine pattern markup and
+%process the pattern.
+%    \begin{macrocode}
+  \begingroup
+    \@texosquery at setup@dtpattern
+    \@texosquery at fmt@dt at pattern
+  \endgroup
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at setup@dtpattern}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at setup@dtpattern{%
+  \let\texosquerydtf\@texosquery at fmt@dtf
+  \let\texosquerypatstr\texosquerypatfmtstr
+  \let\texosquerypatquote\texosquerypatfmtquote
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at paddigits@pos}
+%\changes{1.2}{2017-03-23}{new}
+%Pad positive number to 10 digits. \TeX\ can't reach 11 digits, so this is
+%the maximum representation.
+%    \begin{macrocode}
+\def\@texosquery at paddigits@pos#1{%
+  \ifnum#1<10
+   000000000\number#1
+  \else
+   \ifnum#1<100
+    00000000\number#1
+   \else
+     \ifnum#1<1000
+      0000000\number#1
+     \else
+       \ifnum#1<10000
+        000000\number#1
+       \else
+         \ifnum#1<100000
+          00000\number#1
+         \else
+           \ifnum#1<1000000
+            0000\number#1
+           \else
+             \ifnum#1<10000000
+              000\number#1
+             \else
+               \ifnum#1<100000000
+                00\number#1
+               \else
+                 \ifnum#1<1000000000
+                  0\number#1
+                 \else
+                   \number#1
+                 \fi
+               \fi
+             \fi
+           \fi
+         \fi
+       \fi
+     \fi
+   \fi
+  \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at paddigits}
+%\changes{1.2}{2017-03-23}{new}
+%This will expand to 11 characters (sign followed by 10 digits).
+%    \begin{macrocode}
+\def\@texosquery at paddigits#1{%
+ \ifnum#1<0
+%    \end{macrocode}
+%Move the minus sign outside.
+%    \begin{macrocode}
+   -\expandafter\@texosquery at paddigits@pos\expandafter
+     {\@texosquery at gobble#1}%
+ \else
+   +\@texosquery at paddigits@pos{#1}%
+ \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at paddigits@trailing}
+%\changes{1.2}{2017-03-23}{new}
+%Pad trailing zeros.
+%    \begin{macrocode}
+\def\@texosquery at paddigits@trailing#1{%
+  \expandafter\@texosquery at tenoften@then at gobble
+    #10000000000\@texosquery at end@tenoften
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at tenoften@then at gobble}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at tenoften@then at gobble#1#2#3#4#5#6#7#8#9{%
+  #1#2#3#4#5#6#7#8#9%
+  \@texosquery at lastoften@gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at lastoften@gobble}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at lastoften@gobble#1#2\@texosquery at end@tenoften{#1}
+%    \end{macrocode}
+%\end{macro}
+%
+%Provide commands to select certain digits. (Sign not included.)
+%
+%\begin{macro}{\@texosquery at firstoften}
+%\changes{1.2}{2017-03-23}{new}
+%First of ten.
+%    \begin{macrocode}
+\def\@texosquery at firstoften#1#2#3#4#5#6#7#8#9{%
+ #1%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at secondoften}
+%\changes{1.2}{2017-03-23}{new}
+%Second of ten.
+%    \begin{macrocode}
+\def\@texosquery at secondoften#1#2#3#4#5#6#7#8#9{%
+ #2%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at thirdoften}
+%\changes{1.2}{2017-03-23}{new}
+%Third of ten.
+%    \begin{macrocode}
+\def\@texosquery at thirdoften#1#2#3#4#5#6#7#8#9{%
+ #3%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fourthoften}
+%\changes{1.2}{2017-03-23}{new}
+%Fourth of ten.
+%    \begin{macrocode}
+\def\@texosquery at fourthoften#1#2#3#4#5#6#7#8#9{%
+ #4%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fifthoften}
+%\changes{1.2}{2017-03-23}{new}
+%Fifth of ten.
+%    \begin{macrocode}
+\def\@texosquery at fifthoften#1#2#3#4#5#6#7#8#9{%
+ #5%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at sixthoften}
+%\changes{1.2}{2017-03-23}{new}
+%Sixth of ten.
+%    \begin{macrocode}
+\def\@texosquery at sixthoften#1#2#3#4#5#6#7#8#9{%
+ #6%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at seventhoften}
+%\changes{1.2}{2017-03-23}{new}
+%Seventh of ten.
+%    \begin{macrocode}
+\def\@texosquery at seventhoften#1#2#3#4#5#6#7#8#9{%
+ #7%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at eighthoften}
+%\changes{1.2}{2017-03-23}{new}
+%Eighth of ten.
+%    \begin{macrocode}
+\def\@texosquery at eighthoften#1#2#3#4#5#6#7#8#9{%
+ #8%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at ninthoften}
+%\changes{1.2}{2017-03-23}{new}
+%Ninth of ten.
+%    \begin{macrocode}
+\def\@texosquery at ninthoften#1#2#3#4#5#6#7#8#9{%
+ #9%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at tenthoften}
+%\changes{1.2}{2017-03-23}{new}
+%Tenth of ten.
+%    \begin{macrocode}
+\def\@texosquery at tenthoften#1#2#3#4#5#6#7#8#9{%
+ \@texosquery at firstofone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%Now macros to select first $n$ of ten.
+%
+%\begin{macro}{@texosquery at firsttwooften}
+%\changes{1.2}{2017-03-23}{new}
+%First two of ten.
+%    \begin{macrocode}
+\def\@texosquery at firsttwooften#1#2#3#4#5#6#7#8#9{%
+ #1#2%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at firstthreeoften}
+%\changes{1.2}{2017-03-23}{new}
+%First three of ten.
+%    \begin{macrocode}
+\def\@texosquery at firstthreeoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at firstfouroften}
+%\changes{1.2}{2017-03-23}{new}
+%First four of ten.
+%    \begin{macrocode}
+\def\@texosquery at firstfouroften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at firstfiveoften}
+%\changes{1.2}{2017-03-23}{new}
+%First five of ten.
+%    \begin{macrocode}
+\def\@texosquery at firstfiveoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at firstsixoften}
+%\changes{1.2}{2017-03-23}{new}
+%First six of ten.
+%    \begin{macrocode}
+\def\@texosquery at firstsixoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5#6%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at firstsevenoften}
+%\changes{1.2}{2017-03-23}{new}
+%First seven of ten.
+%    \begin{macrocode}
+\def\@texosquery at firstsevenoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5#6#7%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at firsteightoften}
+%\changes{1.2}{2017-03-23}{new}
+%First eight of ten.
+%    \begin{macrocode}
+\def\@texosquery at firsteightoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5#6#7#8%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at firstnineoften}
+%\changes{1.2}{2017-03-23}{new}
+%First nine of ten.
+%    \begin{macrocode}
+\def\@texosquery at firstnineoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5#6#7#8#9%
+%    \end{macrocode}
+%Grab tenth argument and discard.
+%    \begin{macrocode}
+ \@texosquery at gobble
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at alltenoften}
+%\changes{1.2}{2017-03-23}{new}
+%All ten.
+%    \begin{macrocode}
+\def\@texosquery at alltenoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5#6#7#8#9%
+ \@texosquery at firstofone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%Select last $n$ of ten.
+%
+%\begin{macro}{@texosquery at lasttwooften}
+%\changes{1.2}{2017-03-23}{new}
+%Last two of ten.
+%    \begin{macrocode}
+\def\@texosquery at lasttwooften#1#2#3#4#5#6#7#8#9{%
+ #9%
+ \@texosquery at firstofone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at lastthreeoften}
+%\changes{1.2}{2017-03-23}{new}
+%Last three of ten.
+%    \begin{macrocode}
+\def\@texosquery at lastthreeoften#1#2#3#4#5#6#7#8#9{%
+ #8#9%
+ \@texosquery at firstofone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at lastfouroften}
+%\changes{1.2}{2017-03-23}{new}
+%Last four of ten.
+%    \begin{macrocode}
+\def\@texosquery at lastfouroften#1#2#3#4#5#6#7#8#9{%
+ #7#8#9%
+ \@texosquery at firstofone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at lastfiveoften}
+%\changes{1.2}{2017-03-23}{new}
+%Last five of ten.
+%    \begin{macrocode}
+\def\@texosquery at lastfiveoften#1#2#3#4#5#6#7#8#9{%
+ #6#7#8#9%
+ \@texosquery at firstofone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at lastsixoften}
+%\changes{1.2}{2017-03-23}{new}
+%Last six of ten.
+%    \begin{macrocode}
+\def\@texosquery at lastsixoften#1#2#3#4#5#6#7#8#9{%
+ #5#6#7#8#9%
+ \@texosquery at firstofone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at lastsevenoften}
+%\changes{1.2}{2017-03-23}{new}
+%Last seven of ten.
+%    \begin{macrocode}
+\def\@texosquery at lastsevenoften#1#2#3#4#5#6#7#8#9{%
+ #4#5#6#7#8#9%
+ \@texosquery at firstofone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at lasteightoften}
+%\changes{1.2}{2017-03-23}{new}
+%Last eight of ten.
+%    \begin{macrocode}
+\def\@texosquery at lasteightoften#1#2#3#4#5#6#7#8#9{%
+ #3#4#5#6#7#8#9%
+ \@texosquery at firstofone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{@texosquery at lastnineoften}
+%\changes{1.2}{2017-03-23}{new}
+%Last nine of ten.
+%    \begin{macrocode}
+\def\@texosquery at lastnineoften#1#2#3#4#5#6#7#8#9{%
+ #2#3#4#5#6#7#8#9%
+ \@texosquery at firstofone
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmtminus}
+%\changes{1.2}{2017-03-23}{new}
+%Minus symbol for use in date-time patterns.
+%    \begin{macrocode}
+\def\@texosquery at fmtminus{\texosquerypatfmtminus}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmtplus}
+%\changes{1.2}{2017-03-23}{new}
+%Plus symbol for use in date-time patterns. Omit by default.
+%    \begin{macrocode}
+\def\@texosquery at fmtplus{}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmtsign}
+%\changes{1.2}{2017-03-23}{new}
+%Plus or minus sign for use in date-time patterns.
+%    \begin{macrocode}
+\def\@texosquery at fmtsign#1{%
+ \ifx#1+\@texosquery at fmtplus\else\@texosquery at fmtminus\fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at atleastonedigit}
+%\changes{1.2}{2017-03-23}{new}
+%At least one digit with leading zeros removed.
+%    \begin{macrocode}
+\def\@texosquery at atleastonedigit#1{%
+  \ifnum#1<0
+   \@texosquery at fmtminus\number-#1
+  \else
+   \number#1
+  \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at atleastfourdigits}
+%\changes{1.2}{2017-03-23}{new}
+%At least four digits, possible padded with zeros to make up four. The first
+%argument is the sign, then follow the ten digits.
+%    \begin{macrocode}
+\def\@texosquery at atleastfourdigits#1{%
+  \@texosquery at at@leastfourdigits#1\@texosquery at end@atleastfourdigits
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at at@leastfourdigits}
+%\changes{1.2}{2017-03-23}{new}
+%At least four digits, possible padded with zeros to make up four. The first
+%argument is the sign, then follow the ten digits.
+%    \begin{macrocode}
+\def\@texosquery at at@leastfourdigits#1#2\@texosquery at end@atleastfourdigits{%
+  \@texosquery at fmtsign{#1}%
+  \ifnum#2<1000
+    \@texosquery at lastfouroften#2%
+  \else
+    \number#2
+  \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at threedigitsexactly}
+%\changes{1.2}{2017-03-23}{new}
+%Exactly three digits.
+%    \begin{macrocode}
+\def\@texosquery at threedigitsexactly#1{%
+  \@texosquery at threedigits@exactly#1\@texosquery at threedigits@exactly
+}%
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at threedigits@exactly}
+%\changes{1.2}{2017-03-23}{new}
+%Exactly three digits.
+%    \begin{macrocode}
+\def\@texosquery at threedigits@exactly#1#2\@texosquery at threedigits@exactly{%
+  \@texosquery at fmtsign{#1}%
+  \@texosquery at lastthreeoften#2%
+}%
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at twodigitsexactly}
+%\changes{1.2}{2017-03-23}{new}
+%Exactly two digits.
+%    \begin{macrocode}
+\def\@texosquery at twodigitsexactly#1{%
+  \@texosquery at twodigits@exactly#1\@texosquery at twodigits@exactly
+}%
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at twodigits@exactly}
+%\changes{1.2}{2017-03-23}{new}
+%Exactly two digits.
+%    \begin{macrocode}
+\def\@texosquery at twodigits@exactly#1#2\@texosquery at twodigits@exactly{%
+  \@texosquery at fmtsign{#1}%
+  \@texosquery at lasttwooften#2%
+}%
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fmt@dtf}
+%\changes{1.2}{2017-03-23}{new}
+%\begin{definition}
+%\cs{@texosquery at fmt@dtf}\marg{n}\marg{designator}
+%\end{definition}
+%
+%When formatting a date-time pattern \cs{texosquerydtf} will
+%temporarily be redefined to this command. This command indicates
+%the format obtained by \meta{n} instances of \meta{designator}.
+%For example, \verb|{2}{M}| indicates the format \texttt{MM}. This
+%command tests for \cs{texosqueryfmtpat}\meta{format}, which should
+%take a single argument. If defined, that's used, otherwise use one
+%of the numeric commands defined above. The \sty{locale} package
+%defines \cs{texosqueryfmtpatMMM} and so on to use the locale's month names
+%etc.
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fmt@dtf#1#2{%
+  \@texosquery at ifundef{@texosquery at fmt@#2}%
+  {\@texosquery at warn{Unknown date-time pattern designator `#2'}}%
+  {%
+    \ifcase#1
+    \or
+      \@texosquery at ifundef{texosqueryfmtpat#2}%
+      {%
+        \expandafter\expandafter\expandafter
+          \@texosquery at atleastonedigit
+          \expandafter\expandafter\expandafter
+         {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+      {%
+        \csname texosqueryfmtpat#2\expandafter\expandafter\expandafter\endcsname
+         \expandafter\expandafter\expandafter
+         {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+    \or
+      \@texosquery at ifundef{texosqueryfmtpat#2#2}%
+      {%
+        \expandafter\expandafter\expandafter
+          \@texosquery at twodigitsexactly
+          \expandafter\expandafter\expandafter
+          {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+      {%
+        \csname texosqueryfmtpat#2#2\expandafter\expandafter\expandafter
+        \endcsname \expandafter\expandafter\expandafter
+         {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+    \or
+      \@texosquery at ifundef{texosqueryfmtpat#2#2#2}%
+      {%
+        \expandafter\expandafter\expandafter
+          \@texosquery at threedigitsexactly
+          \expandafter\expandafter\expandafter
+        {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+      {%
+        \csname texosqueryfmtpat#2#2#2\expandafter\expandafter\expandafter
+        \endcsname \expandafter\expandafter\expandafter
+         {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+    \else
+      \@texosquery at ifundef{texosqueryfmtpat#2#2#2#2}%
+      {%
+        \expandafter\expandafter\expandafter
+          \@texosquery at atleastfourdigits
+          \expandafter\expandafter\expandafter
+          {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+      {%
+        \csname texosqueryfmtpat#2#2#2#2\expandafter\expandafter\expandafter
+        \endcsname \expandafter\expandafter\expandafter
+         {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+    \fi
+  }%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%Provide default commands for the time zone designators, since the
+%time zone isn't supplied as a single integer.
+%
+%\begin{macro}{\texosqueryfmttimezonehr}
+%\changes{1.2}{2017-03-23}{new}
+%Allow for \verb|-0| so append 1 to hour in test.
+%    \begin{macrocode}
+\def\texosqueryfmttimezonehr#1{%
+  \ifnum#11<0\@texosquery at fmtminus
+    \ifnum#1>-10 0\fi\number-#1
+  \else
+   +\ifnum#1<10 0\fi\number#1
+  \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmttimezonenumhr}
+%\changes{1.2}{2017-03-23}{new}
+%Like the above, but don't zero-pad or prefix with plus sign.
+%    \begin{macrocode}
+\def\texosqueryfmttimezonenumhr#1{%
+  \ifnum#11<0\@texosquery at fmtminus
+    \number-#1
+  \else
+    \number#1
+  \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmttimezonemin}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosqueryfmttimezonemin#1{%
+  \ifnum#1<10 0\fi\number#1
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at firstoffour}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at firstoffour#1#2#3#4{#1}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at secondoffour}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at secondoffour#1#2#3#4{#2}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at thirdoffour}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at thirdoffour#1#2#3#4{#3}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at fourthoffour}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at fourthoffour#1#2#3#4{#4}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryshorttimezone}
+%\changes{1.2}{2017-03-23}{new}
+%Maps id to short time zone display name. This will need redefining
+%as appropriate. The default simply expands to the ID.
+%Mappings can be obtained for a particular locale using the
+%\shortarg{Z} or \longarg{time-zones} action.
+%    \begin{macrocode}
+\def\texosqueryshorttimezone#1{#1}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryshortdstzone}
+%\changes{1.2}{2017-03-23}{new}
+%Maps id to short daylight saving time zone display name. This will need redefining
+%as appropriate. The default simply expands to the ID followed by
+%(DST).
+%    \begin{macrocode}
+\def\texosqueryshortdstzone#1{#1 (DST)}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerylongtimezone}
+%\changes{1.2}{2017-03-23}{new}
+%Maps id to long time zone display name. This will need redefining
+%as appropriate. The default simply expands to the ID.
+%    \begin{macrocode}
+\def\texosquerylongtimezone#1{#1}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerylongdstzone}
+%\changes{1.2}{2017-03-23}{new}
+%Maps id to long daylight saving time zone display name. This will need redefining
+%as appropriate. The default simply expands to the ID followed by
+%(DST).
+%    \begin{macrocode}
+\def\texosquerylongdstzone#1{#1 (DST)}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerytimesep}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerytimesep{:}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatz}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{z} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatz#1{%
+ \expandafter\ifnum\@texosquery at fourthoffour#1=0
+  \expandafter\texosqueryshorttimezone\expandafter{\@texosquery at thirdoffour#1}%
+ \else
+  \expandafter\texosqueryshortdstzone\expandafter{\@texosquery at thirdoffour#1}%
+ \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatzz}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{zz} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatzz#1{%
+ \expandafter\ifnum\@texosquery at fourthoffour#1=0
+   \expandafter\texosqueryshorttimezone\expandafter{\@texosquery at thirdoffour#1}%
+ \else
+   \expandafter\texosqueryshortdstzone\expandafter{\@texosquery at thirdoffour#1}%
+ \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatzzz}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{zzz} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatzzz#1{%
+ \expandafter\ifnum\@texosquery at fourthoffour#1=0
+   \expandafter\texosquerylongtimezone\expandafter{\@texosquery at thirdoffour#1}%
+ \else
+   \expandafter\texosquerylongdstzone\expandafter{\@texosquery at thirdoffour#1}%
+ \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatzzzz}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{zzzz} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatzzzz#1{%
+ \expandafter\ifnum\@texosquery at fourthoffour#1=0
+   \expandafter\texosquerylongtimezone\expandafter{\@texosquery at thirdoffour#1}%
+ \else
+   \expandafter\texosquerylongdstzone\expandafter{\@texosquery at thirdoffour#1}%
+ \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatZ}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{Z} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatZ#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+   {\@texosquery at firstoffour#1}%
+  \expandafter\texosqueryfmttimezonemin\expandafter
+   {\@texosquery at secondoffour#1}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatZZ}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{ZZ} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatZZ#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatZZZ}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{ZZZ} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatZZZ#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatZZZZ}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{ZZZZ} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatZZZZ#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatX}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{X} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatX#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \texosquerytimesep
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatXX}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{XX} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatXX#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \texosquerytimesep
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatXXX}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{XXX} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatXXX#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \texosquerytimesep
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatXXXX}
+%\changes{1.2}{2017-03-23}{new}
+%Default time zone format for \texttt{XXXX} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatXXXX#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \texosquerytimesep
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpata}
+%\changes{1.2}{2017-03-23}{new}
+%Default am/pm designator for the \texttt{a} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpata#1{%
+ \ifnum#1=0 AM\else PM\fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpataa}
+%\changes{1.2}{2017-03-23}{new}
+%Default am/pm for the \texttt{aa} designator. Just make it the same
+%as the \texttt{a} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpataa{\texosqueryfmtpata}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpataaa}
+%\changes{1.2}{2017-03-23}{new}
+%Default am/pm for the \texttt{aaa} designator. Just make it the same
+%as the \texttt{a} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpataaa{\texosqueryfmtpata}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpataaaa}
+%\changes{1.2}{2017-03-23}{new}
+%Default am/pm for the \texttt{aaaa} designator. Just make it the same
+%as the \texttt{a} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpataaaa{\texosqueryfmtpata}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatG}
+%\changes{1.2}{2017-03-23}{new}
+%Default era designator for the \texttt{G} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatG#1{%
+ \ifnum#1=1 AD\else BC\fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatGG}
+%\changes{1.2}{2017-03-23}{new}
+%Default era for the \texttt{GG} designator. Just make it the same
+%as the \texttt{G} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatGG{\texosqueryfmtpatG}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatGGG}
+%\changes{1.2}{2017-03-23}{new}
+%Default era for the \texttt{GGG} designator. Just make it the same
+%as the \texttt{G} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatGGG{\texosqueryfmtpatG}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosqueryfmtpatGGGG}
+%\changes{1.2}{2017-03-23}{new}
+%Default era for the \texttt{GGGG} designator. Just make it the same
+%as the \texttt{G} designator.
+%    \begin{macrocode}
+\def\texosqueryfmtpatGGGG{\texosqueryfmtpatG}
+%    \end{macrocode}
+%\end{macro}
+%
+%
+%\subsubsection{Applying Numeric Patterns}
+%\label{sec:applynumpatterns}
+%
+%\begin{macro}{\texosqueryfmtnumber}
+%\changes{1.2}{2017-03-23}{new}
+%\begin{definition}
+%\cs{texosqueryfmtnumber}\marg{pattern}\marg{int}\marg{frac}\marg{mantissa}
+%\end{definition}
+%General purpose low-level number formatting command. The first argument 
+%\meta{pattern} is the pattern. The other arguments are unformatted integers 
+%and must be present and not exceed 10 digits each. The \meta{frac} part must 
+%not start with a sign. The minus sign should go at the start of
+%\meta{int} for negative numbers. The plus sign is
+%optional for positive \meta{int} or \meta{mantissa} and not
+%permitted in \meta{frac}. The arguments may each be the actual numerical
+%value or be a single control sequence whose replacement text is 
+%the value. Avoid anything more complicated than that.
+%
+%This package doesn't provide a higher level command that can split a number 
+%into integer, fractional and mantissa parts.
+%    \begin{macrocode}
+\def\texosqueryfmtnumber#1#2#3#4{%
+  \begingroup
+   \let\texosquerypatstr\texosquerypatfmtstr
+   \let\texosquerypatquote\texosquerypatfmtquote
+   \let\texosquerypatplusminus\texosquerypatfmt at plusminus
+   \let\texosquerypatnum\texosquerypatfmt at num
+   \let\texosquerypatsinum\texosquerypatfmt at sinum
+   \let\texosquerypatdec\texosquerypatfmt at dec
+   \let\texosquerypatprefixcurrency\texosquery at patfmt@prefixcurrency
+   \let\texosquerypatprefixicurrency\texosquery at patfmt@prefixicurrency
+   \let\texosquerypatsuffixcurrency\texosquery at patfmt@suffixcurrency
+   \let\texosquerypatsuffixicurrency\texosquery at patfmt@suffixicurrency
+   \let\texosquerypatdigit\texosquerypatfmt at digit
+   \let\texosquerypatdigitnozero\texosquerypatfmt at digitnozero
+   \let\texosquerypatgroupsep\texosquerypatfmt at groupsep
+   \let\texosquerypatprefixpercent\texosquery at patfmt@prefixpercent
+   \let\texosquerypatsuffixpercent\texosquery at patfmt@suffixpercent
+   \let\texosquerypatprefixpermill\texosquery at patfmt@prefixpermill
+   \let\texosquerypatsuffixpermill\texosquery at patfmt@suffixpermill
+   \let\texosquerypatminus\@texosquerypat at numfmt@sign
+   \let\texosquerypatfmt at decsep\texosquerypatfmtdecsep
+%    \end{macrocode}
+%Allow for negative zero in the \meta{int} part. To avoid overflow,
+%first check for 0 and then append 1 to the number to
+%catch \verb|-0|.
+%    \begin{macrocode}
+   \edef\@texosquery at sgn{%
+     \ifnum#2=0
+        \expandafter\ifnum#21<0 -\else+\fi
+     \else
+        \ifnum#2<0 -\else+\fi
+     \fi
+    }%
+%    \end{macrocode}
+%Allow for arguments passed as control sequences that expand to a
+%number.
+%    \begin{macrocode}
+   \edef\@texosquery at int{\expandafter\@texosquery at paddigits
+      \expandafter{\number#2}}%
+   \let\@texosquery at si@int\@texosquery at int
+%    \end{macrocode}
+%Can't use \cs{number} here as we'll lose any leading zeros.
+%    \begin{macrocode}
+   \edef\@texosquery at frac{\expandafter\@texosquery at paddigits@trailing
+     \expandafter{#3}}%
+   \let\@texosquery at si@frac\@texosquery at frac
+   \edef\@texosquery at mantissa{\expandafter\@texosquery at paddigits
+     \expandafter{\number#4}}%
+%    \end{macrocode}
+%Is the mantissa non-zero?
+%    \begin{macrocode}
+   \ifnum#4=0\relax
+   \else
+     \expandafter\ifx\@texosquery at sgn-%
+       \edef\@texosquery at int{\expandafter
+          \@texosquery at paddigits@pos\expandafter{\number-#2}}%
+     \else
+       \edef\@texosquery at int{\@texosquery at paddigits@pos{#2}}%
+     \fi
+%    \end{macrocode}
+%Shift.
+%    \begin{macrocode}
+     \ifnum#4<0
+       \expandafter\@texosquery at neg@shift\expandafter{\number-#4}%
+     \else
+       \@texosquery at pos@shift{#4}%
+     \fi
+     \expandafter\ifx\@texosquery at sgn-%
+       \edef\@texosquery at int{\expandafter\@texosquery at paddigits
+         \expandafter{\number-\@texosquery at int}}%
+     \else
+       \edef\@texosquery at int{\expandafter\@texosquery at paddigits
+         \expandafter{\number\@texosquery at int}}%
+     \fi
+     \edef\@texosquery at frac{\@texosquery at paddigits@trailing{\@texosquery at frac}}%
+   \fi
+   \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at int}%
+   \let\@texosquery at zerodigit\@texosquery at zerodigit@leading
+   \expandafter\ifx\@texosquery at sgn-%
+     \let\@texosquery at currentsign\texosquerypatfmtminus
+   \else
+     \let\@texosquery at currentsign\texosquerypatfmtplus
+   \fi
+   \@texosquery at digitindex=0\relax
+   \@texosquery at digitfoundfalse
+   #1%
+  \endgroup
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at digitindex}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\newcount\@texosquery at digitindex
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\if at texosquery@digitfound}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\newif\if at texosquery@digitfound
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at pos@shift}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at pos@shift#1{%
+  \ifcase#1
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastnineoften\@texosquery at int
+      \expandafter\@texosquery at firstoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastnineoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lasteightoften\@texosquery at int
+      \expandafter\@texosquery at firsttwooften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lasteightoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastsevenoften\@texosquery at int
+      \expandafter\@texosquery at firstthreeoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastsevenoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastsixoften\@texosquery at int
+      \expandafter\@texosquery at firstfouroften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastsixoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastfiveoften\@texosquery at int
+      \expandafter\@texosquery at firstfiveoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastfiveoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastfouroften\@texosquery at int
+      \expandafter\@texosquery at firstsixoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastfouroften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastthreeoften\@texosquery at int
+      \expandafter\@texosquery at firstsevenoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastthreeoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lasttwooften\@texosquery at int
+      \expandafter\@texosquery at firsteightoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lasttwooften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at tenthoften\@texosquery at int
+      \expandafter\@texosquery at firstnineoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at tenthoften\@texosquery at frac
+    }%
+  \or
+    \let\@texosquery at int\@texosquery at frac
+    \edef\@texosquery at frac{0}%
+%   \end{macrocode}
+%Anything larger will require scientific notation. Hopefully the
+%pattern supports this.
+%   \begin{macrocode}
+  \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at neg@shift}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at neg@shift#1{%
+  \ifcase#1
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastoneoften\@texosquery at int
+      \expandafter\@texosquery at firstnineoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstnineoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lasttwooften\@texosquery at int
+      \expandafter\@texosquery at firsteightoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firsteightoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastthreeoften\@texosquery at int
+      \expandafter\@texosquery at firstsevenoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstsevenoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastfouroften\@texosquery at int
+      \expandafter\@texosquery at firstsixoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstsixoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastfiveoften\@texosquery at int
+      \expandafter\@texosquery at firstfiveoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstfiveoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastsixoften\@texosquery at int
+      \expandafter\@texosquery at firstfouroften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstfouroften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastsevenoften\@texosquery at int
+      \expandafter\@texosquery at firstthreeoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstthreeoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lasteightoften\@texosquery at int
+      \expandafter\@texosquery at firsttwooften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firsttwooften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastnineoften\@texosquery at int
+      \expandafter\@texosquery at firstoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{\@texosquery at int\@texosquery at frac}%
+    \edef\@texosquery at int{0}%
+%   \end{macrocode}
+%Anything beyond this will require scientific notation. Hopefully the
+%pattern supports it.
+%   \begin{macrocode}
+  \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquerypat at numfmt@sign}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquerypat at numfmt@sign{%
+  \@texosquery at currentsign
+  \let\@texosquery at currentsign\empty
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%
+%\begin{macro}{\texosquerypatfmtstr}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmtstr#1{#1}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmtquote}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmtquote{'}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmt at plusminus}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmt at plusminus#1#2{%
+ \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at int}%
+ \@texosquery at digitindex=0\relax
+ \@texosquery at digitfoundfalse
+ \expandafter\ifx\@texosquery at sgn-%
+  #2%
+  \ifnum\@texosquery at digitindex=10
+  \else
+   \@texosquery at invalidpattern{#2}%
+  \fi
+ \else
+  #1%
+  \ifnum\@texosquery at digitindex=10
+  \else
+   \@texosquery at invalidpattern{#1}%
+  \fi
+ \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmt at num}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmt at num#1{#1}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmtexp}
+%\changes{1.2}{2017-03-23}{new}
+%Exponent symbol. Change as appropriate.
+%    \begin{macrocode}
+\def\texosquerypatfmtexp{E}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerypatfmt at sinum}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmt at sinum#1#2{%
+ \let\@texosquery at int\@texosquery at si@int
+ \let\@texosquery at frac\@texosquery at si@frac
+ \let\@texosquery at current\@texosquery at int
+ #1%
+ \texosquerypatfmtexp
+ {\let\@texosquery at zerodigit\@texosquery at zerodigit@leading
+ \ifnum\@texosquery at mantissa<0\relax
+   \let\@texosquery at currentsign\texosquerypatfmtminus
+ \else
+   \let\@texosquery at currentsign\texosquerypatfmtplus
+ \fi
+ \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at mantissa}%
+ \@texosquery at digitindex=0\relax
+ \@texosquery at digitfoundfalse
+ #2}}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmtdecsep}
+%\changes{1.2}{2017-03-23}{new}
+%Decimal separator. Change as appropriate.
+%    \begin{macrocode}
+\def\texosquerypatfmtdecsep{.}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerypatfmtcurdecsep}
+%\changes{1.2}{2017-03-23}{new}
+%Currency decimal separator. Change as appropriate.
+%    \begin{macrocode}
+\def\texosquerypatfmtcurdecsep{.}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerypatfmt at dec}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmt at dec#1#2{%
+ \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at int}%
+ \@texosquery at digitindex=0\relax
+ \@texosquery at digitfoundfalse
+ \let\@texosquery at zerodigit\@texosquery at zerodigit@leading
+ #1%
+ \ifnum\@texosquery at digitindex=10
+ \else
+  \@texosquery at invalidpattern{#1}%
+ \fi
+ \texosquerypatfmt at decsep
+ \let\@texosquery at current\@texosquery at frac
+ \@texosquery at digitindex=0\relax
+ \@texosquery at digitfoundfalse
+ \let\@texosquery at zerodigit\@texosquery at zerodigit@trailing
+ \let\@texosquery at currentsign\empty
+ #2%
+ \ifnum\@texosquery at digitindex=10
+ \else
+  \@texosquery at invalidpattern{#2}%
+ \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmtint}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmtint#1{%
+ \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at int}%
+ \@texosquery at digitindex=0\relax
+ \@texosquery at digitfoundfalse
+ \let\@texosquery at zerodigit\@texosquery at zerodigit@leading
+ #1%
+ \ifnum\@texosquery at digitindex=10
+ \else
+  \@texosquery at invalidpattern{#1}%
+ \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at setpatdisplay}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at setpatdisplay{%
+   \def\texosquerypatstr##1{'##1'}%
+   \def\texosquerypatquote{''}%
+   \def\texosquerypatplusminus##1##2{##1;##2}%
+   \def\texosquerypatnum##1{##1}%
+   \def\texosquerypatsinum##1##2{##1E##2}%
+   \def\texosquerypatdec##1##2{##1.##2}%
+   \def\texosquerypatprefixcurrency##1##2{##2¤##1}%
+   \def\texosquerypatprefixicurrency##1##2{##2¤¤##1}%
+   \def\texosquerypatsuffixcurrency##1##2{##1¤##2}%
+   \def\texosquerypatsuffixicurrency##1##2{##1¤¤##2}%
+   \def\texosquerypatdigit{0}%
+   \def\texosquerypatdigitnozero{\#}%
+   \def\texosquerypatminus{-}%
+   \def\texosquerypatgroupsep{,}%
+   \def\texosquerypatprefixpercent##1##2{##2\%##1}%
+   \def\texosquerypatsuffixpercent##1##2{##1\%##2}%
+   \def\texosquerypatprefixpermill##1##2{##2‰##1}%
+   \def\texosquerypatsuffixpermill##1##2{##1‰##2}%
+   \def\texosquerypatfmt at decsep{.}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at invalidpattern}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at invalidpattern#1{%
+  \begingroup
+   \@texosquery at setpatdisplay
+   \@texosquery at err{10 digit specifiers expected in
+    numeric pattern #1. Found \number\@texosquery at digitindex}%
+    {Each integer element of a numeric pattern must have exactly
+     10 digit specifiers (0 or \#)}%
+  \endgroup
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerypatfmtcurrencysign}
+%\changes{1.2}{2017-03-23}{new}
+%Currency symbol. Redefine as appropriate.
+%    \begin{macrocode}
+\def\texosquerypatfmtcurrencysign{\$}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerypatfmticurrencysign}
+%\changes{1.2}{2017-03-23}{new}
+%International currency symbol. There's no generic fallback that's
+%independent of the input encoding, so this uses a UTF-8 character
+%on the assumption that if \cs{textcurrency} isn't available (for
+%example, through \sty{textcomp}, then the user may be using \XeTeX\
+%or \LuaTeX). If this isn't the case, and there's no UTF-8 support,
+%then this command will need to be redefined as appropriate.
+%    \begin{macrocode}
+\ifx\textcurrency\undefined
+  \def\texosquerypatfmticurrencysign{¤}
+\else
+  \def\texosquerypatfmticurrencysign{\textcurrency}
+\fi
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquery at patfmt@prefixcurrency}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquery at patfmt@prefixcurrency#1#2{%
+ \let\texosquerypatfmt at decsep\texosquerypatfmtcurdecsep
+ #2\texosquerypatfmtcurrencysign#1%
+}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquery at patfmt@prefixicurrency}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquery at patfmt@prefixicurrency#1#2{%
+ \let\texosquerypatfmt at decsep\texosquerypatfmtcurdecsep
+ #2\texosquerypatfmticurrencysign#1%
+}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquery at patfmt@suffixcurrency}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquery at patfmt@suffixcurrency#1#2{%
+ \let\texosquerypatfmt at decsep\texosquerypatfmtcurdecsep
+ #1\texosquerypatfmtcurrencysign#2%
+}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquery at patfmt@suffixicurrency}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquery at patfmt@suffixicurrency#1#2{%
+ \let\texosquerypatfmt at decsep\texosquerypatfmtcurdecsep
+ #1\texosquerypatfmticurrencysign#2%
+}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmt at digit}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmt at digit{%
+ \advance\@texosquery at digitindex by 1\relax
+ \if at texosquery@digitfound
+ \else
+   \ifx\@texosquery at currentsign\texosquerypatfmtminus
+    \texosquerypatfmtminus
+    \let\@texosquery at currentsign\empty
+   \fi
+ \fi
+ \@texosquery at digitfoundtrue
+ \ifcase\@texosquery at digitindex
+ \or
+   \expandafter\@texosquery at firstoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at secondoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at thirdoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at fourthoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at fifthoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at sixthoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at seventhoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at eighthoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at ninthoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at tenthoften\@texosquery at current
+ \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmt at digitnozero}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmt at digitnozero{%
+ \advance\@texosquery at digitindex by 1\relax
+ \edef\@texosquery at digit{%
+   \ifcase\@texosquery at digitindex
+    0%
+   \or
+     \expandafter\@texosquery at firstoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at secondoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at thirdoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at fourthoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at fifthoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at sixthoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at seventhoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at eighthoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at ninthoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at tenthoften\@texosquery at current
+   \else
+   0%
+ \fi
+ }%
+ \ifnum\@texosquery at digit=0\relax
+   \@texosquery at zerodigit
+ \else
+   \if at texosquery@digitfound
+   \else
+     \ifx\@texosquery at currentsign\texosquerypatfmtminus
+      \texosquerypatfmtminus
+      \let\@texosquery at currentsign\empty
+     \fi
+   \fi
+   \@texosquery at digitfoundtrue
+   \@texosquery at digit
+ \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at zerodigit@leading}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at zerodigit@leading{%
+ \edef\@texosquery at digit{%
+   \ifcase\@texosquery at digitindex
+    0%
+   \or
+     \expandafter\@texosquery at firstoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firsttwooften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstthreeoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstfouroften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstfiveoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstsixoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstsevenoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firsteightoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstnineoften\@texosquery at current
+   \or
+     \@texosquery at current
+   \else
+    0%
+   \fi
+  }%
+  \ifnum\@texosquery at digit>0\relax
+   \if at texosquery@digitfound
+   \else
+     \ifx\texosquerypatminus\texosquerypatfmtminus
+      \texosquerypatfmtminus
+     \fi
+   \fi
+   \@texosquery at digitfoundtrue
+   0%
+  \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at zerodigit@trailing}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at zerodigit@trailing{%
+ \edef\@texosquery at digit{%
+   \ifcase\@texosquery at digitindex
+    0%
+   \or
+     \@texosquery at current
+   \or
+     \expandafter\@texosquery at lastnineoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lasteightoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lastsevenoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lastsixoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lastfiveoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lastfouroften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lastthreeoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lasttwooften\@texosquery at current
+   \or
+     \expandafter\@texosquery at tenthoften\@texosquery at current
+   \else
+    0%
+   \fi
+  }%
+  \ifnum\@texosquery at digit>0\relax
+   \if at texosquery@digitfound
+   \else
+     \ifx\texosquerypatminus\texosquerypatfmtminus
+      \texosquerypatfmtminus
+     \fi
+   \fi
+   \@texosquery at digitfoundtrue
+   0%
+  \fi
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerypatfmtminus}
+%\changes{1.2}{2017-03-23}{new}
+%Formatted minus sign. Redefined as appropriate.
+%    \begin{macrocode}
+\def\texosquerypatfmtminus{\ifmmode-\else$-$\fi}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmtplus}
+%\changes{1.2}{2017-03-23}{new}
+%Formatted plus sign. Redefined as appropriate.
+%    \begin{macrocode}
+\def\texosquerypatfmtplus{\ifmmode+\else$+$\fi}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmtgroupsep}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmtgroupsep{,}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquerypatfmt at groupsep}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquerypatfmt at groupsep{%
+  \if at texosquery@digitfound\texosquerypatfmtgroupsep\fi}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerypatfmtpercentsign}
+%\changes{1.2}{2017-03-23}{new}
+%Percent sign used in number format.
+%    \begin{macrocode}
+\def\texosquerypatfmtpercentsign{\%}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquerypatfmtpermillsign}
+%\changes{1.2}{2017-03-23}{new}
+%Per-mill sign used in number format. Redefine as appropriate.
+%    \begin{macrocode}
+\def\texosquerypatfmtpermillsign{‰}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@texosquery at adjust@per}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\@texosquery at adjust@per#1{%
+ \@texosquery at pos@shift{#1}%
+ \edef\@texosquery at int{\expandafter\@texosquery at paddigits
+     \expandafter{\number\@texosquery at int}}%
+ \edef\@texosquery at frac{\@texosquery at paddigits@trailing{\@texosquery at frac}}%
+ \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at int}%
+}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\texosquery at patfmt@prefixpercent}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquery at patfmt@prefixpercent#1#2{%
+ \@texosquery at adjust@per{2}%
+  #2\texosquerypatfmtpercentsign#1%
+}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquery at patfmt@suffixpercent}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquery at patfmt@suffixpercent#1#2{%
+ \@texosquery at adjust@per{2}%
+ #1\texosquerypatfmtpercentsign#2%
+}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquery at patfmt@prefixpermill}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquery at patfmt@prefixpermill#1#2{%
+ \@texosquery at adjust@per{3}%
+ #2\texosquerypatfmtpermillsign#1%
+}
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\texosquery at patfmt@suffixpermill}
+%\changes{1.2}{2017-03-23}{new}
+%    \begin{macrocode}
+\def\texosquery at patfmt@suffixpermill#1#2{%
+ \@texosquery at adjust@per{3}%
+ #1\texosquerypatfmtpermillsign#2%
+}
+%    \end{macrocode}
+%\end{macro}
+%
 %All done.
 %Restore the category code of \texttt{@}:
 %    \begin{macrocode}
@@ -810,7 +7529,7 @@
 %\fi
 %
 %\subsection{\LaTeX\ Code}
-%This is just a simple wrapper for \texttt{texosquery.tex}
+%This is just a simple wrapper for \file{texosquery.tex}
 %so that it can be loaded using \LaTeX's standard \cs{usepackage}
 %method.
 %\iffalse
@@ -821,13 +7540,12 @@
 %Identify package:
 %    \begin{macrocode}
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{texosquery}[2016/07/14 v1.1 (NLCT)]
+\ProvidesPackage{texosquery}[2017/03/23 v1.2 (NLCT)]
 %    \end{macrocode}
-%Load \texttt{texosquery.tex}:
+%Load \file{texosquery.tex}:
 %    \begin{macrocode}
 \input{texosquery}
 %    \end{macrocode}
-%That's it!
 %\iffalse
 %    \begin{macrocode}
 %</texosquery.sty>
@@ -834,5 +7552,148 @@
 %    \end{macrocode}
 %\fi
 %
+%\subsection{Configuration File (\file{texosquery.cfg})}
+%The configuration file. This will need to be edited as appropriate
+%to the system.
+%\iffalse
+%    \begin{macrocode}
+%<*texosquery.cfg>
+%    \end{macrocode}
+%\fi
+%    \begin{macrocode}
+ %If this configuration file is added to TeX's path, it can
+ %be used to set up the texosquery defaults for the installation.
+
+ %Default application (must be installed on the operating system's
+ %path). Change as appropriate. Available options:
+ % * texosquery-jre8 (at least Java 8 required)
+ % * texosquery (at least Java 7 required)
+ % * texosquery-jre5 (at least Java 5 required)
+ %(bash users need to check that the .sh extension has been removed
+ %from the bash scripts, or add the extension to the invoker name.)
+\def\TeXOSInvokerName{texosquery}
+
+ % If the invoker name given above is on the restricted list,
+ % allow it to be run in restricted mode:
+ %\TeXOSQueryAllowRestricted
+%    \end{macrocode}
+%\iffalse
+%    \begin{macrocode}
+%</texosquery.cfg>
+%    \end{macrocode}
+%\fi
+%\subsection{Bash Scripts}
+%These are the bash scripts for Unix-like systems.
+%The first line
+%\begin{verbatim}
+%#!/bin/sh
+%\end{verbatim}
+%is added when the files are extracted by \file{texosquery.ins}
+%(since \verb|\nopreamble| automatically inserts a blank line at the
+%start of the file).
+%\iffalse
+%    \begin{macrocode}
+%<*texosquery.sh>
+%    \end{macrocode}
+%\fi
+%\subsubsection{\file{texosquery.sh}}
+%    \begin{macrocode}
+jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery.jar`
+java -jar "$jarpath" "$@"
+%    \end{macrocode}
+%\iffalse
+%    \begin{macrocode}
+%</texosquery.sh>
+%    \end{macrocode}
+%\fi
+%
+%\iffalse
+%    \begin{macrocode}
+%<*texosquery-jre8.sh>
+%    \end{macrocode}
+%\fi
+%\subsubsection{\file{texosquery-jre8.sh}}
+%    \begin{macrocode}
+jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery-jre8.jar`
+java -Djava.locale.providers=CLDR,JRE -jar "$jarpath" "$@"
+%    \end{macrocode}
+%\iffalse
+%    \begin{macrocode}
+%</texosquery-jre8.sh>
+%    \end{macrocode}
+%\fi
+%
+%\iffalse
+%    \begin{macrocode}
+%<*texosquery-jre5.sh>
+%    \end{macrocode}
+%\fi
+%\subsubsection{\file{texosquery-jre5.sh}}
+%    \begin{macrocode}
+jarpath=`kpsewhich --progname=texosquery --format=texmfscripts texosquery-jre5.jar`
+java -jar "$jarpath" "$@"
+%    \end{macrocode}
+%\iffalse
+%    \begin{macrocode}
+%</texosquery-jre5.sh>
+%    \end{macrocode}
+%\fi
+%
+%\subsection{Windows Batch Scripts}
+%These are the batch scripts for Windows. \TeX\ on Windows doesn't
+%allow the creation of \file{.bat} files, so \file{.ins} file
+%creates these with the extension \file{.batch} which will need to
+%be changed to \file{.bat} after extraction.
+%\iffalse
+%    \begin{macrocode}
+%<*texosquery.bat>
+%    \end{macrocode}
+%\fi
+%\subsubsection{\file{texosquery.bat}}
+%    \begin{macrocode}
+ at ECHO OFF
+FOR /F %%I IN ('kpsewhich --progname=texosquery --format=texmfscripts texosquery.jar') DO SET JARPATH=%%I
+java -jar "%JARPATH%" %*
+%    \end{macrocode}
+%\iffalse
+%    \begin{macrocode}
+%</texosquery.bat>
+%    \end{macrocode}
+%\fi
+%
+%\iffalse
+%    \begin{macrocode}
+%<*texosquery-jre8.bat>
+%    \end{macrocode}
+%\fi
+%\subsubsection{\file{texosquery-jre8.bat}}
+%    \begin{macrocode}
+ at ECHO OFF
+FOR /F %%I IN ('kpsewhich --progname=texosquery --format=texmfscripts texosquery-jre8.jar') DO SET JARPATH=%%I
+java -Djava.locale.providers=CLDR,JRE -jar "%JARPATH%" %*
+%    \end{macrocode}
+%\iffalse
+%    \begin{macrocode}
+%</texosquery-jre8.bat>
+%    \end{macrocode}
+%\fi
+%
+%\iffalse
+%    \begin{macrocode}
+%<*texosquery-jre5.bat>
+%    \end{macrocode}
+%\fi
+%\subsubsection{\file{texosquery-jre5.bat}}
+%    \begin{macrocode}
+ at ECHO OFF
+FOR /F %%I IN ('kpsewhich --progname=texosquery --format=texmfscripts texosquery-jre5.jar') DO SET JARPATH=%%I
+java -jar "%JARPATH%" %*
+%    \end{macrocode}
+%\iffalse
+%    \begin{macrocode}
+%</texosquery-jre5.bat>
+%    \end{macrocode}
+%\fi
+%
 %\Finale
 \endinput

Modified: trunk/Master/texmf-dist/source/support/texosquery/texosquery.ins
===================================================================
--- trunk/Master/texmf-dist/source/support/texosquery/texosquery.ins	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/texmf-dist/source/support/texosquery/texosquery.ins	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1,9 +1,8 @@
 \input docstrip
 
 \preamble
-
  texosquery
- Copyright 2016 Nicola Talbot
+ Copyright 2017 Nicola Talbot
 
  This work may be distributed and/or modified under the
  conditions of the LaTeX Project Public License, either version 1.3
@@ -18,11 +17,24 @@
  The Current Maintainer of this work is Nicola Talbot.
 
  This work consists of the files texosquery.dtx and texosquery.ins
- and the derived files texosquery.sty, texosquery.tex.
- Additionally, the Java application texosquery.jar and bash script
- texosquery
+ and the derived files texosquery.sty, texosquery.tex and
+ texosquery.cfg. Additionally, the Java applications texosquery.jar,
+ texosquery-jre5.jar, texosquery-jre8.jar, the bash scripts
+ texosquery.sh, texosquery-jre5.sh, texosquery-jre8.sh, and
+ the corresponding batch files.
 \endpreamble
 
+%The following is to prevent a blank line from appearing
+%at the start of the bash scripts (which occurs when simply using
+%\nopreamble).
+
+\ifx\@gobble\undefined
+ \def\@gobble#1{}
+\fi
+\def\literalhash{\expandafter\@gobble\string\#}
+
+\def\bashpreamble{\literalhash !/bin/sh}
+
 \askforoverwritefalse
 
 \generate
@@ -39,6 +51,42 @@
     \usepostamble\defaultpostamble
     \from{texosquery.dtx}{texosquery.tex,package}%
   }
+  \file{texosquery.cfg}%
+  {%
+    \usepreamble\defaultpreamble
+    \usepostamble\defaultpostamble
+    \from{texosquery.dtx}{texosquery.cfg,package}%
+  }
+  \file{texosquery.sh}%
+  {%
+    \usepreamble\bashpreamble\nopostamble
+    \from{texosquery.dtx}{texosquery.sh}%
+  }
+  \file{texosquery-jre5.sh}%
+  {%
+    \usepreamble\bashpreamble\nopostamble
+    \from{texosquery.dtx}{texosquery-jre5.sh}%
+  }
+  \file{texosquery-jre8.sh}%
+  {%
+    \usepreamble\bashpreamble\nopostamble
+    \from{texosquery.dtx}{texosquery-jre8.sh}%
+  }
+  \file{texosquery.batch}%
+  {%
+    \nopreamble\nopostamble
+    \from{texosquery.dtx}{texosquery.bat}%
+  }
+  \file{texosquery-jre5.batch}%
+  {%
+    \nopreamble\nopostamble
+    \from{texosquery.dtx}{texosquery-jre5.bat}%
+  }
+  \file{texosquery-jre8.batch}%
+  {%
+    \nopreamble\nopostamble
+    \from{texosquery.dtx}{texosquery-jre8.bat}%
+  }
 }
 
 \endbatchfile

Added: trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.cfg
===================================================================
--- trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.cfg	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.cfg	2017-03-24 22:42:34 UTC (rev 43596)
@@ -0,0 +1,62 @@
+%%
+%% This is file `texosquery.cfg',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% texosquery.dtx  (with options: `texosquery.cfg,package')
+%%  texosquery
+%%  Copyright 2017 Nicola Talbot
+%% 
+%%  This work may be distributed and/or modified under the
+%%  conditions of the LaTeX Project Public License, either version 1.3
+%%  of this license of (at your option) any later version.
+%%  The latest version of this license is in
+%%    http://www.latex-project.org/lppl.txt
+%%  and version 1.3 or later is part of all distributions of LaTeX
+%%  version 2005/12/01 or later.
+%% 
+%%  This work has the LPPL maintenance status `maintained'.
+%% 
+%%  The Current Maintainer of this work is Nicola Talbot.
+%% 
+%%  This work consists of the files texosquery.dtx and texosquery.ins
+%%  and the derived files texosquery.sty, texosquery.tex and
+%%  texosquery.cfg. Additionally, the Java applications texosquery.jar,
+%%  texosquery-jre5.jar, texosquery-jre8.jar, the bash scripts
+%%  texosquery.sh, texosquery-jre5.sh, texosquery-jre8.sh, and
+%%  the corresponding batch files.
+%% \CharacterTable
+%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%%   Digits        \0\1\2\3\4\5\6\7\8\9
+%%   Exclamation   \!     Double quote  \"     Hash (number) \#
+%%   Dollar        \$     Percent       \%     Ampersand     \&
+%%   Acute accent  \'     Left paren    \(     Right paren   \)
+%%   Asterisk      \*     Plus          \+     Comma         \,
+%%   Minus         \-     Point         \.     Solidus       \/
+%%   Colon         \:     Semicolon     \;     Less than     \<
+%%   Equals        \=     Greater than  \>     Question mark \?
+%%   Commercial at \@     Left bracket  \[     Backslash     \\
+%%   Right bracket \]     Circumflex    \^     Underscore    \_
+%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
+%%   Right brace   \}     Tilde         \~}
+
+ %If this configuration file is added to TeX's path, it can
+ %be used to set up the texosquery defaults for the installation.
+
+ %Default application (must be installed on the operating system's
+ %path). Change as appropriate. Available options:
+ % * texosquery-jre8 (at least Java 8 required)
+ % * texosquery (at least Java 7 required)
+ % * texosquery-jre5 (at least Java 5 required)
+ %(bash users need to check that the .sh extension has been removed
+ %from the bash scripts, or add the extension to the invoker name.)
+\def\TeXOSInvokerName{texosquery}
+
+ % If the invoker name given above is on the restricted list,
+ % allow it to be run in restricted mode:
+ %\TeXOSQueryAllowRestricted
+\endinput
+%%
+%% End of file `texosquery.cfg'.


Property changes on: trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.cfg
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.sty	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.sty	2017-03-24 22:42:34 UTC (rev 43596)
@@ -5,9 +5,8 @@
 %% The original source files were:
 %%
 %% texosquery.dtx  (with options: `texosquery.sty,package')
-%% 
 %%  texosquery
-%%  Copyright 2016 Nicola Talbot
+%%  Copyright 2017 Nicola Talbot
 %% 
 %%  This work may be distributed and/or modified under the
 %%  conditions of the LaTeX Project Public License, either version 1.3
@@ -22,9 +21,11 @@
 %%  The Current Maintainer of this work is Nicola Talbot.
 %% 
 %%  This work consists of the files texosquery.dtx and texosquery.ins
-%%  and the derived files texosquery.sty, texosquery.tex.
-%%  Additionally, the Java application texosquery.jar and bash script
-%%  texosquery
+%%  and the derived files texosquery.sty, texosquery.tex and
+%%  texosquery.cfg. Additionally, the Java applications texosquery.jar,
+%%  texosquery-jre5.jar, texosquery-jre8.jar, the bash scripts
+%%  texosquery.sh, texosquery-jre5.sh, texosquery-jre8.sh, and
+%%  the corresponding batch files.
 %% \CharacterTable
 %%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
 %%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
@@ -40,8 +41,9 @@
 %%   Right bracket \]     Circumflex    \^     Underscore    \_
 %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
 %%   Right brace   \}     Tilde         \~}
+
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{texosquery}[2016/07/14 v1.1 (NLCT)]
+\ProvidesPackage{texosquery}[2017/03/23 v1.2 (NLCT)]
 \input{texosquery}
 \endinput
 %%

Modified: trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.tex	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/texmf-dist/tex/latex/texosquery/texosquery.tex	2017-03-24 22:42:34 UTC (rev 43596)
@@ -5,9 +5,8 @@
 %% The original source files were:
 %%
 %% texosquery.dtx  (with options: `texosquery.tex,package')
-%% 
 %%  texosquery
-%%  Copyright 2016 Nicola Talbot
+%%  Copyright 2017 Nicola Talbot
 %% 
 %%  This work may be distributed and/or modified under the
 %%  conditions of the LaTeX Project Public License, either version 1.3
@@ -22,9 +21,11 @@
 %%  The Current Maintainer of this work is Nicola Talbot.
 %% 
 %%  This work consists of the files texosquery.dtx and texosquery.ins
-%%  and the derived files texosquery.sty, texosquery.tex.
-%%  Additionally, the Java application texosquery.jar and bash script
-%%  texosquery
+%%  and the derived files texosquery.sty, texosquery.tex and
+%%  texosquery.cfg. Additionally, the Java applications texosquery.jar,
+%%  texosquery-jre5.jar, texosquery-jre8.jar, the bash scripts
+%%  texosquery.sh, texosquery-jre5.sh, texosquery-jre8.sh, and
+%%  the corresponding batch files.
 %% \CharacterTable
 %%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
 %%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
@@ -40,6 +41,7 @@
 %%   Right bracket \]     Circumflex    \^     Underscore    \_
 %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
 %%   Right brace   \}     Tilde         \~}
+
 \ifnum\catcode`\@=11\relax
   \def\@texosquery at restore@at{}%
 \else
@@ -48,11 +50,61 @@
   }%
  \catcode`\@=11\relax
 \fi
-\ifx\TeXOSQuery\undefined
-\else
+\ifx\TeXOSQuery\undefined \else
   \@texosquery at restore@at
   \expandafter\endinput
 \fi
+\expandafter\def\csname ver at texosquery.tex\endcsname{2017/03/23 v1.2 (NLCT)}
+\ifx\@tracklang at pkgwarn\undefined
+  \ifx\PackageWarning\undefined
+    \def\@texosquery at warn#1{%
+      {%
+        \newlinechar=`\^^J
+        \def\MessageBreak{^^J}%
+        \message{^^Jtexosquery Warning: #1 on line \the\inputlineno.^^J}%
+      }%
+    }
+  \else
+    \def\@texosquery at warn#1{%
+      \PackageWarning{texosquery}{#1}%
+    }
+  \fi
+\else
+  \def\@texosquery at warn#1{%
+    \@tracklang at pkgwarn{texosquery}{#1}%
+  }
+\fi
+\ifx\PackageError\undefined
+  \def\@texosquery at err#1#2{%
+    \errhelp{#2}%
+    \errmessage{texosquery: #1}}
+\else
+  \def\@texosquery at err#1#2{\PackageError{texosquery}{#1}{#2}}
+\fi
+\long\def\@texosquery at ifundef#1#2#3{%
+  \ifcsname#1\endcsname
+    \expandafter\ifx\csname #1\endcsname\relax
+      #2%
+    \else
+      #3%
+    \fi
+  \else
+    \expandafter\ifx\csname #1\endcsname\relax
+      #2%
+    \else
+      #3%
+    \fi
+  \fi
+}
+\ifx\ifcsname\undefined
+  \long\def\@texosquery at ifundef#1#2#3{%
+    \expandafter\ifx\csname #1\endcsname\relax
+      #2%
+    \else
+      #3%
+    \fi
+  }
+\fi
 \def\TeXOSInvokerName{texosquery}
 \ifx\@@input\undefined
   \def\TeXOSQueryInvoker#1{\input|"\TeXOSInvokerName\space#1" }
@@ -59,20 +111,252 @@
 \else
   \def\TeXOSQueryInvoker#1{\@@input|"\TeXOSInvokerName\space#1" }
 \fi
-\newif\ifTeXOSQueryDryRun
-\TeXOSQueryDryRuntrue
+\newif\ifTeXOSQueryDryRun \TeXOSQueryDryRuntrue
+\def\TeXOSQueryAllowRestricted{%
+ \def\@texosquery at allowrestricted##1##2{##1}%
+}
+\def\TeXOSQueryDenyRestricted{%
+ \def\@texosquery at allowrestricted##1##2{##2}%
+}
+\def\@texosquery at allowrestricted#1#2{#2}%
+\openin0=texosquery.cfg \ifeof0\relax \else
+  \closein0\relax
+  \begingroup
+    \newlinechar=`\^^J
+    \message{^^JTeXOSQuery: reading configuration file^^J}%
+  \endgroup
+  \input texosquery.cfg
+\fi
+\def\TeXOSQueryAllowRestricted{%
+  \@texosquery at warn{\string\TeXOSQueryAllowRestricted\space
+   ignored (only allowed in texosquery.cfg)}%
+}
+\def\TeXOSQueryDenyRestricted{%
+  \@texosquery at warn{\string\TeXOSQueryDenyRestricted\space
+   ignored (only allowed in texosquery.cfg)}%
+}
 \ifx\shellescape\undefined
   \ifx\pdfshellescape\undefined
   \else
     \ifnum\pdfshellescape=1\relax
       \TeXOSQueryDryRunfalse
+    \else
+      \@texosquery at allowrestricted
+      {%
+        \ifnum\pdfshellescape=2\relax
+          \TeXOSQueryDryRunfalse
+        \fi
+      }
+      {}
     \fi
   \fi
 \else
   \ifnum\shellescape=1\relax
     \TeXOSQueryDryRunfalse
+  \else
+    \@texosquery at allowrestricted
+    {%
+      \ifnum\shellescape=2\relax
+        \TeXOSQueryDryRunfalse
+      \fi
+    }
+    {}
   \fi
 \fi
+\ifx\@texosquery at edef\undefined
+  \ifx\protected at edef\undefined
+    \let\@texosquery at edef\edef
+  \else
+    \let\@texosquery at edef\protected at edef
+  \fi
+\fi
+\def\@texosquery at gobble#1{}
+\def\@texosquery at firstofone#1{#1}
+\def\texosquerynonasciiwrap#1{#1}
+\ifx\detokenize\undefined
+  \def\texosquerynonasciidetokwrap#1{\string#1}
+\else
+  \def\texosquerynonasciidetokwrap#1{\detokenize{#1}}
+\fi
+\edef\texosquerybackslash{\expandafter\@texosquery at gobble\string\\}
+\ifx\textbackslash\undefined
+  \def\texosquerytextbackslash{\texosquerybackslash}
+\else
+  \def\texosquerytextbackslash{\noexpand\textbackslash}
+\fi
+\edef\texosqueryleftbrace{\expandafter\@texosquery at gobble\string\{}
+\def\texosquerytextleftbrace{\{}
+\edef\texosqueryrightbrace{\expandafter\@texosquery at gobble\string\}}
+\def\texosquerytextrightbrace{\}}
+\edef\texosqueryhash{\expandafter\@texosquery at gobble\string\#}
+\def\texosquerytexthash{\#}
+\edef\texosqueryunderscore{\expandafter\@texosquery at gobble\string\_}
+\def\texosquerytextunderscore{\_}
+\edef\texosquerybacktick{\string`}
+\def\texosquerytextbacktick{`}
+\edef\texosqueryclosequote{\string'}
+\def\texosquerytextclosequote{'}
+\edef\texosquerydoublequote{\string"}
+\def\texosquerytextdoublequote{"}
+\edef\texosquerycolon{\string:}
+\def\texosquerytextcolon{:}
+\edef\texosquerysemicolon{\string;}
+\def\texosquerytextsemicolon{;}
+\edef\texosqueryequals{\string=}
+\def\texosquerytextequals{=}
+\edef\texosqueryslash{\string/}
+\def\texosquerytextslash{/}
+\edef\texosqueryhyphen{\string-}
+\def\texosquerytexthyphen{-}
+\edef\texosqueryplus{\string+}
+\def\texosquerytextplus{+}
+\edef\texosqueryperiod{\string.}
+\def\texosquerytextperiod{.}
+\edef\texosquerycomma{\string,}
+\def\texosquerytextcomma{,}
+\edef\texosqueryopenparen{\string(}
+\def\texosquerytextopenparen{(}
+\edef\texosquerycloseparen{\string)}
+\def\texosquerytextcloseparen{)}
+\edef\texosqueryopensq{\string[}
+\def\texosquerytextopensq{[}
+\edef\texosqueryclosesq{\string]}
+\def\texosquerytextclosesq{]}
+\edef\texosqueryasterisk{\string*}
+\def\texosquerytextasterisk{*}
+\edef\texosqueryatchar{\string @}
+\def\texosquerytextatchar{@}
+\edef\texosquerybar{\string|}
+\ifx\undefined\textbar
+  \def\texosquerytextbar{|}
+\else
+  \def\texosquerytextbar{\ifmmode|\else\textbar\fi}
+\fi
+\edef\texosquerylessthan{\string<}
+\ifx\undefined\textless
+  \def\texosquerytextlessthan{<}
+\else
+  \def\texosquerytextlessthan{\ifmmode<\else\textless\fi}
+\fi
+\edef\texosquerygreaterthan{\string>}
+\ifx\undefined\textgreater
+  \def\texosquerytextgreaterthan{>}
+\else
+  \def\texosquerytextgreaterthan{\ifmmode<\else\textgreater\fi}
+\fi
+\edef\texosquerytilde{\string~}
+\ifx\textasciitilde\undefined
+  \def\texosquerytexttilde{\string~}
+\else
+  \def\texosquerytexttilde{\textasciitilde}
+\fi
+\edef\texosquerycircum{\string^}
+\ifx\textasciicircum\undefined
+  \def\texosquerytextcircum{\string^}
+\else
+  \def\texosquerytextcircum{\textasciicircum}
+\fi
+\edef\texosqueryampersand{\string&}
+\def\texosquerytextampersand{\&}
+\edef\texosquerydollar{\expandafter\@texosquery at gobble\string\$}
+\def\texosquerytextdollar{\$}
+\edef\texosquerypercent{\expandafter\@texosquery at gobble\string\%}
+\def\texosquerytextpercent{\%}
+\edef\texosqueryexclam{\string!}
+\def\texosquerytextexclam{!}
+\edef\texosqueryquestion{\string?}
+\def\texosquerytextquestion{?}
+\edef\texosqueryliteralspace{\expandafter\string\space}
+\def\texosquerytextspace{\noexpand\space}
+\edef\@texosquery at D{\string D}
+\def\@texosquery at enableshortcs{%
+     \def\patdtf{\noexpand\texosquerydtf}%
+     \def\patpmnumfmt{\noexpand\texosquerypatplusminus}%
+     \def\patnumfmt{\noexpand\texosquerypatnum}%
+     \def\patsinumfmt{\noexpand\texosquerypatsinum}%
+     \def\patdecfmt{\noexpand\texosquerypatdec}%
+     \def\patpcur{\noexpand\texosquerypatprefixcurrency}%
+     \def\patpicur{\noexpand\texosquerypatprefixicurrency}%
+     \def\patscur{\noexpand\texosquerypatsuffixcurrency}%
+     \def\patsicur{\noexpand\texosquerypatsuffixicurrency}%
+     \def\patstr{\noexpand\texosquerypatstr}%
+     \def\patapo{\noexpand\texosquerypatquote}%
+     \def\patdgt{\noexpand\texosquerypatdigit}%
+     \def\patdgtnz{\noexpand\texosquerypatdigitnozero}%
+     \def\patmsg{\noexpand\texosquerypatminus}%
+     \def\patngp{\noexpand\texosquerypatgroupsep}%
+     \def\patppct{\noexpand\texosquerypatprefixpercent}%
+     \def\patspct{\noexpand\texosquerypatsuffixpercent}%
+     \def\patppml{\noexpand\texosquerypatprefixpermill}%
+     \def\patspml{\noexpand\texosquerypatsuffixpermill}%
+     \def\twrp{\texosquerynonasciiwrap}%
+     \def\fwrp{\texosquerynonasciidetokwrap}%
+     \let\fbks\texosquerybackslash
+     \let\tbks\texosquerytextbackslash
+     \let\flbr\texosqueryleftbrace
+     \let\tlbr\texosquerytextleftbrace
+     \let\frbr\texosqueryrightbrace
+     \let\trbr\texosquerytextrightbrace
+     \let\fhsh\texosqueryhash
+     \let\thsh\texosquerytexthash
+     \let\fusc\texosqueryunderscore
+     \let\tusc\texosquerytextunderscore
+     \let\fgrv\texosquerybacktick
+     \let\tgrv\texosquerytextbacktick
+     \let\fapo\texosqueryclosequote
+     \let\tapo\texosquerytextclosequote
+     \let\fdqt\texosquerydoublequote
+     \let\tdqt\texosquerytextdoublequote
+     \let\fspc\texosqueryliteralspace
+     \let\tspc\texosquerytextspace
+     \let\fcln\texosquerycolon
+     \let\tcln\texosquerytextcolon
+     \let\fscl\texosquerysemicolon
+     \let\tscl\texosquerytextsemicolon
+     \let\feql\texosqueryequals
+     \let\teql\texosquerytextequals
+     \let\fhyn\texosqueryhyphen
+     \let\thyn\texosquerytexthyphen
+     \let\fpls\texosqueryplus
+     \let\tpls\texosquerytextplus
+     \let\ftld\texosquerytilde
+     \let\ttld\texosquerytexttilde
+     \let\fcir\texosquerycircum
+     \let\tcir\texosquerytextcircum
+     \let\famp\texosqueryampersand
+     \let\tamp\texosquerytextampersand
+     \let\fslh\texosqueryslash
+     \let\tslh\texosquerytextslash
+     \let\fpct\texosquerypercent
+     \let\tpct\texosquerytextpercent
+     \let\fexc\texosqueryexclam
+     \let\texc\texosquerytextexclam
+     \let\fque\texosqueryquestion
+     \let\tque\texosquerytextquestion
+     \let\fles\texosquerylessthan
+     \let\tles\texosquerytextlessthan
+     \let\fgre\texosquerygreaterthan
+     \let\tgre\texosquerytextgreaterthan
+     \let\fdol\texosquerydollar
+     \let\tdol\texosquerytextdollar
+     \let\fdot\texosqueryperiod
+     \let\tdot\texosquerytextperiod
+     \let\fcom\texosquerycomma
+     \let\tcom\texosquerytextcomma
+     \let\fopb\texosqueryopenparen
+     \let\topb\texosquerytextopenparen
+     \let\fclb\texosquerycloseparen
+     \let\tclb\texosquerytextcloseparen
+     \let\fosb\texosqueryopensq
+     \let\tosb\texosquerytextopensq
+     \let\fcsb\texosqueryclosesq
+     \let\tcsb\texosquerytextclosesq
+     \let\fast\texosqueryasterisk
+     \let\tast\texosquerytextasterisk
+     \let\fatc\texosqueryatchar
+     \let\tatc\texosquerytextatchar
+     \let\pdfd\@texosquery at D
+}
 \def\TeXOSQuery#1#2{%
   \ifTeXOSQueryDryRun
     \begingroup
@@ -83,6 +367,7 @@
   \else
     \begingroup
     \endlinechar=-1\relax
+    \@texosquery at enableshortcs
     \catcode`\-=12\relax
     \catcode`\_=12\relax
     \catcode`\^=12\relax
@@ -89,18 +374,147 @@
     \catcode`\~=12\relax
     \catcode`\$=12\relax
     \catcode`\&=12\relax
-    \catcode`\"=12\relax
-    \catcode`\'=12\relax
     \catcode`\.=12\relax
     \catcode`\/=12\relax
     \catcode`\:=12\relax
+    \catcode`\"=12\relax
+    \catcode`\'=12\relax
     \catcode`\;=12\relax
     \catcode`\%=12\relax
     \everyeof{\noexpand}\relax
-    \edef\x{\endgroup\def\noexpand#1{\TeXOSQueryInvoker{#2}}}\x
+    \@texosquery at edef\x{\endgroup\def\noexpand#1{\TeXOSQueryInvoker{#2}}}\x
   \fi
 }
+\def\texosquerycurrency#1{%
+ \expandafter\noexpand\csname texosquerycurrency#1\endcsname
+}
+\ifx\faDollar\undefined
+  \def\texosquerycurrencydollar{\$}
+\else
+  \def\texosquerycurrencydollar{\faDollar}
+\fi
+\ifx\textcent\undefined
+  \def\texosquerycurrencycent{cent}
+\else
+  \def\texosquerycurrencycent{\textcent}
+\fi
+\ifx\faGbp\undefined
+  \ifx\pounds\undefined
+    \def\texosquerycurrencypound{pound}
+  \else
+    \def\texosquerycurrencypound{\pounds}
+  \fi
+\else
+  \def\texosquerycurrencypound{\faGbp}
+\fi
+\ifx\textcurrency\undefined
+  \def\texosquerycurrencysign{currency-sign}
+\else
+  \def\texosquerycurrencysign{\textcurrency}
+\fi
+\ifx\faYen\undefined
+  \ifx\textyen\undefined
+    \def\texosquerycurrencyyen{yen}
+  \else
+    \def\texosquerycurrencyyen{\textyen}
+  \fi
+\else
+  \def\texosquerycurrencyyen{\faYen}
+\fi
+\def\texosquerycurrencyecu{ecu}
+\def\texosquerycurrencycolon{colon}
+\def\texosquerycurrencycruzeiro{cruzeiro}
+\def\texosquerycurrencyfranc{franc}
+\ifx\textlira\undefined
+  \def\texosquerycurrencylira{lira}
+\else
+  \def\texosquerycurrencylira{\textlira}
+\fi
+\def\texosquerycurrencymill{mill}
+\ifx\textnaira\undefined
+  \def\texosquerycurrencynaira{naira}
+\else
+  \def\texosquerycurrencynaira{\textnaira}
+\fi
+\def\texosquerycurrencypeseta{peseta}
+\ifx\faRupee\undefined
+  \def\texosquerycurrencyrupee{rupee}
+\else
+  \def\texosquerycurrencyrupee{\faRupee}
+\fi
+\ifx\faWon\undefined
+  \ifx\textwon\undefined
+    \def\texosquerycurrencywon{won}
+  \else
+    \def\texosquerycurrencywon{\textwon}
+  \fi
+\else
+  \def\texosquerycurrencywon{\faWon}
+\fi
+\ifx\faSheqel\undefined
+  \def\texosquerycurrencynewsheqel{newsheqel}
+\else
+  \def\texosquerycurrencynewsheqel{\faSheqel}
+\fi
+\ifx\textdong\undefined
+  \def\texosquerycurrencydong{dong}
+\else
+  \def\texosquerycurrencydong{\textdong}
+\fi
+\ifx\faEuro\undefined
+  \ifx\texteuro\undefined
+    \ifx\euro\undefined
+      \def\texosquerycurrencyeuro{euro}
+    \else
+      \def\texosquerycurrencyeuro{\euro}
+    \fi
+  \else
+    \def\texosquerycurrencyeuro{\texteuro}
+  \fi
+\else
+  \def\texosquerycurrencyeuro{\faEuro}
+\fi
+\def\texosquerycurrencykip{kip}
+\def\texosquerycurrencytugrik{tugrik}
+\def\texosquerycurrencydrachma{drachma}
+\def\texosquerycurrencygermanpenny{german-penny}
+\ifx\textpeso\undefined
+  \def\texosquerycurrencypeso{peso}
+\else
+  \def\texosquerycurrencypeso{\textpeso}
+\fi
+\ifx\textguarani\undefined
+  \def\texosquerycurrencyguarani{guarani}
+\else
+  \def\texosquerycurrencyguarani{\textguarani}
+\fi
+\def\texosquerycurrencyaustral{austral}
+\def\texosquerycurrencyhryvnia{hryvnia}
+\ifx\textcolonmonetary\undefined
+  \def\texosquerycurrencycedi{cedi}
+\else
+  \def\texosquerycurrencycedi{\textcolonmonetary}
+\fi
+\def\texosquerycurrencylivretournois{livre-tournois}
+\def\texosquerycurrencyspesmilo{spesmilo}
+\def\texosquerycurrencytenge{tenge}
+\def\texosquerycurrencyrupee{rupee}
+\ifx\faTurkishLira\undefined
+  \def\texosquerycurrencyturkishlira{turkish-lira}
+\else
+  \def\texosquerycurrencyturkishlira{\faTurkishLira}
+\fi
+\def\texosquerycurrencynordicmark{nordic-mark}
+\def\texosquerycurrencymanat{manat}
+\ifx\faRuble\undefined
+  \def\texosquerycurrencyruble{ruble}
+\else
+  \def\texosquerycurrencyruble{\faRuble}
+\fi
 \def\TeXOSQueryLocale#1{\TeXOSQuery{#1}{\string-l}}
+\def\TeXOSQueryLangTag#1{\TeXOSQuery{#1}{\string-b}}
+\def\TeXOSQueryNumeric#1#2{\TeXOSQuery{#1}{\string-N #2}}
+\def\TeXOSQueryLocaleData#1#2{\TeXOSQuery{#1}{\string-D #2}}
 \def\TeXOSQueryCwd#1{\TeXOSQuery{#1}{\string-c}}
 \def\TeXOSQueryHome#1{\TeXOSQuery{#1}{\string-m}}
 \def\TeXOSQueryTmpDir#1{\TeXOSQuery{#1}{\string-t}}
@@ -107,6 +521,12 @@
 \def\TeXOSQueryVersion#1{\TeXOSQuery{#1}{\string-r}}
 \def\TeXOSQueryArch#1{\TeXOSQuery{#1}{\string-a}}
 \def\TeXOSQueryName#1{\TeXOSQuery{#1}{\string-o}}
+\def\TeXOSQueryDateTime#1{%
+  \TeXOSQuery{#1}{\string-M}%
+}
+\def\TeXOSQueryTimeZones#1#2{%
+  \TeXOSQuery{#1}{\string-Z #2}%
+}
 \def\TeXOSQueryNow#1{%
   \edef\@texosquery at restore@D{%
     \noexpand\catcode`\noexpand\D=\the\catcode`\D\relax}%
@@ -133,12 +553,254 @@
 }
 \def\TeXOSQueryFileSize#1#2{\TeXOSQuery{#1}{\string-s
  \string'\texosquerystripquotes{#2}\string'}}
-\def\TeXOSQueryFileList#1#2#3{\TeXOSQuery{#1}{%
- \string-i \string'#2\string'
- \string'\texosquerystripquotes{#3}\string'}}
-\def\TeXOSQueryFilterFileList#1#2#3#4{\TeXOSQuery{#1}{%
- \string-f \string'#2\string' \string'#3\string'
- \string'\texosquerystripquotes{#4}\string'}}
+\def\@texosquery at filelist#1#2#3#4#5{\TeXOSQuery{#1}{%
+ \string#2 \string'#3\string'
+ \string'\texosquerystripquotes{#4}\string' #5}}
+\def\TeXOSQueryFileList#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{}%
+}
+\def\TeXOSQueryFileListDateAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{date}%
+}
+\def\TeXOSQueryFileListDateDes#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{date\string-des}%
+}
+\def\TeXOSQueryFileListSizeAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{size}%
+}
+\def\TeXOSQueryFileListSizeDes#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{size\string-des}%
+}
+\def\TeXOSQueryFileListNameAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{name}%
+}
+\def\TeXOSQueryFileListNameDes#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{name\string-des}%
+}
+\def\TeXOSQueryFileListNameIgnoreCaseAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{iname}%
+}
+\def\TeXOSQueryFileListNameIgnoreCaseDes#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{iname\string-des}%
+}
+\def\TeXOSQueryFileListExtAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{ext}%
+}
+\def\TeXOSQueryFileListExtDes#1#2#3{%
+ \@texosquery at filelist{#1}{-i}{#2}{#3}{ext\string-des}%
+}
+\def\TeXOSQueryRegularFileList#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{}%
+}
+\def\TeXOSQuerySubDirList#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{}%
+}
+\def\TeXOSQueryRegularFileListDateAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{date}%
+}
+\def\TeXOSQuerySubDirListDateAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{date}%
+}
+\def\TeXOSQueryRegularFileListDateDes#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{date\string-des}%
+}
+\def\TeXOSQuerySubDirListDateDes#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{date\string-des}%
+}
+\def\TeXOSQueryRegularFileListSizeAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{size}%
+}
+\def\TeXOSQuerySubDirListSizeAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{size}%
+}
+\def\TeXOSQueryRegularFileListSizeDes#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{size\string-des}%
+}
+\def\TeXOSQuerySubDirListSizeDes#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{size\string-des}%
+}
+\def\TeXOSQueryRegularFileListNameAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{name}%
+}
+\def\TeXOSQuerySubDirListNameAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{name}%
+}
+\def\TeXOSQueryRegularFileListNameDes#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{name\string-des}%
+}
+\def\TeXOSQuerySubDirListNameDes#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{name\string-des}%
+}
+\def\TeXOSQueryRegularFileListNameIgnoreCaseAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{iname}%
+}
+\def\TeXOSQuerySubDirListNameIgnoreCaseAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{iname}%
+}
+\def\TeXOSQueryRegularFileListNameIgnoreCaseDes#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{iname\string-des}%
+}
+\def\TeXOSQuerySubDirListNameIgnoreCaseDes#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{iname\string-des}%
+}
+\def\TeXOSQueryRegularFileListExtAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{ext}%
+}
+\def\TeXOSQuerySubDirListExtAsc#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{ext}%
+}
+\def\TeXOSQueryRegularFileListExtDes#1#2#3{%
+ \@texosquery at filelist{#1}{-ir}{#2}{#3}{ext\string-des}%
+}
+\def\TeXOSQuerySubDirListExtDes#1#2#3{%
+ \@texosquery at filelist{#1}{-id}{#2}{#3}{ext\string-des}%
+}
+\def\@texosquery at filterfilelist#1#2#3#4#5#6{%
+ \TeXOSQuery{#1}%
+ {%
+   \string#2 \string'#3\string' \string'#4\string'
+   \string'\texosquerystripquotes{#5}\string' #6%
+ }%
+}
+\def\TeXOSQueryFilterFileList#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{}%
+}
+\def\TeXOSQueryFilterFileListDateAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{date}%
+}
+\def\TeXOSQueryFilterFileListDateDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{date\string-des}%
+}
+\def\TeXOSQueryFilterFileListSizeAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{size}%
+}
+\def\TeXOSQueryFilterFileListSizeDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{size\string-des}%
+}
+\def\TeXOSQueryFilterFileListNameAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{name}%
+}
+\def\TeXOSQueryFilterFileListNameDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{name\string-des}%
+}
+\def\TeXOSQueryFilterFileListNameIgnoreCaseAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{iname}%
+}
+\def\TeXOSQueryFilterFileListNameIgnoreCaseDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{iname\string-des}%
+}
+\def\TeXOSQueryFilterFileListExtAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{ext}%
+}
+\def\TeXOSQueryFilterFileListExtDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-f}{#2}{#3}{#4}{ext\string-des}%
+}
+\def\TeXOSQueryFilterRegularFileList#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{}%
+}
+\def\TeXOSQueryFilterSubDirList#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{}%
+}
+\def\TeXOSQueryFilterSubDirListDateAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{date}%
+}
+\def\TeXOSQueryFilterRegularFileListDateAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{date}%
+}
+\def\TeXOSQueryFilterSubDirListDateDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{date\string-des}%
+}
+\def\TeXOSQueryFilterRegularFileListDateDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{date\string-des}%
+}
+\def\TeXOSQueryFilterSubDirListSizeAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{size}%
+}
+\def\TeXOSQueryFilterRegularFileListSizeAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{size}%
+}
+\def\TeXOSQueryFilterSubDirListSizeDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{size\string-des}%
+}
+\def\TeXOSQueryFilterRegularFileListSizeDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{size\string-des}%
+}
+\def\TeXOSQueryFilterSubDirListNameAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{name}%
+}
+\def\TeXOSQueryFilterRegularFileListNameAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{name}%
+}
+\def\TeXOSQueryFilterSubDirListNameDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{name\string-des}%
+}
+\def\TeXOSQueryFilterRegularFileListNameDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{name\string-des}%
+}
+\def\TeXOSQueryFilterSubDirListNameIgnoreCaseAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{iname}%
+}
+\def\TeXOSQueryFilterRegularFileListNameIgnoreCaseAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{iname}%
+}
+\def\TeXOSQueryFilterSubDirListNameIgnoreCaseDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{iname\string-des}%
+}
+\def\TeXOSQueryFilterRegularFileListNameIgnoreCaseDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{iname\string-des}%
+}
+\def\TeXOSQueryFilterSubDirListExtAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{ext}%
+}
+\def\TeXOSQueryFilterRegularFileListExtAsc#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{ext}%
+}
+\def\TeXOSQueryFilterSubDirListExtDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fd}{#2}{#3}{#4}{ext\string-des}%
+}
+\def\TeXOSQueryFilterRegularFileListExtDes#1#2#3#4{%
+ \@texosquery at filterfilelist{#1}{-fr}{#2}{#3}{#4}{ext\string-des}%
+}
+\def\@texosquery at walk#1#2#3#4#5{%
+ \TeXOSQuery{#1}%
+ {%
+   \string-w \string'#2\string' \string'#3\string'
+   \string'\texosquerystripquotes{#4}\string' #5%
+ }%
+}
+\def\TeXOSQueryWalk#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{}%
+}
+\def\TeXOSQueryWalkDateAsc#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{date}%
+}
+\def\TeXOSQueryWalkDateDes#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{date\string-des}%
+}
+\def\TeXOSQueryWalkSizeAsc#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{size}%
+}
+\def\TeXOSQueryWalkSizeDes#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{size\string-des}%
+}
+\def\TeXOSQueryWalkNameAsc#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{name}%
+}
+\def\TeXOSQueryWalkNameDes#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{name\string-des}%
+}
+\def\TeXOSQueryWalkNameIgnoreCaseAsc#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{iname}%
+}
+\def\TeXOSQueryWalkNameIgnoreCaseDes#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{iname\string-des}%
+}
+\def\TeXOSQueryWalkExtAsc#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{ext}%
+}
+\def\TeXOSQueryWalkExtDes#1#2#3#4{%
+ \@texosquery at walk{#1}{#2}{#3}{#4}{ext\string-des}%
+}
 \def\TeXOSQueryFileURI#1#2{\TeXOSQuery{#1}{\string-u
  \string'\texosquerystripquotes{#2}\string'}}
 \def\TeXOSQueryFilePath#1#2{\TeXOSQuery{#1}{\string-p
@@ -145,6 +807,1064 @@
  \string'\texosquerystripquotes{#2}\string'}}
 \def\TeXOSQueryDirName#1#2{\TeXOSQuery{#1}{\string-e
  \string'\texosquerystripquotes{#2}\string'}}
+\def\texosquerydtf#1#2{%
+  \ifcase#1
+  \or
+   #2%
+  \or
+   #2#2%
+  \or
+   #2#2#2%
+  \else
+   #2#2#2#2%
+  \fi
+}
+\def\texosquerypatstr#1{'#1'}
+\def\texosquerypatquote{''}
+\def\texosquerypatplusminus#1#2{#1;#2}
+\def\texosquerypatnum#1{#1}
+\def\texosquerypatsinum#1#2{#1E#2}
+\def\texosquerypatdec#1#2{#1.#2}
+\def\texosquerypatprefixcurrency#1#2{#2¤#1}
+\def\texosquerypatprefixicurrency#1#2{#2¤¤#1}
+\def\texosquerypatsuffixcurrency#1#2{#1¤#2}
+\def\texosquerypatsuffixicurrency#1#2{#1¤¤#2}
+\def\texosquerypatdigit{0}
+\def\texosquerypatdigitnozero{\#}
+\def\texosquerypatminus{-}
+\def\texosquerypatgroupsep{,}
+\def\texosquerypatprefixpercent#1#2{#2\%#1}
+\def\texosquerypatsuffixpercent#1#2{#1\%#2}
+\def\texosquerypatprefixpermill#1#2{#2‰#1}
+\def\texosquerypatsuffixpermill#1#2{#1‰#2}
+\def\@texosquery at pattern@shortcuts{%
+   \def\%{\noexpand\texosquerydtf}%
+   \def\0{\noexpand\texosquerypatdigit}%
+   \def\#{\noexpand\texosquerypatdigitnozero}%
+   \def\-{\noexpand\texosquerypatminus}%
+   \def\,{\noexpand\texosquerypatgroupsep}%
+   \def\numfmt{\noexpand\texosquerypatnum}%
+   \def\pmnumfmt{\noexpand\texosquerypatplusminus}%
+   \def\sinumfmt{\noexpand\texosquerypatsinum}%
+   \def\decfmt{\noexpand\texosquerypatdec}%
+   \def\pcur{\noexpand\texosquerypatprefixcurrency}%
+   \def\picur{\noexpand\texosquerypatprefixicurrency}%
+   \def\scur{\noexpand\texosquerypatsuffixcurrency}%
+   \def\sicur{\noexpand\texosquerypatsuffixicurrency}%
+   \def\ppct{\noexpand\texosquerypatprefixpercent}%
+   \def\spct{\noexpand\texosquerypatsuffixpercent}%
+   \def\ppml{\noexpand\texosquerypatprefixpermill}%
+   \def\spml{\noexpand\texosquerypatsuffixpermill}%
+}
+\def\texosquerydefpattern#1#2{%
+ \begingroup
+  \@texosquery at pattern@shortcuts
+  \@texosquery at edef\x{\endgroup\def\noexpand#1{#2}}\x
+}
+\def\texosqueryfmtdatetime#1{%
+  \def\@texosquery at fmt@dt at pattern{#1}%
+  \@texosquery at fmt@getera
+}
+\def\@texosquery at fmt@getera#1{%
+  \edef\@texosquery at fmt@G{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getyear
+}
+\def\@texosquery at fmt@getyear#1{%
+  \edef\@texosquery at fmt@y{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getweekyear
+}
+\def\@texosquery at fmt@getweekyear#1{%
+  \edef\@texosquery at fmt@Y{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getmonth
+}
+\def\@texosquery at fmt@getmonth#1{%
+  \edef\@texosquery at fmt@M{\@texosquery at paddigits{#1}}%
+  \let\@texosquery at fmt@L\@texosquery at fmt@M
+  \@texosquery at fmt@getweekinyear
+}
+\def\@texosquery at fmt@getweekinyear#1{%
+  \edef\@texosquery at fmt@w{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getweekinmonth
+}
+\def\@texosquery at fmt@getweekinmonth#1{%
+  \edef\@texosquery at fmt@W{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getdayinyear
+}
+\def\@texosquery at fmt@getdayinyear#1{%
+  \edef\@texosquery at fmt@D{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getdayinmonth
+}
+\def\@texosquery at fmt@getdayinmonth#1{%
+  \edef\@texosquery at fmt@d{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getdayofweekinmonth
+}
+\def\@texosquery at fmt@getdayofweekinmonth#1{%
+  \edef\@texosquery at fmt@F{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getdaynumberofweek
+}
+\def\@texosquery at fmt@getdaynumberofweek#1{%
+  \edef\@texosquery at fmt@u{\@texosquery at paddigits{#1}}%
+  \let\@texosquery at fmt@E\@texosquery at fmt@u
+  \@texosquery at fmt@getampm
+}
+\def\@texosquery at fmt@getampm#1{%
+  \edef\@texosquery at fmt@a{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@gethourindayH
+}
+\def\@texosquery at fmt@gethourindayH#1{%
+  \edef\@texosquery at fmt@H{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@gethourindayk
+}
+\def\@texosquery at fmt@gethourindayk#1{%
+  \edef\@texosquery at fmt@k{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@gethourinampmK
+}
+\def\@texosquery at fmt@gethourinampmK#1{%
+  \edef\@texosquery at fmt@K{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@gethourinampmh
+}
+\def\@texosquery at fmt@gethourinampmh#1{%
+  \edef\@texosquery at fmt@h{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getminute
+}
+\def\@texosquery at fmt@getminute#1{%
+  \edef\@texosquery at fmt@m{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getsecond
+}
+\def\@texosquery at fmt@getsecond#1{%
+  \edef\@texosquery at fmt@s{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@getmillisecond
+}
+\def\@texosquery at fmt@getmillisecond#1{%
+  \edef\@texosquery at fmt@S{\@texosquery at paddigits{#1}}%
+  \@texosquery at fmt@gettimezone
+}
+\def\@texosquery at fmt@gettimezone#1{%
+  \def\@texosquery at fmt@Z{#1}%
+  \def\@texosquery at fmt@z{#1}%
+  \def\@texosquery at fmt@X{#1}%
+  \begingroup
+    \@texosquery at setup@dtpattern
+    \@texosquery at fmt@dt at pattern
+  \endgroup
+}
+\def\@texosquery at setup@dtpattern{%
+  \let\texosquerydtf\@texosquery at fmt@dtf
+  \let\texosquerypatstr\texosquerypatfmtstr
+  \let\texosquerypatquote\texosquerypatfmtquote
+}
+\def\@texosquery at paddigits@pos#1{%
+  \ifnum#1<10
+   000000000\number#1
+  \else
+   \ifnum#1<100
+    00000000\number#1
+   \else
+     \ifnum#1<1000
+      0000000\number#1
+     \else
+       \ifnum#1<10000
+        000000\number#1
+       \else
+         \ifnum#1<100000
+          00000\number#1
+         \else
+           \ifnum#1<1000000
+            0000\number#1
+           \else
+             \ifnum#1<10000000
+              000\number#1
+             \else
+               \ifnum#1<100000000
+                00\number#1
+               \else
+                 \ifnum#1<1000000000
+                  0\number#1
+                 \else
+                   \number#1
+                 \fi
+               \fi
+             \fi
+           \fi
+         \fi
+       \fi
+     \fi
+   \fi
+  \fi
+}
+\def\@texosquery at paddigits#1{%
+ \ifnum#1<0
+   -\expandafter\@texosquery at paddigits@pos\expandafter
+     {\@texosquery at gobble#1}%
+ \else
+   +\@texosquery at paddigits@pos{#1}%
+ \fi
+}
+\def\@texosquery at paddigits@trailing#1{%
+  \expandafter\@texosquery at tenoften@then at gobble
+    #10000000000\@texosquery at end@tenoften
+}
+\def\@texosquery at tenoften@then at gobble#1#2#3#4#5#6#7#8#9{%
+  #1#2#3#4#5#6#7#8#9%
+  \@texosquery at lastoften@gobble
+}
+\def\@texosquery at lastoften@gobble#1#2\@texosquery at end@tenoften{#1}
+\def\@texosquery at firstoften#1#2#3#4#5#6#7#8#9{%
+ #1%
+ \@texosquery at gobble
+}
+\def\@texosquery at secondoften#1#2#3#4#5#6#7#8#9{%
+ #2%
+ \@texosquery at gobble
+}
+\def\@texosquery at thirdoften#1#2#3#4#5#6#7#8#9{%
+ #3%
+ \@texosquery at gobble
+}
+\def\@texosquery at fourthoften#1#2#3#4#5#6#7#8#9{%
+ #4%
+ \@texosquery at gobble
+}
+\def\@texosquery at fifthoften#1#2#3#4#5#6#7#8#9{%
+ #5%
+ \@texosquery at gobble
+}
+\def\@texosquery at sixthoften#1#2#3#4#5#6#7#8#9{%
+ #6%
+ \@texosquery at gobble
+}
+\def\@texosquery at seventhoften#1#2#3#4#5#6#7#8#9{%
+ #7%
+ \@texosquery at gobble
+}
+\def\@texosquery at eighthoften#1#2#3#4#5#6#7#8#9{%
+ #8%
+ \@texosquery at gobble
+}
+\def\@texosquery at ninthoften#1#2#3#4#5#6#7#8#9{%
+ #9%
+ \@texosquery at gobble
+}
+\def\@texosquery at tenthoften#1#2#3#4#5#6#7#8#9{%
+ \@texosquery at firstofone
+}
+\def\@texosquery at firsttwooften#1#2#3#4#5#6#7#8#9{%
+ #1#2%
+ \@texosquery at gobble
+}
+\def\@texosquery at firstthreeoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3%
+ \@texosquery at gobble
+}
+\def\@texosquery at firstfouroften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4%
+ \@texosquery at gobble
+}
+\def\@texosquery at firstfiveoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5%
+ \@texosquery at gobble
+}
+\def\@texosquery at firstsixoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5#6%
+ \@texosquery at gobble
+}
+\def\@texosquery at firstsevenoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5#6#7%
+ \@texosquery at gobble
+}
+\def\@texosquery at firsteightoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5#6#7#8%
+ \@texosquery at gobble
+}
+\def\@texosquery at firstnineoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5#6#7#8#9%
+ \@texosquery at gobble
+}
+\def\@texosquery at alltenoften#1#2#3#4#5#6#7#8#9{%
+ #1#2#3#4#5#6#7#8#9%
+ \@texosquery at firstofone
+}
+\def\@texosquery at lasttwooften#1#2#3#4#5#6#7#8#9{%
+ #9%
+ \@texosquery at firstofone
+}
+\def\@texosquery at lastthreeoften#1#2#3#4#5#6#7#8#9{%
+ #8#9%
+ \@texosquery at firstofone
+}
+\def\@texosquery at lastfouroften#1#2#3#4#5#6#7#8#9{%
+ #7#8#9%
+ \@texosquery at firstofone
+}
+\def\@texosquery at lastfiveoften#1#2#3#4#5#6#7#8#9{%
+ #6#7#8#9%
+ \@texosquery at firstofone
+}
+\def\@texosquery at lastsixoften#1#2#3#4#5#6#7#8#9{%
+ #5#6#7#8#9%
+ \@texosquery at firstofone
+}
+\def\@texosquery at lastsevenoften#1#2#3#4#5#6#7#8#9{%
+ #4#5#6#7#8#9%
+ \@texosquery at firstofone
+}
+\def\@texosquery at lasteightoften#1#2#3#4#5#6#7#8#9{%
+ #3#4#5#6#7#8#9%
+ \@texosquery at firstofone
+}
+\def\@texosquery at lastnineoften#1#2#3#4#5#6#7#8#9{%
+ #2#3#4#5#6#7#8#9%
+ \@texosquery at firstofone
+}
+\def\@texosquery at fmtminus{\texosquerypatfmtminus}
+\def\@texosquery at fmtplus{}
+\def\@texosquery at fmtsign#1{%
+ \ifx#1+\@texosquery at fmtplus\else\@texosquery at fmtminus\fi
+}
+\def\@texosquery at atleastonedigit#1{%
+  \ifnum#1<0
+   \@texosquery at fmtminus\number-#1
+  \else
+   \number#1
+  \fi
+}
+\def\@texosquery at atleastfourdigits#1{%
+  \@texosquery at at@leastfourdigits#1\@texosquery at end@atleastfourdigits
+}
+\def\@texosquery at at@leastfourdigits#1#2\@texosquery at end@atleastfourdigits{%
+  \@texosquery at fmtsign{#1}%
+  \ifnum#2<1000
+    \@texosquery at lastfouroften#2%
+  \else
+    \number#2
+  \fi
+}
+\def\@texosquery at threedigitsexactly#1{%
+  \@texosquery at threedigits@exactly#1\@texosquery at threedigits@exactly
+}%
+\def\@texosquery at threedigits@exactly#1#2\@texosquery at threedigits@exactly{%
+  \@texosquery at fmtsign{#1}%
+  \@texosquery at lastthreeoften#2%
+}%
+\def\@texosquery at twodigitsexactly#1{%
+  \@texosquery at twodigits@exactly#1\@texosquery at twodigits@exactly
+}%
+\def\@texosquery at twodigits@exactly#1#2\@texosquery at twodigits@exactly{%
+  \@texosquery at fmtsign{#1}%
+  \@texosquery at lasttwooften#2%
+}%
+\def\@texosquery at fmt@dtf#1#2{%
+  \@texosquery at ifundef{@texosquery at fmt@#2}%
+  {\@texosquery at warn{Unknown date-time pattern designator `#2'}}%
+  {%
+    \ifcase#1
+    \or
+      \@texosquery at ifundef{texosqueryfmtpat#2}%
+      {%
+        \expandafter\expandafter\expandafter
+          \@texosquery at atleastonedigit
+          \expandafter\expandafter\expandafter
+         {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+      {%
+        \csname texosqueryfmtpat#2\expandafter\expandafter\expandafter\endcsname
+         \expandafter\expandafter\expandafter
+         {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+    \or
+      \@texosquery at ifundef{texosqueryfmtpat#2#2}%
+      {%
+        \expandafter\expandafter\expandafter
+          \@texosquery at twodigitsexactly
+          \expandafter\expandafter\expandafter
+          {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+      {%
+        \csname texosqueryfmtpat#2#2\expandafter\expandafter\expandafter
+        \endcsname \expandafter\expandafter\expandafter
+         {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+    \or
+      \@texosquery at ifundef{texosqueryfmtpat#2#2#2}%
+      {%
+        \expandafter\expandafter\expandafter
+          \@texosquery at threedigitsexactly
+          \expandafter\expandafter\expandafter
+        {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+      {%
+        \csname texosqueryfmtpat#2#2#2\expandafter\expandafter\expandafter
+        \endcsname \expandafter\expandafter\expandafter
+         {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+    \else
+      \@texosquery at ifundef{texosqueryfmtpat#2#2#2#2}%
+      {%
+        \expandafter\expandafter\expandafter
+          \@texosquery at atleastfourdigits
+          \expandafter\expandafter\expandafter
+          {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+      {%
+        \csname texosqueryfmtpat#2#2#2#2\expandafter\expandafter\expandafter
+        \endcsname \expandafter\expandafter\expandafter
+         {\csname @texosquery at fmt@#2\endcsname}%
+      }%
+    \fi
+  }%
+}
+\def\texosqueryfmttimezonehr#1{%
+  \ifnum#11<0\@texosquery at fmtminus
+    \ifnum#1>-10 0\fi\number-#1
+  \else
+   +\ifnum#1<10 0\fi\number#1
+  \fi
+}
+\def\texosqueryfmttimezonenumhr#1{%
+  \ifnum#11<0\@texosquery at fmtminus
+    \number-#1
+  \else
+    \number#1
+  \fi
+}
+\def\texosqueryfmttimezonemin#1{%
+  \ifnum#1<10 0\fi\number#1
+}
+\def\@texosquery at firstoffour#1#2#3#4{#1}
+\def\@texosquery at secondoffour#1#2#3#4{#2}
+\def\@texosquery at thirdoffour#1#2#3#4{#3}
+\def\@texosquery at fourthoffour#1#2#3#4{#4}
+\def\texosqueryshorttimezone#1{#1}
+\def\texosqueryshortdstzone#1{#1 (DST)}
+\def\texosquerylongtimezone#1{#1}
+\def\texosquerylongdstzone#1{#1 (DST)}
+\def\texosquerytimesep{:}
+\def\texosqueryfmtpatz#1{%
+ \expandafter\ifnum\@texosquery at fourthoffour#1=0
+  \expandafter\texosqueryshorttimezone\expandafter{\@texosquery at thirdoffour#1}%
+ \else
+  \expandafter\texosqueryshortdstzone\expandafter{\@texosquery at thirdoffour#1}%
+ \fi
+}
+\def\texosqueryfmtpatzz#1{%
+ \expandafter\ifnum\@texosquery at fourthoffour#1=0
+   \expandafter\texosqueryshorttimezone\expandafter{\@texosquery at thirdoffour#1}%
+ \else
+   \expandafter\texosqueryshortdstzone\expandafter{\@texosquery at thirdoffour#1}%
+ \fi
+}
+\def\texosqueryfmtpatzzz#1{%
+ \expandafter\ifnum\@texosquery at fourthoffour#1=0
+   \expandafter\texosquerylongtimezone\expandafter{\@texosquery at thirdoffour#1}%
+ \else
+   \expandafter\texosquerylongdstzone\expandafter{\@texosquery at thirdoffour#1}%
+ \fi
+}
+\def\texosqueryfmtpatzzzz#1{%
+ \expandafter\ifnum\@texosquery at fourthoffour#1=0
+   \expandafter\texosquerylongtimezone\expandafter{\@texosquery at thirdoffour#1}%
+ \else
+   \expandafter\texosquerylongdstzone\expandafter{\@texosquery at thirdoffour#1}%
+ \fi
+}
+\def\texosqueryfmtpatZ#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+   {\@texosquery at firstoffour#1}%
+  \expandafter\texosqueryfmttimezonemin\expandafter
+   {\@texosquery at secondoffour#1}%
+}
+\def\texosqueryfmtpatZZ#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+\def\texosqueryfmtpatZZZ#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+\def\texosqueryfmtpatZZZZ#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+\def\texosqueryfmtpatX#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \texosquerytimesep
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+\def\texosqueryfmtpatXX#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \texosquerytimesep
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+\def\texosqueryfmtpatXXX#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \texosquerytimesep
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+\def\texosqueryfmtpatXXXX#1{%
+  \expandafter\texosqueryfmttimezonehr\expandafter
+    {\@texosquery at firstoffour#1}%
+  \texosquerytimesep
+  \expandafter\texosqueryfmttimezonemin\expandafter
+    {\@texosquery at secondoffour#1}%
+}
+\def\texosqueryfmtpata#1{%
+ \ifnum#1=0 AM\else PM\fi
+}
+\def\texosqueryfmtpataa{\texosqueryfmtpata}
+\def\texosqueryfmtpataaa{\texosqueryfmtpata}
+\def\texosqueryfmtpataaaa{\texosqueryfmtpata}
+\def\texosqueryfmtpatG#1{%
+ \ifnum#1=1 AD\else BC\fi
+}
+\def\texosqueryfmtpatGG{\texosqueryfmtpatG}
+\def\texosqueryfmtpatGGG{\texosqueryfmtpatG}
+\def\texosqueryfmtpatGGGG{\texosqueryfmtpatG}
+\def\texosqueryfmtnumber#1#2#3#4{%
+  \begingroup
+   \let\texosquerypatstr\texosquerypatfmtstr
+   \let\texosquerypatquote\texosquerypatfmtquote
+   \let\texosquerypatplusminus\texosquerypatfmt at plusminus
+   \let\texosquerypatnum\texosquerypatfmt at num
+   \let\texosquerypatsinum\texosquerypatfmt at sinum
+   \let\texosquerypatdec\texosquerypatfmt at dec
+   \let\texosquerypatprefixcurrency\texosquery at patfmt@prefixcurrency
+   \let\texosquerypatprefixicurrency\texosquery at patfmt@prefixicurrency
+   \let\texosquerypatsuffixcurrency\texosquery at patfmt@suffixcurrency
+   \let\texosquerypatsuffixicurrency\texosquery at patfmt@suffixicurrency
+   \let\texosquerypatdigit\texosquerypatfmt at digit
+   \let\texosquerypatdigitnozero\texosquerypatfmt at digitnozero
+   \let\texosquerypatgroupsep\texosquerypatfmt at groupsep
+   \let\texosquerypatprefixpercent\texosquery at patfmt@prefixpercent
+   \let\texosquerypatsuffixpercent\texosquery at patfmt@suffixpercent
+   \let\texosquerypatprefixpermill\texosquery at patfmt@prefixpermill
+   \let\texosquerypatsuffixpermill\texosquery at patfmt@suffixpermill
+   \let\texosquerypatminus\@texosquerypat at numfmt@sign
+   \let\texosquerypatfmt at decsep\texosquerypatfmtdecsep
+   \edef\@texosquery at sgn{%
+     \ifnum#2=0
+        \expandafter\ifnum#21<0 -\else+\fi
+     \else
+        \ifnum#2<0 -\else+\fi
+     \fi
+    }%
+   \edef\@texosquery at int{\expandafter\@texosquery at paddigits
+      \expandafter{\number#2}}%
+   \let\@texosquery at si@int\@texosquery at int
+   \edef\@texosquery at frac{\expandafter\@texosquery at paddigits@trailing
+     \expandafter{#3}}%
+   \let\@texosquery at si@frac\@texosquery at frac
+   \edef\@texosquery at mantissa{\expandafter\@texosquery at paddigits
+     \expandafter{\number#4}}%
+   \ifnum#4=0\relax
+   \else
+     \expandafter\ifx\@texosquery at sgn-%
+       \edef\@texosquery at int{\expandafter
+          \@texosquery at paddigits@pos\expandafter{\number-#2}}%
+     \else
+       \edef\@texosquery at int{\@texosquery at paddigits@pos{#2}}%
+     \fi
+     \ifnum#4<0
+       \expandafter\@texosquery at neg@shift\expandafter{\number-#4}%
+     \else
+       \@texosquery at pos@shift{#4}%
+     \fi
+     \expandafter\ifx\@texosquery at sgn-%
+       \edef\@texosquery at int{\expandafter\@texosquery at paddigits
+         \expandafter{\number-\@texosquery at int}}%
+     \else
+       \edef\@texosquery at int{\expandafter\@texosquery at paddigits
+         \expandafter{\number\@texosquery at int}}%
+     \fi
+     \edef\@texosquery at frac{\@texosquery at paddigits@trailing{\@texosquery at frac}}%
+   \fi
+   \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at int}%
+   \let\@texosquery at zerodigit\@texosquery at zerodigit@leading
+   \expandafter\ifx\@texosquery at sgn-%
+     \let\@texosquery at currentsign\texosquerypatfmtminus
+   \else
+     \let\@texosquery at currentsign\texosquerypatfmtplus
+   \fi
+   \@texosquery at digitindex=0\relax
+   \@texosquery at digitfoundfalse
+   #1%
+  \endgroup
+}
+\newcount\@texosquery at digitindex
+\newif\if at texosquery@digitfound
+\def\@texosquery at pos@shift#1{%
+  \ifcase#1
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastnineoften\@texosquery at int
+      \expandafter\@texosquery at firstoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastnineoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lasteightoften\@texosquery at int
+      \expandafter\@texosquery at firsttwooften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lasteightoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastsevenoften\@texosquery at int
+      \expandafter\@texosquery at firstthreeoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastsevenoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastsixoften\@texosquery at int
+      \expandafter\@texosquery at firstfouroften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastsixoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastfiveoften\@texosquery at int
+      \expandafter\@texosquery at firstfiveoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastfiveoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastfouroften\@texosquery at int
+      \expandafter\@texosquery at firstsixoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastfouroften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lastthreeoften\@texosquery at int
+      \expandafter\@texosquery at firstsevenoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lastthreeoften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at lasttwooften\@texosquery at int
+      \expandafter\@texosquery at firsteightoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at lasttwooften\@texosquery at frac
+    }%
+  \or
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at tenthoften\@texosquery at int
+      \expandafter\@texosquery at firstnineoften\@texosquery at frac}%
+    \edef\@texosquery at frac{%
+       \expandafter\@texosquery at tenthoften\@texosquery at frac
+    }%
+  \or
+    \let\@texosquery at int\@texosquery at frac
+    \edef\@texosquery at frac{0}%
+  \fi
+}
+\def\@texosquery at neg@shift#1{%
+  \ifcase#1
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastoneoften\@texosquery at int
+      \expandafter\@texosquery at firstnineoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstnineoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lasttwooften\@texosquery at int
+      \expandafter\@texosquery at firsteightoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firsteightoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastthreeoften\@texosquery at int
+      \expandafter\@texosquery at firstsevenoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstsevenoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastfouroften\@texosquery at int
+      \expandafter\@texosquery at firstsixoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstsixoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastfiveoften\@texosquery at int
+      \expandafter\@texosquery at firstfiveoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstfiveoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastsixoften\@texosquery at int
+      \expandafter\@texosquery at firstfouroften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstfouroften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastsevenoften\@texosquery at int
+      \expandafter\@texosquery at firstthreeoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstthreeoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lasteightoften\@texosquery at int
+      \expandafter\@texosquery at firsttwooften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firsttwooften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{%
+      \expandafter\@texosquery at lastnineoften\@texosquery at int
+      \expandafter\@texosquery at firstoften\@texosquery at frac
+    }%
+    \edef\@texosquery at int{%
+      \expandafter\@texosquery at firstoften\@texosquery at int
+    }%
+  \or
+    \edef\@texosquery at frac{\@texosquery at int\@texosquery at frac}%
+    \edef\@texosquery at int{0}%
+  \fi
+}
+\def\@texosquerypat at numfmt@sign{%
+  \@texosquery at currentsign
+  \let\@texosquery at currentsign\empty
+}
+\def\texosquerypatfmtstr#1{#1}
+\def\texosquerypatfmtquote{'}
+\def\texosquerypatfmt at plusminus#1#2{%
+ \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at int}%
+ \@texosquery at digitindex=0\relax
+ \@texosquery at digitfoundfalse
+ \expandafter\ifx\@texosquery at sgn-%
+  #2%
+  \ifnum\@texosquery at digitindex=10
+  \else
+   \@texosquery at invalidpattern{#2}%
+  \fi
+ \else
+  #1%
+  \ifnum\@texosquery at digitindex=10
+  \else
+   \@texosquery at invalidpattern{#1}%
+  \fi
+ \fi
+}
+\def\texosquerypatfmt at num#1{#1}
+\def\texosquerypatfmtexp{E}
+\def\texosquerypatfmt at sinum#1#2{%
+ \let\@texosquery at int\@texosquery at si@int
+ \let\@texosquery at frac\@texosquery at si@frac
+ \let\@texosquery at current\@texosquery at int
+ #1%
+ \texosquerypatfmtexp
+ {\let\@texosquery at zerodigit\@texosquery at zerodigit@leading
+ \ifnum\@texosquery at mantissa<0\relax
+   \let\@texosquery at currentsign\texosquerypatfmtminus
+ \else
+   \let\@texosquery at currentsign\texosquerypatfmtplus
+ \fi
+ \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at mantissa}%
+ \@texosquery at digitindex=0\relax
+ \@texosquery at digitfoundfalse
+ #2}}
+\def\texosquerypatfmtdecsep{.}
+\def\texosquerypatfmtcurdecsep{.}
+\def\texosquerypatfmt at dec#1#2{%
+ \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at int}%
+ \@texosquery at digitindex=0\relax
+ \@texosquery at digitfoundfalse
+ \let\@texosquery at zerodigit\@texosquery at zerodigit@leading
+ #1%
+ \ifnum\@texosquery at digitindex=10
+ \else
+  \@texosquery at invalidpattern{#1}%
+ \fi
+ \texosquerypatfmt at decsep
+ \let\@texosquery at current\@texosquery at frac
+ \@texosquery at digitindex=0\relax
+ \@texosquery at digitfoundfalse
+ \let\@texosquery at zerodigit\@texosquery at zerodigit@trailing
+ \let\@texosquery at currentsign\empty
+ #2%
+ \ifnum\@texosquery at digitindex=10
+ \else
+  \@texosquery at invalidpattern{#2}%
+ \fi
+}
+\def\texosquerypatfmtint#1{%
+ \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at int}%
+ \@texosquery at digitindex=0\relax
+ \@texosquery at digitfoundfalse
+ \let\@texosquery at zerodigit\@texosquery at zerodigit@leading
+ #1%
+ \ifnum\@texosquery at digitindex=10
+ \else
+  \@texosquery at invalidpattern{#1}%
+ \fi
+}
+\def\@texosquery at setpatdisplay{%
+   \def\texosquerypatstr##1{'##1'}%
+   \def\texosquerypatquote{''}%
+   \def\texosquerypatplusminus##1##2{##1;##2}%
+   \def\texosquerypatnum##1{##1}%
+   \def\texosquerypatsinum##1##2{##1E##2}%
+   \def\texosquerypatdec##1##2{##1.##2}%
+   \def\texosquerypatprefixcurrency##1##2{##2¤##1}%
+   \def\texosquerypatprefixicurrency##1##2{##2¤¤##1}%
+   \def\texosquerypatsuffixcurrency##1##2{##1¤##2}%
+   \def\texosquerypatsuffixicurrency##1##2{##1¤¤##2}%
+   \def\texosquerypatdigit{0}%
+   \def\texosquerypatdigitnozero{\#}%
+   \def\texosquerypatminus{-}%
+   \def\texosquerypatgroupsep{,}%
+   \def\texosquerypatprefixpercent##1##2{##2\%##1}%
+   \def\texosquerypatsuffixpercent##1##2{##1\%##2}%
+   \def\texosquerypatprefixpermill##1##2{##2‰##1}%
+   \def\texosquerypatsuffixpermill##1##2{##1‰##2}%
+   \def\texosquerypatfmt at decsep{.}%
+}
+\def\@texosquery at invalidpattern#1{%
+  \begingroup
+   \@texosquery at setpatdisplay
+   \@texosquery at err{10 digit specifiers expected in
+    numeric pattern #1. Found \number\@texosquery at digitindex}%
+    {Each integer element of a numeric pattern must have exactly
+     10 digit specifiers (0 or \#)}%
+  \endgroup
+}
+\def\texosquerypatfmtcurrencysign{\$}
+\ifx\textcurrency\undefined
+  \def\texosquerypatfmticurrencysign{¤}
+\else
+  \def\texosquerypatfmticurrencysign{\textcurrency}
+\fi
+\def\texosquery at patfmt@prefixcurrency#1#2{%
+ \let\texosquerypatfmt at decsep\texosquerypatfmtcurdecsep
+ #2\texosquerypatfmtcurrencysign#1%
+}
+\def\texosquery at patfmt@prefixicurrency#1#2{%
+ \let\texosquerypatfmt at decsep\texosquerypatfmtcurdecsep
+ #2\texosquerypatfmticurrencysign#1%
+}
+\def\texosquery at patfmt@suffixcurrency#1#2{%
+ \let\texosquerypatfmt at decsep\texosquerypatfmtcurdecsep
+ #1\texosquerypatfmtcurrencysign#2%
+}
+\def\texosquery at patfmt@suffixicurrency#1#2{%
+ \let\texosquerypatfmt at decsep\texosquerypatfmtcurdecsep
+ #1\texosquerypatfmticurrencysign#2%
+}
+\def\texosquerypatfmt at digit{%
+ \advance\@texosquery at digitindex by 1\relax
+ \if at texosquery@digitfound
+ \else
+   \ifx\@texosquery at currentsign\texosquerypatfmtminus
+    \texosquerypatfmtminus
+    \let\@texosquery at currentsign\empty
+   \fi
+ \fi
+ \@texosquery at digitfoundtrue
+ \ifcase\@texosquery at digitindex
+ \or
+   \expandafter\@texosquery at firstoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at secondoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at thirdoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at fourthoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at fifthoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at sixthoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at seventhoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at eighthoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at ninthoften\@texosquery at current
+ \or
+   \expandafter\@texosquery at tenthoften\@texosquery at current
+ \fi
+}
+\def\texosquerypatfmt at digitnozero{%
+ \advance\@texosquery at digitindex by 1\relax
+ \edef\@texosquery at digit{%
+   \ifcase\@texosquery at digitindex
+    0%
+   \or
+     \expandafter\@texosquery at firstoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at secondoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at thirdoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at fourthoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at fifthoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at sixthoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at seventhoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at eighthoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at ninthoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at tenthoften\@texosquery at current
+   \else
+   0%
+ \fi
+ }%
+ \ifnum\@texosquery at digit=0\relax
+   \@texosquery at zerodigit
+ \else
+   \if at texosquery@digitfound
+   \else
+     \ifx\@texosquery at currentsign\texosquerypatfmtminus
+      \texosquerypatfmtminus
+      \let\@texosquery at currentsign\empty
+     \fi
+   \fi
+   \@texosquery at digitfoundtrue
+   \@texosquery at digit
+ \fi
+}
+\def\@texosquery at zerodigit@leading{%
+ \edef\@texosquery at digit{%
+   \ifcase\@texosquery at digitindex
+    0%
+   \or
+     \expandafter\@texosquery at firstoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firsttwooften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstthreeoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstfouroften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstfiveoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstsixoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstsevenoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firsteightoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at firstnineoften\@texosquery at current
+   \or
+     \@texosquery at current
+   \else
+    0%
+   \fi
+  }%
+  \ifnum\@texosquery at digit>0\relax
+   \if at texosquery@digitfound
+   \else
+     \ifx\texosquerypatminus\texosquerypatfmtminus
+      \texosquerypatfmtminus
+     \fi
+   \fi
+   \@texosquery at digitfoundtrue
+   0%
+  \fi
+}
+\def\@texosquery at zerodigit@trailing{%
+ \edef\@texosquery at digit{%
+   \ifcase\@texosquery at digitindex
+    0%
+   \or
+     \@texosquery at current
+   \or
+     \expandafter\@texosquery at lastnineoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lasteightoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lastsevenoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lastsixoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lastfiveoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lastfouroften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lastthreeoften\@texosquery at current
+   \or
+     \expandafter\@texosquery at lasttwooften\@texosquery at current
+   \or
+     \expandafter\@texosquery at tenthoften\@texosquery at current
+   \else
+    0%
+   \fi
+  }%
+  \ifnum\@texosquery at digit>0\relax
+   \if at texosquery@digitfound
+   \else
+     \ifx\texosquerypatminus\texosquerypatfmtminus
+      \texosquerypatfmtminus
+     \fi
+   \fi
+   \@texosquery at digitfoundtrue
+   0%
+  \fi
+}
+\def\texosquerypatfmtminus{\ifmmode-\else$-$\fi}
+\def\texosquerypatfmtplus{\ifmmode+\else$+$\fi}
+\def\texosquerypatfmtgroupsep{,}
+\def\texosquerypatfmt at groupsep{%
+  \if at texosquery@digitfound\texosquerypatfmtgroupsep\fi}
+\def\texosquerypatfmtpercentsign{\%}
+\def\texosquerypatfmtpermillsign{‰}
+\def\@texosquery at adjust@per#1{%
+ \@texosquery at pos@shift{#1}%
+ \edef\@texosquery at int{\expandafter\@texosquery at paddigits
+     \expandafter{\number\@texosquery at int}}%
+ \edef\@texosquery at frac{\@texosquery at paddigits@trailing{\@texosquery at frac}}%
+ \edef\@texosquery at current{\expandafter\@texosquery at gobble\@texosquery at int}%
+}
+\def\texosquery at patfmt@prefixpercent#1#2{%
+ \@texosquery at adjust@per{2}%
+  #2\texosquerypatfmtpercentsign#1%
+}
+\def\texosquery at patfmt@suffixpercent#1#2{%
+ \@texosquery at adjust@per{2}%
+ #1\texosquerypatfmtpercentsign#2%
+}
+\def\texosquery at patfmt@prefixpermill#1#2{%
+ \@texosquery at adjust@per{3}%
+ #2\texosquerypatfmtpermillsign#1%
+}
+\def\texosquery at patfmt@suffixpermill#1#2{%
+ \@texosquery at adjust@per{3}%
+ #1\texosquerypatfmtpermillsign#2%
+}
 \@texosquery at restore@at
 \endinput
 %%

Modified: trunk/Master/tlpkg/libexec/ctan2tds
===================================================================
--- trunk/Master/tlpkg/libexec/ctan2tds	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/tlpkg/libexec/ctan2tds	2017-03-24 22:42:34 UTC (rev 43596)
@@ -2293,7 +2293,7 @@
  'rcs',                 'rcs.el|src|' . $standardsource,
  'ruhyphen',            '^[^.]*$|README.ru|hyphen.rules',
  'selnolig',            'NULL',                 # not .fea
- 'texosquery',		'.java|' . $standardsource,
+ 'texosquery',		'java|\.batch$|' . $standardsource,
  'thailatex',           'NULL',                 # no gain in splitting up
  'translation-array-fr',        'NULL',         # doc
  'translation-chemsym-de',      'NULL',         # doc
@@ -2843,7 +2843,7 @@
  'texfot'               => 'texfot\.pl$',
  'texliveonfly'         => '\.py$',
  'texloganalyser'       => 'texloganalyser',
- 'texosquery'		=> 'texosquery$',
+ 'texosquery'		=> 'texosquery(|-jre[5-9])\.sh$',
  'typeoutfileinfo'      => '\.sh$',
  'thumbpdf'             => '\.pl$',
  'ulqda'                => '\.pl$',

Modified: trunk/Master/tlpkg/tlpsrc/texosquery.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/texosquery.tlpsrc	2017-03-24 22:27:33 UTC (rev 43595)
+++ trunk/Master/tlpkg/tlpsrc/texosquery.tlpsrc	2017-03-24 22:42:34 UTC (rev 43596)
@@ -1,2 +1,2 @@
 binpattern f bin/${ARCH}/${PKGNAME}
-
+binpattern f bin/${ARCH}/${PKGNAME}-jre*



More information about the tex-live-commits mailing list