Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What this is

`chicken` is a chicken-ipsum text generator (a Perl port/extension of https://github.com/sebastiancarlos/chicken-ipsum). Plain Perl 5 with only core modules (`Getopt::Long`); no build system, no test suite, no dependencies to install.

## Files

- `chicken.pl` — the whole program. Installed as `/usr/bin/chicken`.
- `man_chicken.pl` — generator for the man page. Its `__DATA__` section is a roff template; every `$(args)` is replaced by the output of `./chicken.pl --seed <s> args` (anything after the args, e.g. `| tr ...`, is passed through the shell as part of the `qx()` call).
- `chicken.1` — **generated** man page. Do not edit by hand; edit the template in `man_chicken.pl` and regenerate.
- `install.sh` — copies the script and man page into `${DESTDIR}/usr/bin` and `${DESTDIR}/usr/share/man/man1` (used for packaging with `bee`).

## Commands

```sh
./chicken.pl # one paragraph, 15-75 words
./chicken.pl -nw 10 --seed 42 # deterministic output
perl -c chicken.pl # syntax check
./man_chicken.pl > chicken.1 # regenerate the man page (must run from repo root; it calls ./chicken.pl)
man ./chicken.1 # view it
DESTDIR=/some/root ./install.sh # staged install
```

There are no tests. To verify a change, compare seeded output before/after (e.g. `./man_chicken.pl | diff - chicken.1`); the man page regeneration is fully deterministic and currently reproduces the committed `chicken.1` byte-for-byte.

## Things that are easy to break

- **Man page seeds derive from `$VERSION`.** `man_chicken.pl` starts at `seed = VERSION * 1000` and increments once per `$(...)` substitution, in template order. So bumping `$VERSION`, inserting/removing a `$(...)` in the template, or changing the order/number of `rand()` calls in `chicken.pl` changes the text of the whole (rest of the) man page. That's expected — just regenerate `chicken.1` and commit it together with the change.
- **When adding an option**, update three places: `GetOptions`/`USAGE` in `chicken.pl`, and the SYNOPSIS + Options sections of the template in `man_chicken.pl`; then regenerate `chicken.1`.
- `--maxlength` works by skipping words that don't fit. Skipped words must not affect capitalization, and the paragraph is closed off afterwards: the trailing space is removed and a `.` is added, with room for it held back during the loop. Keep the default (no `-ml`) path free of extra `rand()` calls so seeded output and the man page stay stable.
- `--namethischicken` builds its name pool from `@WORDS` (only words without a hyphen), so changing `@WORDS` changes the set of possible names.
32 changes: 21 additions & 11 deletions chicken.pl
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ sub USAGE {
usage: $0 [options]
--numberofwords -nw <n[-m]> : number of words, ranged from n to m
--maxlength -ml <n> : maximun length
--maxlength -ml <n> : maximum length
--enumerate -en <n> : create a list of arguments
--namethischicken : tell the chickens name
--printchickenversion : print out "$VERSION"
--seed <n> : feed the random chicken
eof
exit;
exit 1;
}

our %OPT;
Expand All @@ -29,7 +29,7 @@ sub USAGE {
my $opt_maxlength = 0;
my $numberOfWords = 0;
my $opt_namethischicken = 0;
my $opt_seed = 0;
my $opt_seed;

my ( $f, $t ) = ( 0, 0 );
my $opt_enumerate = 0;
Expand All @@ -48,7 +48,7 @@ sub USAGE {
exit;
}

srand( $opt_seed ? $opt_seed : time() );
srand($opt_seed) if defined $opt_seed;

my @WORDS = ( "puk", "pukaak", "cluck", "cluckity", "bwak", "waak", "bok", "bwok", "cluck-a-buh-gawk", "cock-a-doodle-doo", "bwwwaak", "gobble", "honk" );

Expand All @@ -57,6 +57,7 @@ sub USAGE {
if ($opt_namethischicken) {

my %ChickenPopulation;
my @MarriedChickens;
my @ChickenNames = grep { !/-/ } @WORDS;

for my $pn (@ChickenNames) {
Expand All @@ -68,11 +69,11 @@ sub USAGE {
# "Waak Bok" could also be married to "Cluck" which would end up in "Waak Bok-Cluck"
for my $pn (@ChickenNames) {
for ( keys %ChickenPopulation ) {
push @_, ucfirst($pn) . ' ' . $_ unless $ChickenPopulation{$_} == 1;
push @MarriedChickens, ucfirst($pn) . ' ' . $_ unless $ChickenPopulation{$_} == 1;
}
}

for (@_) { s/( \w+) /$1-/; $ChickenPopulation{$_} = 3 }
for (@MarriedChickens) { s/( \w+) /$1-/; $ChickenPopulation{$_} = 3 }
my @CN = keys %ChickenPopulation;

my $chickensname = $CN[ rand( scalar @CN ) ];
Expand All @@ -89,7 +90,7 @@ sub USAGE {
else {
print STDERR "wrong format for --numberofwords\n";
print STDERR "should be either 'n' or 'n-m'. ( '-nw 50' or '-nw 30-90''\n";
exit;
exit 1;
}

my $enumerate = ($opt_enumerate) ? $opt_enumerate : 1;
Expand Down Expand Up @@ -127,14 +128,17 @@ sub USAGE {

# optionally capitalize the word
# note: always capitalize if it's the first words, or if preceded by punctuation
my $shouldCapitalize = $i == 0 || $previousWordHadPunctuation || rand() > 0.7;
my $shouldCapitalize = $paragraph eq '' || $previousWordHadPunctuation || rand() > 0.7;

$word = $shouldCapitalize ? uc( substr( $word, 0, 1 ) ) . substr( $word, 1 ) : $word;

# preserve info for next iteration
$previousWordHadPunctuation = $shouldAddPunctuation;
# keep room for a final '.' in case this ends up being the last word that fits
my $reserve = $shouldAddPunctuation ? 0 : 1;

if ( $opt_maxlength == 0 or length($paragraph) + length($word) + $reserve <= $opt_maxlength ) {
# preserve info for next iteration
$previousWordHadPunctuation = $shouldAddPunctuation;

if ( $opt_maxlength == 0 or length($paragraph) + length($word) - 1 < $opt_maxlength ) {
# add word to paragraph
$paragraph = $paragraph . $word;

Expand All @@ -143,6 +147,12 @@ sub USAGE {
}
}

# words may have been skipped by --maxlength: drop the trailing space and terminate the sentence
if ($opt_maxlength) {
$paragraph =~ s/ $//;
$paragraph .= '.' if $paragraph ne '' and $paragraph !~ /[.!?]$/;
}

if ($opt_enumerate) {
printf "%d. ", $e + 1;
}
Expand Down
5 changes: 3 additions & 2 deletions man_chicken.pl
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
my $seed = $_ * 1000;

sub bokbokbok {
my ($args) = @_;
$seed++;
return qx(./chicken.pl --seed $seed $1);
return qx(./chicken.pl --seed $seed $args);
};

while(<DATA>) {
s/\$\((.*?)\)/&bokbokbok($&)/eg;
s/\$\((.*?)\)/bokbokbok($1)/eg;
print;
}

Expand Down