Skip to content

Commit

Permalink
Allocate (brucemiller#2460)
Browse files Browse the repository at this point in the history
* allocateRegister avoids allocating a \count... slot that is already used; NewCounter avoids redefining a counter that already was defined; uses internal arabic macro for \the<ctr>

* Define \lx@alloc@ as safe version of plain's \alloc@, latex's \e@alloc; defines internal \lx@counter@arabic

* Use new \lx@alloc@ for plain's \alloc@, latex's \e@alloc
  • Loading branch information
brucemiller authored Dec 28, 2024
1 parent 1301850 commit 74c0e05
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 16 deletions.
5 changes: 5 additions & 0 deletions lib/LaTeXML/Engine/LaTeX.pool.ltxml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ Let('\magnification', '\@undefined');
Let('\@empty', '\lx@empty');
Let('\@ifundefined', '\lx@ifundefined');

# Use Package's register allocation to avoid allocating same slot twice; and ALWAYS have room!
DefMacro('\e@alloc{}{}{}{}{}{}', '\lx@alloc@{#1}{#3}{#2}{#6}', locked => 1);
DefMacro('\e@ch@ck{}{}{}{}', '', locked => 1);

#**********************************************************************
# Basic \documentclass & \documentstyle

Expand Down Expand Up @@ -771,6 +775,7 @@ sub beginAppendices {
else {
NewCounter($counter, 'document', idprefix => 'A');
DefMacroI('\the' . $counter, undef, '\Alph{' . $counter . '}', scope => 'global'); }
SetCounter($counter => Number(0)); # In case register was already defined
AssignMapping('counter_for_type', appendix => $counter);
Let(T_CS('\\' . $counter), T_CS('\@@appendix'), 'global');
Let(T_CS('\@appendix'), T_CS('\relax'), 'global');
Expand Down
22 changes: 22 additions & 0 deletions lib/LaTeXML/Engine/TeX_Registers.pool.ltxml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,28 @@ DefPrimitive('\muskipdef SkipSpaces Token SkipSpaces SkipMatch:=', sub {
DefPrimitive('\toksdef SkipSpaces Token SkipSpaces SkipMatch:=', sub {
shorthandDef($_[0], $_[1], '\toks', Tokens()); });

# Candidate for use defining plain's \alloc@ and latex's \e@alloc
our %stored_registers = (
'\countdef' => 1, '\dimendef' => 1, '\skipdef' => 1, '\muskipdef' => 1, '\toksdef' => 1);
DefMacro('\lx@alloc@ DefToken {} {} DefToken', sub {
my ($gullet, $type, $tracker, $allocator, $cs) = @_;
$type = ToString($type);
$tracker = ToString($tracker);
my $next;
if ($stored_registers{ ToString($allocator) }) {
$next = LaTeXML::Package::allocateRegister($type);
$next =~ s/^\Q$type\E//; }
else {
my $xnext = $STATE->lookupValue($tracker) || Number(0);
$next = $xnext->valueOf + 1; }
$STATE->assignValue($tracker => Number($next), 'global');
return Tokens(T_CS('\allocationnumber'), Explode($next), T_CS('\relax'),
T_CS('\global'), $allocator, $cs, T_OTHER('='), T_CS('\allocationnumber')); });

# Out of place, but utility for LaTeX-style \the<ctr>; used by Package's NewCounter
DefMacro('\lx@counter@arabic{}', sub {
ExplodeText(CounterValue(ToString(Expand($_[1])))->valueOf); });

#======================================================================
# Numeric Registers
#----------------------------------------------------------------------
Expand Down
13 changes: 4 additions & 9 deletions lib/LaTeXML/Engine/plain.pool.ltxml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ DefPrimitive('\wlog{}', sub {
NoteLog(ToString(Expand($_[1])));
return; },
locked => 1);

# Use Package's register allocation to avoid allocating same slot twice; and ALWAYS have room!
DefMacro('\alloc@{}{}{}{}{}', '\lx@alloc@{#2}{\count1#1}{#3}{#5}', locked => 1);
DefMacro('\ch@ck{}{}{}', '', locked => 1);
# From plain.tex
RawTeX(<<'EoTeX');
\outer\def\newcount{\alloc@0\count\countdef\insc@unt}
Expand All @@ -211,18 +215,9 @@ RawTeX(<<'EoTeX');
\outer\def\newfam{\alloc@8\fam\chardef\sixt@@n}
\outer\def\newlanguage{\alloc@9\language\chardef\@cclvi}
EoTeX
DefMacro('\e@alloc{}{}{}{}{}{}',
'\global\advance#3\@ne
% \e@ch@ck{#3}{#4}{#5}#1%
\allocationnumber#3\relax
\global#2#6\allocationnumber
% \wlog{\string#6=\string#1\the\allocationnumber}
');
DefMacro('\alloc@{}{}{}{}', '\e@alloc#2#3{\count1#1}#4\float@count');

# This implementation is quite wrong
DefPrimitive('\newinsert Token', sub { DefRegisterI($_[1], undef, Number(0)); });
# \alloc@, \ch@ck

# TeX plain uses \newdimen, etc. for these.
# Is there any advantage to that?
Expand Down
22 changes: 15 additions & 7 deletions lib/LaTeXML/Package.pm
Original file line number Diff line number Diff line change
Expand Up @@ -597,9 +597,12 @@ sub allocateRegister {
if (my $addr = $allocations{$type}) { # $addr is a Register but MUST be stored as \count<#>
if (my $n = $STATE->lookupValue($addr)) {
my $next = $n->valueOf + 1;
my $loc = $type . $next;
while ($STATE->isValueBound($loc)) {
$next++; $loc = $type . $next; }
$STATE->assignValue($addr => Number($next), 'global');
return $type . $next; }
else { # If allocations not set up, punt to unallocated register
return $loc; }
else { # If allocations not set up, punt to unallocated register
return; } }
else {
Error('misdefined', $type, undef, "Type $type is not an allocated register type");
Expand Down Expand Up @@ -634,8 +637,15 @@ sub NewCounter {
my $unctr = "UN$ctr"; # UNctr is counter for generating ID's for UN-numbered items.
if ($within && ($within ne 'document') && !LookupDefinition(T_CS("\\c\@$within"))) {
NewCounter($within); }
my $cs = T_CS("\\c\@$ctr");
DefRegisterI($cs, undef, Number(0), allocate => '\count');
my $cs = T_CS("\\c\@$ctr");
my $prevdefn = $STATE->lookupMeaning($cs);
if ($prevdefn && ((ref $prevdefn) eq 'LaTeXML::Core::Definition::Register')
&& (($$prevdefn{address} || '') =~ /^\\count/)) {
Info('unexpected', $cs, undef, "Counter $ctr was already allocated, skipping"); }
else {
Warn('unexpected', $cs, undef,
"Counter " . ToString($cs) . " was already defined as $prevdefn; redefining") if $prevdefn;
DefRegisterI($cs, undef, Number(0), allocate => '\count'); }
AfterAssignment();
AssignValue("\\cl\@$ctr" => Tokens(), 'global') unless LookupValue("\\cl\@$ctr");
DefRegisterI(T_CS("\\c\@$unctr"), undef, Number(0));
Expand All @@ -649,9 +659,7 @@ sub NewCounter {
'global') if $within;
AssignValue('nested_counters_' . $ctr => $options{nested}, 'global') if $options{nested};
# default is equivalent to \arabic{ctr}, but w/o using the LaTeX macro!
DefMacroI(T_CS("\\the$ctr"), undef, sub {
ExplodeText(CounterValue($ctr)->valueOf); },
scope => 'global');
DefMacroI(T_CS("\\the$ctr"), undef, "\\lx\@counter\@arabic{$ctr}", scope => 'global');
if (!LookupDefinition(T_CS("\\p\@$ctr"))) {
DefMacroI(T_CS("\\p\@$ctr"), undef, Tokens(), scope => 'global'); }
my $prefix = $options{idprefix};
Expand Down

0 comments on commit 74c0e05

Please sign in to comment.