File Coverage

blib/lib/LaTeX/TOM/Node.pm
Criterion Covered Total %
statement 33 72 45.8
branch 1 18 5.5
condition 1 8 12.5
subroutine 11 25 44.0
pod 0 20 0.0
total 46 143 32.1


line stmt bran cond sub pod time code
1             ###############################################################################
2             #
3             # LaTeX::TOM::Node
4             #
5             # This package defines an object for nodes in the TOM tree, and methods to go
6             # with them.
7             #
8             ###############################################################################
9              
10             package LaTeX::TOM::Node;
11              
12 10     10   74 use strict;
  10         19  
  10         263  
13 10     10   46 use warnings;
  10         20  
  10         259  
14 10     10   48 use constant true => 1;
  10         17  
  10         1124  
15 10     10   61 use constant false => 0;
  10         22  
  10         9712  
16              
17             our $VERSION = '0.05';
18              
19             # Make a new Node: turn input hash into object.
20             #
21             sub _new {
22 650     650   908 my $class = shift;
23 650         934 my ($node) = @_;
24              
25 650   50     1566 return bless $node || {};
26             }
27              
28             # "copy constructor"
29             #
30             sub copy {
31 25     25 0 32 my $node = shift;
32              
33 25         41 return bless $node;
34             }
35              
36             # Split a text node into two text nodes, with the first ending before point a,
37             # and the second starting after point b. actually returns NEW nodes, does not
38             # alter the input node.
39             #
40             # Note: a and b are relative to the contents of the node, not the original
41             # document.
42             #
43             # Note2: a and b are not jointly constrained. You can split after location x
44             # without losing any characters by setting a = x + 1 and b = x.
45             #
46             sub split {
47 239     239 0 359 my $node = shift;
48 239         374 my ($a, $b) = @_;
49              
50 239 50       468 return (undef) x 2 unless $node->{type} eq 'TEXT';
51              
52 239         481 my $left_text = substr $node->{content}, 0, $a;
53 239         489 my $right_text = substr $node->{content}, $b + 1, length($node->{content}) - $b;
54              
55             my $left_node = LaTeX::TOM::Node->_new({
56             type => 'TEXT',
57             start => $node->{start},
58 239         899 end => $node->{start} + $a - 1,
59             content => $left_text,
60             });
61              
62             my $right_node = LaTeX::TOM::Node->_new({
63             type => 'TEXT',
64             start => $node->{start} + $b + 1,
65             end => $node->{start} + length $node->{content},
66 239         874 content => $right_text,
67             });
68              
69 239         597 return ($left_node, $right_node);
70             }
71              
72             #
73             # accessor methods
74             #
75              
76             sub getNodeType {
77 68     68 0 10539 my $node = shift;
78              
79 68         134 return $node->{type};
80             }
81              
82             sub getNodeText {
83 18     18 0 7739 my $node = shift;
84              
85 18         61 return $node->{content};
86             }
87              
88             sub setNodeText {
89 0     0 0 0 my $node = shift;
90 0         0 my ($text) = @_;
91              
92 0         0 $node->{content} = $text;
93             }
94              
95             sub getNodeStartingPosition {
96 0     0 0 0 my $node = shift;
97              
98 0         0 return $node->{start};
99             }
100              
101             sub getNodeEndingPosition {
102 0     0 0 0 my $node = shift;
103              
104 0         0 return $node->{end};
105             }
106              
107             sub getNodeMathFlag {
108 0     0 0 0 my $node = shift;
109              
110 0 0       0 return $node->{math} ? true : false;
111             }
112              
113             sub getNodePlainTextFlag {
114 0     0 0 0 my $node = shift;
115              
116 0 0       0 return $node->{plaintext} ? true : false;
117             }
118              
119             sub getNodeOuterStartingPosition {
120 0     0 0 0 my $node = shift;
121              
122 0 0       0 return (defined $node->{ostart} ? $node->{ostart} : $node->{start});
123             }
124              
125             sub getNodeOuterEndingPosition {
126 0     0 0 0 my $node = shift;
127              
128 0 0       0 return (defined $node->{oend} ? $node->{oend} : $node->{end});
129             }
130              
131             sub getEnvironmentClass {
132 3     3 0 821 my $node = shift;
133              
134 3         12 return $node->{class};
135             }
136              
137             sub getCommandName {
138 21     21 0 3533 my $node = shift;
139              
140 21         197 return $node->{command};
141             }
142              
143             #
144             # linked-list accessors
145             #
146              
147             sub getChildTree {
148 0     0 0   my $node = shift;
149              
150 0           return $node->{children};
151             }
152              
153             sub getFirstChild {
154 0     0 0   my $node = shift;
155              
156 0 0         if ($node->{children}) {
157 0           return $node->{children}->{nodes}[0];
158             }
159              
160 0           return undef;
161             }
162              
163             sub getLastChild {
164 0     0 0   my $node = shift;
165              
166 0 0         if ($node->{children}) {
167 0           return $node->{children}->{nodes}[-1];
168             }
169              
170 0           return undef;
171             }
172              
173             sub getPreviousSibling {
174 0     0 0   my $node = shift;
175              
176 0           return $node->{prev};
177             }
178              
179             sub getNextSibling {
180 0     0 0   my $node = shift;
181              
182 0           return $node->{'next'};
183             }
184              
185             sub getParent {
186 0     0 0   my $node = shift;
187              
188 0           return $node->{parent};
189             }
190              
191             # This is an interesting function, and kind of a hack because of the way the
192             # parser makes the current tree. Basically it will give you the next sibling
193             # that is a GROUP node, until it either hits the end of the tree level, a TEXT
194             # node which doesn't match /^\s*$/, or a COMMAND node.
195             #
196             # This is useful for finding all GROUPed parameters after a COMMAND node. You
197             # can just have a while loop that calls this method until it gets 'undef'.
198             #
199             # Note: this may be bad, but TEXT Nodes matching /^\s*\[[0-9]+\]$/ (optional
200             # parameter groups) are treated as if they were whitespace.
201             #
202             sub getNextGroupNode {
203 0     0 0   my $node = shift;
204              
205 0           my $next = $node;
206 0           while ($next = $next->{'next'}) {
207              
208             # found a GROUP node.
209 0 0 0       if ($next->{type} eq 'GROUP') {
    0 0        
210 0           return $next;
211             }
212              
213             # see if we should skip a node
214             elsif ($next->{type} eq 'COMMENT' ||
215             ($next->{type} eq 'TEXT' &&
216             $next->{content} =~ /^\s*(?:\[\s*[0-9]+\s*\]\s*)?$/)) {
217              
218 0           next;
219             }
220              
221             else {
222 0           return undef;
223             }
224             }
225              
226 0           return undef;
227             }
228              
229             1;