diff --git a/lib/LaTeXML/Common/XML/XSLT.pm b/lib/LaTeXML/Common/XML/XSLT.pm
index a0f7cfda95..936eb1c29b 100644
--- a/lib/LaTeXML/Common/XML/XSLT.pm
+++ b/lib/LaTeXML/Common/XML/XSLT.pm
@@ -31,5 +31,9 @@ sub transform {
my ($self, $document, %params) = @_;
return $$self{stylesheet}->transform($document, %params); }
+sub register_function {
+ my ($self, $uri, $name, $subref) = @_;
+ return $$self{stylesheet}->register_function($uri, $name, $subref); }
+
#======================================================================
1;
diff --git a/lib/LaTeXML/Post/XSLT.pm b/lib/LaTeXML/Post/XSLT.pm
index 385269cd88..c8799e0d5d 100644
--- a/lib/LaTeXML/Post/XSLT.pm
+++ b/lib/LaTeXML/Post/XSLT.pm
@@ -59,6 +59,14 @@ sub process {
return unless $$self{stylesheet};
# # Set up the Stylesheet parameters; making pathname parameters relative to document
my %params = %{ $$self{parameters} };
+ # set up XSLT extension function f:_copy-resource(src, type)
+ $$self{stylesheet}->register_function('http://dlmf.nist.gov/LaTeXML/functions', '_copy-resource', sub {
+ # values can be scalars or XML::LibXML::NodeList
+ my ($src, $type) = @_;
+ return Warn('malformed', '', $self, 'f:_copy-resource() requires at least one argument') unless defined $src;
+ # string interpolation converts node lists to the concatenation of all the string values
+ return $self->copyResource($doc, "$src", defined $type ? ("$type") : ());
+ });
# Deal with any resources embedded within the document
if (my @resnodes = $doc->findnodes('//ltx:resource[@src]')) {
if ($$self{noresources}) {
diff --git a/lib/LaTeXML/resources/XSLT/LaTeXML-common.xsl b/lib/LaTeXML/resources/XSLT/LaTeXML-common.xsl
index c0219ae2c5..40c8ef0cc3 100644
--- a/lib/LaTeXML/resources/XSLT/LaTeXML-common.xsl
+++ b/lib/LaTeXML/resources/XSLT/LaTeXML-common.xsl
@@ -154,6 +154,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+