aboutsummaryrefslogtreecommitdiff
path: root/challenge-259/dave-jacoby/perl/ch-2.pl
blob: 807c4e0a458fd4ee9548d99667bfd454efab09d3 (plain)
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
#!/usr/bin/env perl

use strict;
use warnings;
use experimental qw{ say postderef signatures state };

use JSON;
use List::Util qw{ sum0 };

my $json = JSON->new->pretty->canonical;

my @examples = (

    '{%  youtube title="Title with escaped backslash \\" %}',
    '{%  id   field1="value1"    field2="value2"  field3=42 %}',
    '{%  jacoby language1="perl" language2="javascript" hobby="guitar" %}',
    '{%  hansolo ship="falcon"    friend="wookie"  love="leia" %}',
    '{%  linkedin jobs="multiple words in one line" %}',
    '{%  youtube answer=42       title="Title \"quoted\" done" %}',
);

for my $example (@examples) {
    my $output = line_parse($example);
    my $jo     = $json->encode($output);

    say <<~"END";
    Input:  \$line = '$example'

    Output: 
        $jo
    END
}

sub line_parse ($line) {
    my $output = {};
    while ( $line !~ /^\{\% \s* \%\}/ ) {

        # value matches word="word"
        if ( $line =~ /^\{\% \s* \w+=\"\w+\"/ ) {
            my ( $field, $value ) = $line =~ /(\w+)=\"(\w+)\"\s/;
            $output->{field}{$field} = $value;
            $line =~ s{(\w+=\"\w+\")\s}{};
            next;
        }

        # value matches word=number
        if ( $line =~ /^\{\% \s* \w+=\d+/ ) {
            my ( $field, $value ) = $line =~ /(\w+)=(\d+)\s/;
            $output->{field}{$field} = $value;
            $line =~ s{(\w+=\d+)\s}{};
            next;
        }

        # value matches word="word word word" and also backslash
        if ( $line =~ /^\{\% \s* \w+=\"[\s\w\\\"]+\"/ ) {
            my ( $field, $value ) = $line =~ /(\w+)=\"([\s\w\\\"]+)\"\s/;
            $output->{field}{$field} = $value;
            $line =~ s{(\w+=\"[\s\w\\\"]+\")\s}{};
            next;
        }

        # value matches only word
        if ( $line =~ /^\{\% \s* \w+/ ) {
            my ($field) = $line =~ m{(\w+)};
            $line =~ s{(\w+)}{}mix;
            if   ( $output->{name} ) { $output->{field}{$field} = ''; }
            else                     { $output->{name}          = $field; }
            next;
        }
        substr( $line, 3, 1 ) = '';
    }
    return $output;
}