blib/lib/Text/Diff/HTML.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 40 | 40 | 100.0 |
branch | 6 | 8 | 75.0 |
condition | n/a | ||
subroutine | 12 | 12 | 100.0 |
pod | 0 | 5 | 0.0 |
total | 58 | 65 | 89.2 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Text::Diff::HTML; | ||||||
2 | |||||||
3 | 1 | 1 | 57261 | use strict; | |||
1 | 2 | ||||||
1 | 28 | ||||||
4 | 1 | 1 | 5 | use vars qw(@ISA $VERSION); | |||
1 | 1 | ||||||
1 | 44 | ||||||
5 | 1 | 1 | 449 | use HTML::Entities; | |||
1 | 4902 | ||||||
1 | 70 | ||||||
6 | 1 | 1 | 462 | use Text::Diff (); # Just to be safe. | |||
1 | 10147 | ||||||
1 | 127 | ||||||
7 | |||||||
8 | $VERSION = '0.08'; | ||||||
9 | @ISA = qw(Text::Diff::Unified); | ||||||
10 | |||||||
11 | sub file_header { | ||||||
12 | 1 | 1 | 0 | 819 | return ' ' |
||
13 | . encode_entities(shift->SUPER::file_header(@_)) | ||||||
14 | . ''; | ||||||
15 | } | ||||||
16 | |||||||
17 | sub hunk_header { | ||||||
18 | 1 | 1 | 0 | 543 | return ' ' |
||
19 | . encode_entities(shift->SUPER::hunk_header(@_)) | ||||||
20 | . ''; | ||||||
21 | } | ||||||
22 | |||||||
23 | sub hunk_footer { | ||||||
24 | 1 | 1 | 0 | 471 | return ' | ||
25 | . encode_entities(shift->SUPER::hunk_footer(@_)) | ||||||
26 | . ''; | ||||||
27 | } | ||||||
28 | |||||||
29 | sub file_footer { | ||||||
30 | 1 | 1 | 0 | 498 | return ' | ||
31 | . encode_entities(shift->SUPER::file_footer(@_)) | ||||||
32 | . ''; | ||||||
33 | } | ||||||
34 | |||||||
35 | # Each of the items in $seqs is an array reference. The first one has the | ||||||
36 | # contents of the first file and the second has the contents of the second | ||||||
37 | # file, all broken into hunks. $ops is an array reference of array references, | ||||||
38 | # one corresponding to each of the hunks in the sequences. | ||||||
39 | # | ||||||
40 | # The contents of each op in $ops tell us what to do with each hunk. Each op | ||||||
41 | # can have up to four items: | ||||||
42 | # | ||||||
43 | # 0: The index of the relevant hunk in the first file sequence. | ||||||
44 | # 1: The index of the relevant hunk in the second file sequence. | ||||||
45 | # 2: The opcode for the hunk, either '+', '-', or ' '. | ||||||
46 | # 3: A flag; not sure what this is, doesn't seem to apply to unified diffs. | ||||||
47 | # | ||||||
48 | # So what we do is figure out which op we have and output the relevant span | ||||||
49 | # element if it is different from the last op. Then we select the hunk from | ||||||
50 | # second sequence (SEQ_B_IDX) if it's '+' and the first sequence (SEQ_A_IDX) | ||||||
51 | # otherwise, and then output the opcode and the hunk. | ||||||
52 | |||||||
53 | 1 | 1 | 8 | use constant OPCODE => 2; # "-", " ", "+" | |||
1 | 2 | ||||||
1 | 47 | ||||||
54 | 1 | 1 | 4 | use constant SEQ_A_IDX => 0; | |||
1 | 2 | ||||||
1 | 47 | ||||||
55 | 1 | 1 | 5 | use constant SEQ_B_IDX => 1; | |||
1 | 2 | ||||||
1 | 240 | ||||||
56 | |||||||
57 | my %code_map = ( | ||||||
58 | '+' => [ 'ins' => 'ins' ], | ||||||
59 | '-' => [ 'del' => 'del' ], | ||||||
60 | ' ' => [ 'span class="ctx"' => 'span' ] | ||||||
61 | ); | ||||||
62 | |||||||
63 | sub hunk { | ||||||
64 | 1 | 1 | 0 | 455 | shift; | ||
65 | 1 | 2 | my $seqs = [ shift, shift ]; | ||||
66 | 1 | 3 | my $ops = shift; | ||||
67 | 1 | 50 | 4 | return unless @$ops; | |||
68 | |||||||
69 | # Start the span element for the first opcode. | ||||||
70 | 1 | 2 | my $last = $ops->[0][ OPCODE ]; | ||||
71 | 1 | 4 | my $hunk = qq{<$code_map{ $last }->[0]>}; | ||||
72 | |||||||
73 | # Output each line of the hunk. | ||||||
74 | 1 | 5 | while (my $op = shift @$ops) { | ||||
75 | 4 | 54 | my $opcode = $op->[OPCODE]; | ||||
76 | 4 | 50 | 9 | my $elem = $code_map{ $opcode } or next; | |||
77 | |||||||
78 | # Close the last span and start a new one for a new opcode. | ||||||
79 | 4 | 100 | 7 | if ($opcode ne $last) { | |||
80 | 2 | 5 | $hunk .= "$code_map{ $last }->[1]><$elem->[0]>"; | ||||
81 | 2 | 3 | $last = $opcode; | ||||
82 | } | ||||||
83 | |||||||
84 | # Output the appropriate line. | ||||||
85 | 4 | 100 | 9 | my $idx = $opcode ne '+' ? SEQ_A_IDX : SEQ_B_IDX; | |||
86 | 4 | 13 | $hunk .= encode_entities("$opcode $seqs->[$idx][$op->[$idx]]"); | ||||
87 | } | ||||||
88 | |||||||
89 | 1 | 16 | return $hunk . "$code_map{ $last }->[1]>"; | ||||
90 | } | ||||||
91 | |||||||
92 | 1; | ||||||
93 | __END__ |