Skip to content

Commit

Permalink
Non urls (#2213)
Browse files Browse the repository at this point in the history
* url.sty macros don't create hyperlinks; Safer internal macronames

* hyperref macros with * don't make hyperlinks; safer internal macro names

* \cref* doesn't create hyperlinks

* Update url.sty test cases
  • Loading branch information
brucemiller authored Sep 26, 2023
1 parent fb0fedd commit a7eeaa3
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 73 deletions.
36 changes: 19 additions & 17 deletions lib/LaTeXML/Package/cleveref.sty.ltxml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ sub splitLabels {
return split(/\s*,\s*/, ToString($labels)); }

sub crefMulti {
my ($labels, $showtype, $capitalized) = @_;
my ($starred, $labels, $showtype, $capitalized) = @_;
my @labels = splitLabels($labels);
if (scalar(@labels) < 2) {
return Invocation(T_CS('\lx@cref'),
$starred,
T_OTHER($showtype
? ($capitalized
? "creftypecap~refnum"
Expand All @@ -57,6 +58,7 @@ sub crefMulti {
$labels[0]); }
else {
my @tokens = (Invocation(T_CS('\lx@cref'),
$starred,
T_OTHER($showtype
? ($capitalized
? "creftypepluralcap~refnum"
Expand All @@ -65,37 +67,37 @@ sub crefMulti {
shift(@labels)));
if (scalar(@labels == 1)) {
push(@tokens, T_CS('\crefpairconjunction'),
Invocation(T_CS('\lx@cref'), T_OTHER('refnum'), $labels[0])); }
Invocation(T_CS('\lx@cref'), $starred, T_OTHER('refnum'), $labels[0])); }
else {
while (scalar(@labels) > 1) {
push(@tokens, T_CS('\crefmiddleconjunction'),
Invocation(T_CS('\lx@cref'), T_OTHER('refnum'), shift(@labels))); }
Invocation(T_CS('\lx@cref'), $starred, T_OTHER('refnum'), shift(@labels))); }
push(@tokens, T_CS('\creflastconjunction'),
Invocation(T_CS('\lx@cref'), T_OTHER('refnum'), shift(@labels))); }
Invocation(T_CS('\lx@cref'), $starred, T_OTHER('refnum'), shift(@labels))); }
return @tokens; } }
# Since we're not grouping by type, we're ignoring \crefpairgroupconjunction, etc

DefConstructor('\lx@cref {} Semiverbatim',
"<ltx:ref labelref='#label' show='#1' _force_font='true'/>",
properties => sub { (label => CleanLabel($_[2])); });
DefConstructor('\lx@cref OptionalMatch:* {} Semiverbatim',
"<ltx:ref labelref='#label' show='#2' ?#1(class='ltx_nolink')() _force_font='true'/>",
properties => sub { (label => CleanLabel($_[3])); });

DefMacro('\cref OptionalMatch:* Semiverbatim', sub { crefMulti($_[2], 1, 0); });
DefMacro('\Cref OptionalMatch:* Semiverbatim', sub { crefMulti($_[2], 1, 1); });
DefMacro('\cref OptionalMatch:* Semiverbatim', sub { crefMulti($_[1], $_[2], 1, 0); });
DefMacro('\Cref OptionalMatch:* Semiverbatim', sub { crefMulti($_[1], $_[2], 1, 1); });

DefMacro('\crefrange OptionalMatch:* Semiverbatim Semiverbatim',
'\lx@cref{creftypeplural~refnum}{#2}\crefrangeconjunction\ref{#3}');
'\lx@cref#1{creftypeplural~refnum}{#2}\crefrangeconjunction\ref{#3}');
DefMacro('\Crefrange OptionalMatch:* Semiverbatim Semiverbatim',
'\lx@cref{creftypepluralcap~refnum}{#2}\crefrangeconjunction\ref{#3}');
'\lx@cref#1{creftypepluralcap~refnum}{#2}\crefrangeconjunction\ref{#3}');

