File Coverage

blib/lib/Acme/AwesomeQuotes.pm
Criterion Covered Total %
statement 47 47 100.0
branch 16 16 100.0
condition 4 6 66.6
subroutine 11 11 100.0
pod 1 2 50.0
total 79 82 96.3


line stmt bran cond sub pod time code
1 1     1   35130 use strict;
  1         4  
  1         46  
2 1     1   6 use warnings;
  1         2  
  1         39  
3 1     1   5 use utf8;
  1         2  
  1         9  
4 1     1   45 use 5.008_003;
  1         13  
  1         84  
5              
6             package Acme::AwesomeQuotes;
7             BEGIN {
8 1     1   57 $Acme::AwesomeQuotes::VERSION = '0.02';
9             }
10              
11             binmode STDIN, ':utf8';
12             binmode STDOUT, ':utf8';
13             binmode STDERR, ':utf8';
14              
15 1     1   6 use Exporter;
  1         3  
  1         115  
16             our @ISA = qw(Exporter);
17             our @EXPORT_OK = qw(GetAwesome);
18             our @EXPORT = qw(GetAwesome);
19              
20 1     1   6 use Carp qw(croak);
  1         1  
  1         80  
21 1     1   13452 use Unicode::Normalize qw(NFC NFD);
  1         2375  
  1         155  
22              
23             # ABSTRACT: Make your text awesome!
24              
25              
26             my %chartypes = (
27             'all' => qr/[\x{030C}\x{0300}\x{0301}]/,
28 1     1   6 'notgrave' => qr/[^\P{NonspacingMark}\x{0300}]/,
  1         2  
  1         16  
29             'notacute' => qr/[^\P{NonspacingMark}\x{0301}]/,
30             'notcaron' => qr/[^\P{NonspacingMark}\x{030C}]/,
31             'puncsep' => qr/[\p{Separator}\p{Punctuation}]/,
32             );
33              
34              
35             sub GetAwesome {
36 20     20 1 4112 (my $string = NFD($_[0])) =~ s/(?:^${chartypes{puncsep}}+|${chartypes{puncsep}}+$)//g;
37              
38 20 100       531 eval {checkstring($string)} or croak $@;
  20         39  
39              
40             # For individual characters, use a caron instead of terminal acute/grave accents:
41 15 100       68 if ($string =~ /^\p{Letter}\p{NonspacingMark}*$/) {
42             # Prep string – remove extant carons/accents:
43 3         50 $string =~ s/^(\p{Letter}${chartypes{notcaron}}*)${chartypes{all}}+(${chartypes{notcaron}}*)$/$1$2/;
44              
45             # Make string awesome!
46 3         723 $string = NFC($string);
47 3         23 $string =~ s/^(.*)$/`$1\x{030C}´/;
48             }
49             else {
50             # If there are initial acute/terminal grave accents, use a caron instead:
51 12 100       67 my $initialaccent = ($string =~ s/^(\p{Letter}\p{NonspacingMark}*)[\x{0301}\x{030C}]+/${1}/g)
52             ? "\x{030C}" : "\x{0300}";
53 12 100       126 my $finalaccent = ($string =~ s/(\p{Letter}\p{NonspacingMark}*)[\x{0300}\x{030C}]+(\p{NonspacingMark}*)$/${1}${2}/g)
54             ? "\x{030C}" : "\x{0301}";
55              
56             # Prep string – remove extant terminal acute/grave accents:
57 12         95 $string =~ s/^(\p{Letter}${chartypes{notgrave}}*)\x{0300}/$1/;
58 12         1344 $string =~ s/(\p{Letter}${chartypes{notacute}}*)\x{0301}(${chartypes{notacute}}*)$/$1$2/;
59              
60             # Make string awesome!
61 12         396 $string = NFC($string);
62 12         87 $string =~ s/^(\p{Letter}\p{ModifierLetter}*)/`${1}${initialaccent}/;
63 12         140 $string =~ s/(\p{Letter}\p{ModifierLetter}*)$/${1}${finalaccent}´/;
64             }
65              
66 15         159 return(NFC($string));
67             }
68              
69              
70             sub checkstring {
71 20     20 0 33 my $string = $_[0];
72 20 100 66     521 if ($string eq '') {
    100 66        
    100          
    100          
73 1         163 die "String is empty!\n";
74             }
75             elsif ((($string =~ /^`\p{Letter}${chartypes{notgrave}}*\x{0300}/) &&
76             ($string =~ /\p{Letter}${chartypes{notacute}}*\x{0301}${chartypes{notacute}}*´$/)) ||
77             ($string =~ /^`\p{Letter}${chartypes{notcaron}}*\x{030C}${chartypes{notcaron}}*´$/)) {
78 1         472 die "String '$string' is *already* awesome!\n";
79             }
80             elsif ($string !~ /^\p{Letter}/) {
81 2         264 die "String '$string' begins with a non-letter character.\n";
82             }
83             elsif ($string !~ /\p{Letter}\p{NonspacingMark}*$/) {
84 1         156 die "String '$string' terminates with a non-letter character.\n";
85             }
86             else {
87 15         533 1;
88             }
89             }
90              
91              
92             1; # This is a module, so it must return true.
93              
94             __END__