Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More optimization #2149

Merged
merged 9 commits into from
Jul 13, 2023
9 changes: 8 additions & 1 deletion lib/LaTeXML/Common/Error.pm
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ our @EXPORT = (
# Progress Spinner
qw(&ProgressSpinup &ProgressSpindown &ProgressStep),
# Debugging messages
qw(&DebuggableFeature &Debug &CheckDebuggable),
qw(&DebuggableFeature &Debug &CheckDebuggable &Deprecated),
# Colored-logging related functions
qw(&colorizeString),
# stateless message generation
Expand Down Expand Up @@ -486,6 +486,13 @@ sub CheckDebuggable {
print STDERR _freshline(\*STDERR), "Known debugging features: " . join(', ', sort keys %LaTeXML::Debuggable) . "\n"; }
return; }

sub Deprecated {
my ($key, $version, $message) = @_;
return if $STATE && $STATE->lookupMapping('DEPRECATIONS_WARNED', $key);
Warn('deprecated', $key, undef, "$key is deprecated (as of $version)", $message);
$STATE->assignMapping('DEPRECATIONS_WARNED', $key => 1) if $STATE;
return; }

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Handlers for perl's die & warn
# We'll try to decode some common errors to make them more usable
Expand Down
17 changes: 10 additions & 7 deletions lib/LaTeXML/Core/Definition/Conditional.pm
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ sub new {
my ($class, $cs, $parameters, $test, %traits) = @_;
my $source = $STATE->getStomach->getGullet->getMouth;
return bless { cs => $cs, parameters => $parameters, test => $test,
locator => $source->getLocator,
isExpandable => 1,
locator => $source->getLocator,
%traits }, $class; }

sub isExpandable {
return 1; }

sub getTest {
my ($self) = @_;
return $$self{test}; }

