File: Primitive.pm

package info (click to toggle)
latexml 0.8.8-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 31,920 kB
  • sloc: xml: 109,048; perl: 30,224; sh: 179; javascript: 28; makefile: 13
file content (123 lines) | stat: -rw-r--r-- 5,010 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# /=====================================================================\ #
# |  LaTeXML::Core::Definition::Primitive                               | #
# | Representation of definitions of Control Sequences                  | #
# |=====================================================================| #
# | Part of LaTeXML:                                                    | #
# |  Public domain software, produced as part of work done by the       | #
# |  United States Government & not subject to copyright in the US.     | #
# |---------------------------------------------------------------------| #
# | Bruce Miller <bruce.miller@nist.gov>                        #_#     | #
# | http://dlmf.nist.gov/LaTeXML/                              (o o)    | #
# \=========================================================ooo==U==ooo=/ #
package LaTeXML::Core::Definition::Primitive;
use strict;
use warnings;
use LaTeXML::Global;
use LaTeXML::Common::Object;
use LaTeXML::Common::Error;
use LaTeXML::Core::Box;
use LaTeXML::Core::Token;
use LaTeXML::Core::Tokens;
use base qw(LaTeXML::Core::Definition);

# Known traits:
#    isPrefix : whether this primitive is a TeX prefix, \global, etc.
sub new {
  my ($class, $cs, $parameters, $replacement, %traits) = @_;
  Error('misdefined', $cs, $STATE->getStomach,
    "Primitive replacement for '" . ToString($cs) . "' is not a string or CODE",
    "Replacement is $replacement")
    if (ref $replacement) && (ref $replacement ne 'CODE');
  return bless { cs => $cs, parameters => $parameters, replacement => $replacement,
    locator => $STATE->getStomach->getGullet->getMouth->getLocator,
    %traits }, $class; }

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

sub executeBeforeDigest {
  my ($self, $stomach) = @_;
  local $LaTeXML::Core::State::UNLOCKED = 1;
  my @pre = grep { defined } @{ $$self{beforeDigest} || [] };
  return (map { &$_($stomach) } @pre); }

sub executeAfterDigest {
  my ($self, $stomach, @whatever) = @_;
  local $LaTeXML::Core::State::UNLOCKED = 1;
  my @post = grep { defined } @{ $$self{afterDigest} || [] };
  return (map { &$_($stomach, @whatever) } @post); }

# Digest the primitive; this should occur in the stomach.
sub invoke {
  my ($self, $stomach) = @_;
  my $_tracing = $STATE->lookupValue('TRACING') || 0;
  my $tracing  = ($_tracing & TRACE_COMMANDS);
  my $profiled = ($_tracing & TRACE_PROFILE) && ($LaTeXML::CURRENT_TOKEN || $$self{cs});

  LaTeXML::Core::Definition::startProfiling($profiled, 'digest') if $profiled;
  Debug('{' . $self->tracingCSName . '}')                        if $tracing;
  my @result = ($self->executeBeforeDigest($stomach));
  my $parms  = $$self{parameters};
  my @args   = ($parms ? $parms->readArguments($stomach->getGullet, $self) : ());
  Debug($self->tracingArgs(@args)) if $tracing && @args;
  my $replacement = $$self{replacement};

  if (!ref $replacement) {
    my $alias = $$self{alias};
    $alias = T_CS($alias) if $alias && !ref $alias;
    push(@result, Box($replacement, undef, undef,
        Tokens($alias || $$self{cs}, ($parms ? $parms->revertArguments(@args) : ())),
        (defined $replacement ? () : (isEmpty => 1)))); }
  else {
    push(@result, &{ $$self{replacement} }($stomach, @args)); }
  push(@result, $self->executeAfterDigest($stomach));
  LaTeXML::Core::Definition::stopProfiling($profiled, 'digest') if $profiled;
  return @result; }

sub equals {
  my ($self, $other) = @_;
  return (defined $other
      && (ref $self) eq (ref $other)) && Equals($self->getParameters, $other->getParameters)
    && Equals($$self{replacement},  $$other{replacement})
    && Equals($$self{beforeDigest}, $$other{beforeDigest})
    && Equals($$self{afterDigest},  $$other{afterDigest})
    ; }

#===============================================================================
1;

__END__

=pod

=head1 NAME

C<LaTeXML::Core::Definition::Primitive>  - Primitive Control sequence definitions.

=head1 DESCRIPTION

These represent primitive control sequences that are converted directly to
Boxes or Lists containing basic Unicode content, rather than structured XML,
or those executed for side effect during digestion in the L<LaTeXML::Core::Stomach>,
changing the L<LaTeXML::Core::State>.  The results of invoking a C<LaTeXML::Core::Definition::Primitive>,
if any, should be a list of digested items (C<LaTeXML::Core::Box>, C<LaTeXML::Core::List>
or C<LaTeXML::Core::Whatsit>).

It extends L<LaTeXML::Core::Definition>.

Primitive definitions may have lists of daemon subroutines, C<beforeDigest> and C<afterDigest>,
that are executed before (and before the arguments are read) and after digestion.
These should either end with C<return;>, C<()>, or return a list of digested
objects (L<LaTeXML::Core::Box>, etc) that will be contributed to the current list.

=head1 AUTHOR

Bruce Miller <bruce.miller@nist.gov>

=head1 COPYRIGHT

Public domain software, produced as part of work done by the
United States Government & not subject to copyright in the US.

=cut