# Make page refs same as regular?
DefMacro('\cpageref OptionalMatch:* Semiverbatim', sub { crefMulti($_[2], 1, 0); });
DefMacro('\Cpageref OptionalMatch:* Semiverbatim', sub { crefMulti($_[2], 1, 1); });
DefMacro('\cpageref OptionalMatch:* Semiverbatim', sub { crefMulti($_[1], $_[2], 1, 0); });
DefMacro('\Cpageref OptionalMatch:* Semiverbatim', sub { crefMulti($_[1], $_[2], 1, 1); });

# More likely with page ranges that the types are different?
DefMacro('\cpagerefrange OptionalMatch:* Semiverbatim Semiverbatim',
'\lx@cref{creftype~refnum}{#2}\crefrangeconjunction\lx@cref{creftype~refnum}{#3}');
'\lx@cref#1{creftype~refnum}{#2}\crefrangeconjunction\lx@cref#1{creftype~refnum}{#3}');
DefMacro('\Cpagerefrange OptionalMatch:* Semiverbatim Semiverbatim',
'\lx@cref{creftypecap~refnum}{#2}\crefrangeconjunction\lx@ref{creftype~refnum{#3}');
'\lx@cref#1{creftypecap~refnum}{#2}\crefrangeconjunction\lx@cref#1{creftype~refnum{#3}');

DefMacro('\namecref Semiverbatim', '\lx@cref{creftype}{#1}');
DefMacro('\nameCref Semiverbatim', '\lx@cref{creftypecap}{#1}');
Expand All @@ -104,8 +106,8 @@ DefMacro('\nameCrefs Semiverbatim', '\lx@cref{creftypepluralcap}{#1}');
DefMacro('\lcnamecref Semiverbatim', '\lx@cref{creftype}{#1}');
DefMacro('\lcnamecrefs Semiverbatim', '\lx@cref{creftypeplural}{#1}');

DefMacro('\labelcref Semiverbatim', sub { crefMulti($_[1], 0, 0); });
DefMacro('\labelcpageref Semiverbatim', sub { crefMulti($_[1], 0, 0); });
DefMacro('\labelcref Semiverbatim', sub { crefMulti(undef, $_[1], 0, 0); });
DefMacro('\labelcpageref Semiverbatim', sub { crefMulti(undef, $_[1], 0, 0); });

