File Coverage

blib/lib/Syntax/Highlight/JSON.pm
Criterion Covered Total %
statement 12 109 11.0
branch 0 8 0.0
condition n/a
subroutine 4 27 14.8
pod 0 4 0.0
total 16 148 10.8


line stmt bran cond sub pod time code
1              
2             =head1 NAME
3              
4             Syntax::Highlight::JSON - Convert JSON to a pretty-printed and syntax-highlighted HTML representation
5              
6             =cut
7              
8             package Syntax::Highlight::JSON;
9              
10 1     1   752 use strict;
  1         1  
  1         38  
11 1     1   5 use warnings;
  1         1  
  1         34  
12              
13 1     1   887 use JSON::Streaming::Reader;
  1         20535  
  1         34  
14 1     1   12 use IO::Scalar;
  1         2  
  1         1296  
15              
16             our $VERSION = "0.01";
17              
18             sub highlight_stream {
19 0     0 0   my ($in_stream) = @_;
20              
21 0           my $out_string = "";
22 0           my $out_stream = IO::Scalar->new(\$out_string);
23 0           my $reader = JSON::Streaming::Reader->for_stream($in_stream);
24              
25 0           _highlight($reader, $out_stream);
26              
27 0           return $out_string;
28             }
29              
30             sub highlight_string {
31 0     0 0   my ($in_string) = @_;
32              
33 0           my $out_string = "";
34 0           my $out_stream = IO::Scalar->new(\$out_string);
35 0           my $reader = JSON::Streaming::Reader->for_string($in_string);
36              
37 0           _highlight($reader, $out_stream);
38              
39 0           return $out_string;
40             }
41              
42             sub highlight_stream_to_stream {
43 0     0 0   my ($in_stream, $out_stream) = @_;
44              
45 0           my $reader = JSON::Streaming::Reader->for_stream($in_stream);
46              
47 0           _highlight($reader, $out_stream);
48             }
49              
50             sub highlight_string_to_stream {
51 0     0 0   my ($in_string, $out_stream) = @_;
52              
53 0           my $reader = JSON::Streaming::Reader->for_string($in_string);
54              
55 0           _highlight($reader, $out_stream);
56             }
57              
58             sub _highlight {
59 0     0     my ($jr, $out_stream) = @_;
60              
61 0           my $current_indent = 0;
62 0           my $in_property = 0;
63 0           my @mv_stack;
64             my @p_stack;
65 0           my $made_value = 0;
66              
67             my $tab = sub {
68 0     0     $out_stream->print(" " x $current_indent);
69 0           };
70             my $pr = sub {
71 0     0     $out_stream->print(@_);
72 0           };
73             my $push = sub {
74 0     0     push @mv_stack, $made_value;
75 0           $made_value = 0;
76 0           push @p_stack, $in_property;
77 0           $in_property = 0;
78 0           };
79             my $pop = sub {
80 0     0     $made_value = pop @mv_stack;
81 0           $in_property = pop @p_stack;
82 0           };
83             my $comma = sub {
84 0 0   0     $out_stream->print(",") if $made_value;
85 0 0         if ($in_property) {
86 0           $out_stream->print(" ");
87             }
88             else {
89 0           $out_stream->print("\n");
90 0           $tab->();
91             }
92 0           };
93             my $end_block = sub {
94 0 0   0     if ($made_value) {
95 0           $out_stream->print("\n");
96 0           $tab->();
97             }
98 0           };
99              
100 0           $pr->('
'); 
101             $jr->process_tokens(
102             start_object => sub {
103 0     0     $comma->();
104 0           $pr->('{');
105 0           $push->();
106 0           $current_indent++;
107             },
108             end_object => sub {
109 0     0     $current_indent--;
110 0           $end_block->();
111 0           $pop->();
112 0           $pr->('}'),
113             $made_value = 1;
114             },
115             start_property => sub {
116 0     0     my ($name) = @_;
117 0           $comma->();
118 0           $push->();
119 0           $in_property = 1;
120 0           $pr->('', _json_string($name), ':');
121             },
122             end_property => sub {
123 0     0     $in_property = 0;
124 0           $pop->();
125 0           $made_value = 1;
126 0           $pr->('');
127             },
128             start_array => sub {
129 0     0     $comma->();
130 0           $pr->('[');
131 0           $push->();
132 0           $current_indent++;
133             },
134             end_array => sub {
135 0     0     $current_indent--;
136 0           $end_block->();
137 0           $pop->();
138 0           $pr->(']'),
139             $made_value = 1;
140             },
141             add_string => sub {
142 0     0     my ($value) = @_;
143 0           $comma->();
144 0           $pr->('', _json_string($value), '');
145 0           $made_value = 1;
146             },
147             add_number => sub {
148 0     0     my ($value) = @_;
149 0           $comma->();
150 0           $pr->('', $value, '');
151 0           $made_value = 1;
152             },
153             add_boolean => sub {
154 0     0     my ($value) = @_;
155 0           $comma->();
156 0 0         $pr->('', ($value ? 'true' : 'false'), '');
157 0           $made_value = 1;
158             },
159             add_null => sub {
160 0     0     my ($value) = @_;
161 0           $comma->();
162 0           $pr->('null');
163 0           $made_value = 1;
164             },
165             error => sub {
166 0     0     my $error = shift;
167 0           die $error;
168             },
169 0           );
170 0           $pr->('');
171              
172              
173             }
174              
175             my %esc = (
176             "\n" => '\n',
177             "\r" => '\r',
178             "\t" => '\t',
179             "\f" => '\f',
180             "\b" => '\b',
181             "\"" => '\"',
182             "\\" => '\\\\',
183             "\'" => '\\\'',
184             );
185             sub _json_string {
186 0     0     my ($value) = @_;
187              
188 0           $value =~ s/([\x22\x5c\n\r\t\f\b])/$esc{$1}/eg;
  0            
189 0           $value =~ s/([\x00-\x08\x0b\x0e-\x1f])/'\\u00' . unpack('H2', $1)/eg;
  0            
190              
191 0           return '"'.$value.'"';
192             }
193              
194             1;