# This MUST return Tokens() or undef. (NOT a Token)
sub invoke {
my ($self, $gullet) = @_;
# A real conditional must have condition_type set
Expand Down Expand Up @@ -132,17 +135,17 @@ sub skipConditionalBody {
shift(@$stack); } # then DO pop that conditional's frame; it's DONE!
elsif (!--$level) { # If no more nesting, we're done.
shift(@$stack); # Done with this frame
return $t; } } # AND Return the finishing token.
return TokensI($t); } } # AND Return the finishing token.
elsif ($level > 1) { } # Ignore \else,\or nested in the body.
elsif (($cond_type eq 'or') && (++$n_ors == $nskips)) {
return $t; }
return TokensI($t); }
elsif (($cond_type eq 'else') && $nskips
# Found \else and we're looking for one?
# Make sure this \else is NOT for a nested \if that is part of the test clause!
&& ($$stack[0] eq $LaTeXML::IFFRAME)) {
# No need to actually call elseHandler, but note that we've seen an \else!
$$stack[0]{elses} = 1;
return $t; } } # } #}
return TokensI($t); } } # } #}
Error('expected', '\fi', $gullet, "Missing \\fi or \\else, conditional fell off end",
"Conditional started at " . ToString($start));
return; }
Expand All @@ -156,7 +159,7 @@ sub invoke_else {
. " since we seem not to be in a conditional");
return; }
elsif ($$stack[0]{parsing}) { # Defer expanding the \else if we're still parsing the test
return Tokens(T_CS('\relax'), $LaTeXML::CURRENT_TOKEN); }
return TokensI(T_CS('\relax'), $LaTeXML::CURRENT_TOKEN); }
elsif ($$stack[0]{elses}) { # Already seen an \else's at this level?
Error('unexpected', $LaTeXML::CURRENT_TOKEN, $gullet,
"Extra " . Stringify($LaTeXML::CURRENT_TOKEN),
Expand All @@ -180,7 +183,7 @@ sub invoke_fi {
. " since we seem not to be in a conditional");
return; }
elsif ($$stack[0]{parsing}) { # Defer expanding the \else if we're still parsing the test
return Tokens(T_CS('\relax'), $LaTeXML::CURRENT_TOKEN); }
return TokensI(T_CS('\relax'), $LaTeXML::CURRENT_TOKEN); }
else { # "expand" by removing the stack entry for this level
local $LaTeXML::IFFRAME = $$stack[0];
$STATE->shiftValue('if_stack'); # Done with this frame
Expand Down
47 changes: 28 additions & 19 deletions lib/LaTeXML/Core/Definition/Expandable.pm
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,27 @@ use base qw(LaTeXML::Core::Definition);

sub new {
my ($class, $cs, $parameters, $expansion, %traits) = @_;
$expansion = Tokens($expansion) if ref $expansion eq 'LaTeXML::Core::Token';
my $source = $STATE->getStomach->getGullet->getMouth;
if (ref $expansion eq 'LaTeXML::Core::Tokens') {
my $type = ref $expansion;
# expansion must end up Tokens or CODE
if (!$type) {
$expansion = TokenizeInternal($expansion)->packParameters; }
elsif ($type eq 'LaTeXML::Core::Token') {
$expansion = TokensI($expansion); }
elsif ($type eq 'LaTeXML::Core::Tokens') {
Fatal('misdefined', $cs, $source, "Expansion of '" . ToString($cs) . "' has unbalanced {}",
"Expansion is " . ToString($expansion)) unless $expansion->isBalanced;
$expansion = $expansion->packParameters unless $traits{nopackParameters}; }
elsif (!ref $expansion) {
$expansion = TokenizeInternal($expansion)->packParameters; }

elsif ($type ne 'CODE') {
Error('misdefined', $cs, $source,
"Expansion of '" . ToString($cs) . "' cannot be of type '$type'");
$expansion = TokensI(); }
return bless { cs => $cs, parameters => $parameters, expansion => $expansion,
locator => $source->getLocator,
isProtected => $traits{protected} || $STATE->getPrefix('protected'),
isOuter => $traits{outer} || $STATE->getPrefix('outer'),
isLong => $traits{long} || $STATE->getPrefix('long'),
isExpandable => 1,
locator => $source->getLocator,
isProtected => $traits{protected} || $STATE->getPrefix('protected'),
isOuter => $traits{outer} || $STATE->getPrefix('outer'),
isLong => $traits{long} || $STATE->getPrefix('long'),
hasCCARG => (($type ne 'CODE') && (grep { $$_[1] == CC_ARG; } $expansion->unlist) ? 1 : 0),
%traits }, $class; }

sub isExpandable {
Expand All @@ -49,6 +55,7 @@ sub getExpansion {
return $$self{expansion}; }

# Expand the expandable control sequence. This should be carried out by the Gullet.
# This MUST return Tokens() or undef. (NOT a Token)
sub invoke {
no warnings 'recursion';
my ($self, $gullet, $onceonly) = @_;
Expand Down Expand Up @@ -80,20 +87,22 @@ sub invoke {
Error('recursion', $$self{cs}, $gullet,
"Token " . Stringify($$self{cs}) . " expands into itself!",
"defining as empty");
$expansion = Tokens(); } }
$expansion = TokensI(); } }
$result = $expansion; }
else {
my @args = $parms->readArguments($gullet, $self);
# for "real" macros, make sure all args are Tokens
my $r;
my @targs = map { ($_ && ($r = ref $_)
&& (($r eq 'LaTeXML::Core::Token') || ($r eq 'LaTeXML::Core::Tokens'))
? $_ : Tokens(Revert($_))); } @args;
if ($$self{hasCCARG}) { # Do we actually need to substitute the args in?
my $r; # Make sure they are actually Tokens!
@args = map { ($_ && ($r = ref $_)
&& (($r eq 'LaTeXML::Core::Token') || ($r eq 'LaTeXML::Core::Tokens'))
? $_ : Tokens(Revert($_))); } @args;
$result = $expansion->substituteParameters(@args); }
else {
$result = $expansion; }
if ($tracing) { # More involved...
Debug($self->tracingCSName . ' ->' . tracetoString($expansion));
Debug($self->tracingArgs(@targs)) if @args; }
$result = $expansion->substituteParameters(@targs); }
# Getting exclusive requires dubious Gullet support!
Debug($self->tracingArgs(@args)) if @args; } }
# Getting exclusive profiling requires dubious Gullet support!
$result = Tokens($result, T_MARKER($profiled)) if $profiled;
return $result; }

Expand Down
Loading