Compare commits

...

8 Commits

2 changed files with 68 additions and 37 deletions

View File

@@ -1,18 +1,38 @@
# Catechism CLI (ccc) # Catechism CLI (ccc)
A command-line tool for querying sections of the Catechism of the Catholic 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 ## Usage
Before using `ccc` you must first load a cache of where each section is located
on the web.
```bash ```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 ## Dependencies
The script requires the following Perl modules (all included in standard Perl The script requires the following Perl modules:
distributions):
- `LWP::UserAgent` - For HTTP requests - `LWP::UserAgent` - For HTTP requests
- `JSON::PP` - For JSON parsing - `JSON::PP` - For JSON parsing
@@ -21,6 +41,9 @@ distributions):
- `File::Path` - For creating cache directory structures - `File::Path` - For creating cache directory structures
- `Math::Base36` - For calculating the name of the HTML files - `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 ## Licensing
This project is licensed under the terms & conditions of the Zlib license. See 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 File::Path qw(make_path);
use Math::Base36 ':all'; 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') { unless(defined($arg)) {
usage(); 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') { } elsif($arg eq '-l' || $arg eq '--load-cache') {
my $cache_dir = get_xdg_cache_dir(); my $cache_dir = get_xdg_cache_dir();
make_path($cache_dir) unless -d $cache_dir; make_path($cache_dir) unless -d $cache_dir;
my $cache_file = File::Spec->catfile($cache_dir, 'section_map.json'); my $cache_file = File::Spec->catfile($cache_dir, 'section_map.json');
build_section_map($cache_file); 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); my ($start_section, $end_section);
if($arg =~ /^(\d+)-(\d+)$/) { if($arg =~ /^(\d+)-(\d+)$/) {
$start_section = $1; $start_section = $1;
@@ -88,16 +97,22 @@ unless($found_any) {
exit 1; exit 1;
} }
sub usage { sub print_usage {
print STDERR "Usage: ccc [OPTIONS] [section_number|range]\n"; print "Usage:\n";
print STDERR "Options:\n"; print " ccc <section|range>\n";
print STDERR " -l, --load-cache Build the section cache from Vatican server\n"; print " ccc [OPTION]\n";
print STDERR " -h, --help Show this help message\n"; }
print STDERR "Examples:\n";
print STDERR " ccc -l # Build cache\n"; sub print_help {
print STDERR " ccc 270 # Single section\n"; print_usage();
print STDERR " ccc 1691-1698 # Range of sections\n"; print "\nOptions:\n";
exit 1; 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 { sub load_cache {
@@ -177,19 +192,20 @@ sub extract_section_numbers {
my @sections; my @sections;
# Find section header numbers with Windows lines # Find section header numbers with Windows lines
while($html =~ /\r\n<[p|P] class=MsoNormal[^>]*>(<i[^>]*>)?(\d{1,4})/g) { while($html =~ /\r\n<[pP] class=MsoNormal[^>]*>(<i[^>]*>)?(\d{1,4})\s+/g) {
push @sections, $2; my $section_num = $2;
push @sections, $section_num;
} }
return @sections; return @sections;
} }
sub fetch_and_display_section { sub fetch_and_display_section {
my ($section_num, $section_info) = @_; my ($section_num, $section_page) = @_;
my $ua = LWP::UserAgent->new(timeout => 10); my $ua = LWP::UserAgent->new(timeout => 10);
my $base_url = 'https://www.vatican.va/archive/ENG0015'; 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); my $response = $ua->get($url);
@@ -199,19 +215,10 @@ sub fetch_and_display_section {
} }
my $content = $response->content; my $content = $response->content;
print_section($content, $section_num);
# 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;
}
} }
sub extract_section_content { sub print_section {
my ($html, $section_num) = @_; my ($html, $section_num) = @_;
# Convert HTML entities # Convert HTML entities
@@ -240,10 +247,11 @@ sub extract_section_content {
# Add line breaks for readability # Add line breaks for readability
$content =~ s/([.!?])\s+(?=[A-Z])/\n\n/g; $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 { sub get_xdg_cache_dir {