# No, this isn't quite the same thing...
DefPrimitive('\crefalias {}{}', sub {
Expand Down
22 changes: 17 additions & 5 deletions lib/LaTeXML/Package/hyperref.sty.ltxml
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,12 @@ DefRegister('\pdfcompresslevel', Number(0));
# Additional User Macros

# \href{url}{text}
DefMacro('\href HyperVerbatim {}', '\@@Url\href{}{}{#1}{#2}');
DefMacro('\href HyperVerbatim {}', '\lx@hyper@url@\href{}{}{#1}{#2}');

# \url{url} from url.sty... well sorta
# Redefine \url{url} from url.sty...
# It's slightly different in that it expands the argument
# Redefine \@url to sanitize the argument less
DefMacro('\@Url Token', sub {
DefMacro('\lx@hyper@url Token', sub {
my ($gullet, $cmd) = @_;
my ($open, $close, $url);
$open = $gullet->readToken;
Expand All @@ -174,14 +174,26 @@ DefMacro('\@Url Token', sub {
my @toks = grep { $_->getCatcode != CC_SPACE; } $url->unlist;
# Identical with url's \@Url except, let CS's through!
@toks = map { (($_->getCatcode == CC_CS) ? $_ : T_OTHER(ToString($_))) } @toks;
(Invocation(T_CS('\@@Url'),
(Invocation(T_CS('\lx@hyper@url@'),
T_OTHER(ToString($cmd)), Tokens($open), Tokens($close),
Tokens(@toks),
Tokens(T_CS('\UrlFont'), T_CS('\UrlLeft'), @toks, T_CS('\UrlRight')))->unlist,
T_CS('\endgroup')); });

# RE-define from url w
DefMacro('\url', '\begingroup\lx@hyper@url\url', locked => 1);

DefConstructor('\lx@hyper@url@ Undigested {}{} Semiverbatim {}',
"?#isMath(<ltx:XMWrap class='#class' href='#href'>#5</ltx:XMWrap>)" # Allow this to work in Math!
. " (<ltx:ref href='#href' class='#class'>#5</ltx:ref>)",
properties => sub { (href => ComposeURL(LookupValue('BASE_URL'), $_[4]),
class => sub { my $c = ToString($_[1]); $c =~ s/^\\//; 'ltx_' . $c; }); },
sizer => '#5',
reversion => '#1#2#4#3');

# \nolinkurl{url}
DefConstructor('\nolinkurl Semiverbatim', '#1');
DefConstructor('\nolinkurl Semiverbatim',
"<ltx:ref href='#1' class='ltx_nolink' >#1</ltx:ref>");

# \hyperbaseurl{url}
DefPrimitive('\hyperbaseurl Semiverbatim', sub { AssignValue(BASE_URL => ToString($_[1])); });
Expand Down
19 changes: 10 additions & 9 deletions lib/LaTeXML/Package/url.sty.ltxml
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ Let('\UrlRight', '\@empty');

# \DeclareUrlCommand\cmd{settings}
# Have this expand into \@Url w/ the declared cmd as arg, so it gets reflected in XML.
DefMacro('\DeclareUrlCommand{}{}', '\def#1{\begingroup #2\@Url#1}');
DefMacro('\DeclareUrlCommand{}{}', '\def#1{\begingroup #2\lx@url@url#1}');

# This is an extended version of \Url that takes an extra token as 1st arg.
# That token is the cs that invoked it, so that it can be reflected in the generated XML,
# as well as used to generate the reversion.
# In any case, we read the verbatim arg, and build a Whatsit for @@Url
DefMacro('\@Url Token', sub {
DefMacro('\lx@url@url Token', sub {
my ($gullet, $cmd) = @_;
my ($open, $close, $url);
StartSemiverbatim('%');
Expand All @@ -58,7 +58,7 @@ DefMacro('\@Url Token', sub {
EndSemiverbatim();
my @toks = grep { $_->getCatcode != CC_SPACE; } (ref $url ? $url->unlist : ());
@toks = map { T_OTHER(ToString($_)) } @toks;
(Invocation(T_CS('\@@Url'),
(Invocation(T_CS('\lx@url@url@nolink'),
T_OTHER(ToString($cmd)), Tokens($open), Tokens($close),
Tokens(@toks),
Tokens(T_CS('\UrlFont'), T_CS('\UrlLeft'), @toks, T_CS('\UrlRight')))->unlist,
Expand All @@ -68,20 +68,21 @@ DefMacro('\@Url Token', sub {
DefMacro('\Url', sub {
my ($gullet) = @_;
$gullet->unread(T_OTHER('\Url'));
(T_CS('\@Url')); });
(T_CS('\lx@url@url')); });

# \@@Url cmd {open}{close}{url}{formattedurl}
DefConstructor('\@@Url Undigested {}{} Semiverbatim {}',
"?#isMath(<ltx:XMWrap href='#href'>#5</ltx:XMWrap>)" # Allow this to work in Math!
. " (<ltx:ref href='#href' class='#class'>#5</ltx:ref>)",
#DefConstructor('\@@Url Undigested {}{} Semiverbatim {}',
DefConstructor('\lx@url@url@nolink Undigested {}{} Semiverbatim {}',
"?#isMath(<ltx:XMWrap class='ltx_nolink #class' href='#href'>#5</ltx:XMWrap>)" # Allow this to work in Math!
. " (<ltx:ref href='#href' class='ltx_nolink #class'>#5</ltx:ref>)",
properties => sub { (href => ComposeURL(LookupValue('BASE_URL'), $_[4]),
class => sub { my $c = ToString($_[1]); $c =~ s/^\\//; 'ltx_' . $c; }); },
sizer => '#5',
reversion => '#1#2#4#3');

# These are the expansions of \DeclareUrlCommand
DefMacro('\path', '\begingroup\urlstyle{tt}\@Url\path');
DefMacro('\url', '\begingroup\@Url\url', locked => 1);
DefMacro('\path', '\begingroup\urlstyle{tt}\lx@url@url\path');
DefMacro('\url', '\begingroup\lx@url@url\url', locked => 1);

# \urldef{newcmd}\cmd{arg}
# Kinda tricky, since we need to get the expansion of \cmd as the value of \newcmd
Expand Down
Loading

0 comments on commit a7eeaa3

Please sign in to comment.