Compare commits

..

8 Commits

2 changed files with 68 additions and 37 deletions

View File

@@ -1,18 +1,38 @@
# Catechism CLI (ccc)
A command-line tool for querying sections of the Catechism of the Catholic
Church by section number.
Church from the Vatican's website by section number.
## Usage
Before using `ccc` you must first load a cache of where each section is located
on the web.
```bash
ccc <section_number|range>
ccc --load-cache
# or
ccc -l
```
Once loaded you can query any particular section by simply using the section
number.
```console
$ ccc 241
241 For this reason the apostles confess Jesus to be the Word: "In the beginning was the Word, and the Word was with God, and the Word was God"; as "the image of the invisible God"; as the "radiance of the glory of God and the very stamp of his nature".65
```
Alternatively you can also specify a range of sections to query.
```console
$ ccc 232-233
232 Christians are baptized "in the name of the Father and of the Son and of the Holy Spirit"53 Before receiving the sacrament, they respond to a three-part question when asked to confess the Father, the Son and the Spirit: "I do." "The faith of all Christians rests on the Trinity."54
233 Christians are baptized in the name of the Father and of the Son and of the Holy Spirit: not in their names,55 for there is only one God, the almighty Father, his only Son and the Holy Spirit: the Most Holy Trinity.
```
## Dependencies
The script requires the following Perl modules (all included in standard Perl
distributions):
The script requires the following Perl modules:
- `LWP::UserAgent` - For HTTP requests
- `JSON::PP` - For JSON parsing
@@ -21,6 +41,9 @@ distributions):
- `File::Path` - For creating cache directory structures
- `Math::Base36` - For calculating the name of the HTML files
The `Math::Base36` module is not a part of standard Perl distribuitions, but can
be installed with [cpan](https://www.cpan.org/modules/INSTALL.html).
## Licensing
This project is licensed under the terms & conditions of the Zlib license. See

74
ccc
View File

@@ -31,19 +31,28 @@ use File::HomeDir;
use File::Path qw(make_path);
use Math::Base36 ':all';
my $arg = shift or usage();
my $VERSION = '0.1';
my $PROG_NAME = 'ccc';
my $arg = shift;
if($arg eq '--help' || $arg eq '-h') {
usage();
unless(defined($arg)) {
print STDERR "No arguments given.\n\n";
print_usage();
exit 1;
} elsif($arg eq '--help' || $arg eq '-h') {
print_help();
exit;
} elsif($arg eq '-l' || $arg eq '--load-cache') {
my $cache_dir = get_xdg_cache_dir();
make_path($cache_dir) unless -d $cache_dir;
my $cache_file = File::Spec->catfile($cache_dir, 'section_map.json');
build_section_map($cache_file);
exit 0;
exit;
} elsif($arg eq '-v' || $arg eq '--version') {
print "$PROG_NAME v$VERSION\n";
exit;
}
# Parse argument - can be single number or range (e.g., "1691-1698")
my ($start_section, $end_section);
if($arg =~ /^(\d+)-(\d+)$/) {
$start_section = $1;
@@ -88,16 +97,22 @@ unless($found_any) {
exit 1;
}
sub usage {
print STDERR "Usage: ccc [OPTIONS] [section_number|range]\n";
print STDERR "Options:\n";
print STDERR " -l, --load-cache Build the section cache from Vatican server\n";
print STDERR " -h, --help Show this help message\n";
print STDERR "Examples:\n";
print STDERR " ccc -l # Build cache\n";
print STDERR " ccc 270 # Single section\n";
print STDERR " ccc 1691-1698 # Range of sections\n";
exit 1;
sub print_usage {
print "Usage:\n";
print " ccc <section|range>\n";
print " ccc [OPTION]\n";
}
sub print_help {
print_usage();
print "\nOptions:\n";
print " -l, --load-cache Build the section cache from Vatican server\n";
print " -h, --help Show this help message\n";
print " -v, --version Show version information\n";
print "\nExamples:\n";
print " ccc -l # Build cache\n";
print " ccc 270 # Single section\n";
print " ccc 1691-1698 # Range of sections\n";
}
sub load_cache {
@@ -177,19 +192,20 @@ sub extract_section_numbers {
my @sections;
# Find section header numbers with Windows lines
while($html =~ /\r\n<[p|P] class=MsoNormal[^>]*>(<i[^>]*>)?(\d{1,4})/g) {
push @sections, $2;
while($html =~ /\r\n<[pP] class=MsoNormal[^>]*>(<i[^>]*>)?(\d{1,4})\s+/g) {
my $section_num = $2;
push @sections, $section_num;
}
return @sections;
}
sub fetch_and_display_section {
my ($section_num, $section_info) = @_;
my ($section_num, $section_page) = @_;
my $ua = LWP::UserAgent->new(timeout => 10);
my $base_url = 'https://www.vatican.va/archive/ENG0015';
my $url = "$base_url/$section_info";
my $url = "$base_url/$section_page";
my $response = $ua->get($url);
@@ -199,19 +215,10 @@ sub fetch_and_display_section {
}
my $content = $response->content;
# Extract the section content
my $section_content = extract_section_content($content, $section_num);
if($section_content) {
print $section_content;
} else {
print STDERR "Error: Could not parse section $section_num\n";
exit 1;
}
print_section($content, $section_num);
}
sub extract_section_content {
sub print_section {
my ($html, $section_num) = @_;
# Convert HTML entities
@@ -240,10 +247,11 @@ sub extract_section_content {
# Add line breaks for readability
$content =~ s/([.!?])\s+(?=[A-Z])/\n\n/g;
return "\033[1m$section_num\033[0m $content\n";
print "\033[1m$section_num\033[0m $content\n";
} else {
print STDERR "Error: Could not parse section $section_num\n";
exit 1;
}
return undef;
}
sub get_xdg_cache_dir {