txt: ## dist_zef-samy-Fortune.md
  # NAME
  
  Fortune - Unix fortune database interface
  
  # SYNOPSIS
  
  ```
  use Fortune;
  
  ## Object-oriented interface
  
  my $fortune = Fortune.new: '/path/to/database';
  
  my $pick = $fortune.fortune.pick;
  
  $fortune.fortune.append: (q:to/HERE/).chomp;
  Arnold's Laws of Documentation:
          (1) If it should exist, it doesn't.
          (2) If it does exist, it's out of date.
          (3) Only documentation for useless programs transcends the
              first two laws.
  HERE
  
  $fortune.write: '/path/to/new/database', :header('/path/to/header');
  
  ## Some convenience subs
  
  strfile '/path/to/database', '/path/to/header';
  
  $pick = fortune;
  
  ```
  
  # DESCRIPTION
  
  Fortune is a Raku module that provides an interface for reading and writing Unix fortune files, both the text database files and the binary header files.
  
  ## class Fortune
  
  ### Attributes
  
  #### fortune
  
  ```
  has Str @.fortune is rw
  
  ```
  
  `Str` array of fortunes. Manipulating this array is how you can modify a fortune database.
  
  ```
  # Add a fortune
  $fortune.fortune.append: "A new fortune";
  
  # Remove a fortune
  $fortune.fortune.pop;
  
  # Sort fortunes
  $fortune.fortune.=sort;
  
  # Shuffle fortunes
  $fortune.fortune.=pick(*);
  
  # etc. etc.
  
  ```
  
  #### order
  
  ```
  has FortuneOrder $.order is rw
  
  ```
  
  Attribute that determines the order to write the header's offset table in. Does not determine the order of the fortunes stored in the object's `fortune` attribute.
  
  See the `FortuneOrder` documentation below for documentation on valid values for `order`.
  
  #### rot13
  
  ```
  has Bool $.rot13 is rw
  
  ```
  
  `Bool` that determines whether the source fortune database was ROT-13 ciphered or not. When set to `True`, the `Fortune` object will read and write databases as if they were ROT-13 ciphered.
  
  #### delimit
  
  ```
  has Char $.delimit is rw
  
  ```
  
  Character that is used for delimitting lines in a source fortune database. Is usually a single percentage sign (`'%'`). `delimit` must be a string that represents a single ASCII character.
  
  #### version
  
  ```
  has Int $.version is rw
  
  ```
  
  Version number of the fortune header. Valid values are `1` and `2`. Version 1 is the version used by most strfile implementations, version 2 is the version used by OpenBSD. The difference between the two versions is the way they store offsets in the fortune header: `1` stores offsets as 64-bit unsigned integars while `2` stores them as 32-bit unsigned integars. The version has no effect on the source fortune database.
  
  ### Methods
  
  #### new
  
  ```
  method new(
  	$database?,
  	:$header,
  	:@fortune,
  	FortuneOrder :$order,
  	Bool :$rot13,
  	Char :$delimit,
  	Int :$version
  )
  
  ```
  
  Returns a new `Fortune` object. Will either create an entirely new database if `$database` is not provided, or read from an existing one if `$database` is provided.
  
  `$database` is the path to the database to read fortunes from. The fortunes can be accessed and manipulated from the object's `fortune` attribute.
  
  `$header` is the path to the database's corresponding binary header to read from. If `$header` is a value that evaluates to `False`, `new` will not attempt to read any header file. By default, `$header` will either be `$database` with the `'.dat'` suffix appended if `$database` was provided and such a header does exist, otherwise it will be set to `False`. Please note that when reading from `$header`, `new` will override any custom attributes that were supplied.
  
  `@fortune` is the list of fortune strings to supply for the `fortune` attribute. Defaults to `Empty`. If `$database` is also provided, `new` will append the list of fortunes read from `$database` to the list provided by `@fortune`.
  
  `$order` is the value to supply for the `order` attribute. Defaults to `FORTUNE_UNORDER`.
  
  `$rot13` is the value to supply for the `rot13` attribute. Defaults to `False`.
  
  `$delimit` is the value to supply for the `delimit` attribute. Defaults to `'%'`.
  
  `$version` is the value to supply for the `version` attribute. Defaults to `1`.
  
  #### read
  
  ```
  method read(
  	$database,
  	:$header,
  	Bool :$append
  )
  
  ```
  
  Reads data from the source database `$database` and (optionally) from the header `$header`.
  
  `$header` will, by default, be `$database` with the `'.dat'` suffix if such a file exists, or `False` otherwise. If you do not wish to read from an existing header, `$header` can be set to `False`.
  
  `$append` is a `Bool` determining whether to append new fortunes to the `fortunes` array or to overwrite it. Defautls to `False`.
  
  Returns `True`, if successful.
  
  #### read\_header
  
  ```
  method read_header($header)
  
  ```
  
  Reads data from the header file `$header`.
  
  Returns `True`, if successful.
  
  #### read\_database
  
  ```
  method read_database(
  	$database,
  	Char :$delimit,
  	Bool :$rot13,
  	Bool :$append
  )
  
  ```
  
  Reads fortunes from the database file `$database`.
  
  `$delimit` is the delimitting character to use when reading `$database`. Does not modify the `delimit` attribute. Defaults to the value of the `delimit` attribute.
  
  `$rot13` determines whether to ROT-13 cipher the fortunes in `$database`. Does not modify the `rot13` attribute. Defaults to the value of the `rot13` attribute.
  
  `$append` is a `Bool` determining whether to override the current fortune list in `fortune`, or to just append to it. Defaults to `False`.
  
  Returns `True`, if successful.
  
  #### write
  
  ```
  method write(
  	$database,
  	:$header
  )
  
  ```
  
  Write fortune database to `$database` and (optionally) fortune header to `$header`.
  
  By default, `$header` will be `$database` with the `'.dat'` suffix. If set to any value that evaluates to `False`, `write` will not try to write a header file.
  
  Returns list of `IO` objects for each written file.
  
  #### write\_database
  
  ```
  method write_database($database)
  
  ```
  
  Write fortune database to `$database`.
  
  Returns `IO` object of written database.
  
  #### write\_header
  
  ```
  method write_header($header)
  
  ```
  
  Write fortune header to `$header`.
  
  Returns `IO` object of written header.
  
  ### Subroutines
  
  The following subroutines were written to provide simple convenience functions for those who do not wish to interact with the object-oriented part of this module.
  
  #### strfile
  
  ```
  sub strfile(
  	$database,
  	$header?,
  	Char :$delimit,
  	FortuneOrder :$order,
  	Bool :$rot13,
  	Int :$version
  )
  
  ```
  
  Subroutine emulating the `strfile(8)` utility. Reads fortunes from `$database` and generates a corresponding fortune header to `$header`. If not supplied, `$header` will default to `$database` with the `'.dat'` suffix.
  
  `$delimit` is the delimitting character `$database` uses. Defaults to `'%'`.
  
  `$order` is the order to write the offset table in. Defaults to `FORTUNE_UNORDER`.
  
  `$rot13` is a `Bool` determining whether the source database was ROT-13 ciphered or not. Defaults to `False`.
  
  `$version` is the version number to use for the generated header. Defaults to `1`.
  
  Returns the `IO` object of the written header.
  
  #### fortune
  
  ```
  multi sub fortune(
  	Bool :$short,
  	Bool :$long
  )
  
  multi sub fortune(
  	$database,
  	:$header,
  	Bool :$short,
  	Bool :$long,
  	Bool :$equal,
  	Bool :$all,
  	Bool :$offensive,
  	Char :$delimit,
  	Bool :$rot13
  )
  
  multi sub fortune(
  	$dir,
  	Bool :$short,
  	Bool :$long,
  	Bool :$equal,
  	Bool :$all,
  	Bool :$offensive,
  	Char :$delimit,
  	Bool :$rot13
  )
  
  ```
  
  Subroutine somewhat emulating the `fortune(6)` utility. Picks a random fortune from a supplied database and returns it.
  
  When ran without providing a fortune file/directory, returns a fortune from this module's own database.
  
  When given a file as an argument, returns a random fortune from that file.
  
  When given a directory as argument, returns a random fortune from one of the databases in that directory.
  
  `$header` is the path to the header file to read from. Defaults to `$database` with the `'.dat'` suffix, or `False` if such a file does not exist. When `False`, `fortune` will not try to read any header file.
  
  `$short` is a `Bool` determining whether to only pick from short fortunes. A short fortune is a fortune of 160 characters or less. Defaults to `False`.
  
  `$long` is a `Bool` determining whether to only pick from long fortunes. A long fortune is a fortune that has more than 160 characters. Defaults to `False`.
  
  `$equal` is a `Bool` determining whether to treat each fortune file in `$dir` of equal size. Is `False` by default, which means that `fortune()` is more likely to pick a fortune from a larger file.
  
  `$all` is a `Bool` determining whether to include all fortunes files, including offensive ones, when picking a fortune. Is meaningless unless the fortune argument is a directory.
  
  `$offensive` is a `Bool` that means `fortune()` will only pick offensive fortunes, which are fortunes located in a file with a `'-o'` suffix. Is meaningless unless the fortune argument is a directory. Also, to quote the `fortune(6)` manpage:
  
  ```
  Please, please, please request a potentially offensive fortune if and only if
  you believe, deep down in your heart, that you are willing to be offended.
  (And that if you are, you'll just quit using [:offensive] rather than give us
  grief about it, okay?)
  
      ...  let us keep in mind the basic governing philosophy of The Brotherhood,
      as handsomely summarized in these words:  we  believe  in  healthy,  hearty
      laughter -- at the expense of the whole human race, if needs be.  Needs be.
               --H. Allen Smith, "Rude Jokes"
  
  ```
  
  `$delimit` is the delimitting character to use when reading from a database. Defaults to `'%'`.
  
  `$rot13` is a `Bool` determining whether the database is ROT-13 ciphered or not. Defaults to `False`.
  
  This subroutine caches the `Fortune` object it creates from reading a database, and will re-use it as long as it has the same arguments as the previous `fortune` call. This makes it efficient to call this subroutine on the same database multiple times.
  
  ### Global Variables
  
  #### DATABASE
  
  ```
  our constant $DATABASE
  
  ```
  
  `IO` object of `Fortune`'s personal fortune database, which is the one used by default by `fortune()` and the `rfortune` script. Can be accessed via `$Fortune::DATABASE`.
  
  ## enum FortuneOrder
  
  ```
  enum FortuneOrder <
  	FORTUNE_UNORDER
  	FORTUNE_ORDER
  	FORTUNE_FC_ORDER
  	FORTUNE_RANDOM
  >
  
  ```
  
  Enumeration representing the various ways a header file can order their offset tables.
  
  * `FORTUNE_UNORDER`
  
    The offsets are ordered in the same way the fortunes are ordered in the `fortune` array.
  * `FORTUNE_ORDER`
  
    The offsets are ordered alphabetically.
  * `FORTUNE_FC_ORDER`
  
    The offsets are ordered alphabetically, case-insensitive.
  * `FORTUNE_RANDOM`
  
    The offsets are ordered randomly.
  
  # AUTHOR
  
  Written by Samuel Young, <samyoung12788@gmail.com>.
  
  The source for this module can be found on its [Codeberg page](https://codeberg.org/1-1sam/raku-Fortune). Comments and pull requests are welcome.
  
  # COPYRIGHT
  
  Copyright 2025, Samuel Young
  
  This program is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0.
  
  # SEE ALSO
  
  fortune(6), strfile(8)
  