%%
%% This is file `ducksay.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% ducksay.dtx  (with options: `pkg')
%% 
%% --------------------------------------------------------------
%% ducksay -- cowsay for LaTeX
%% E-mail: jspratte@yahoo.de
%% Released under the LaTeX Project Public License v1.3c or later
%% See http://www.latex-project.org/lppl.txt
%% --------------------------------------------------------------
%% 
%% Copyright (C) 2017-2022 Jonathan P. Spratte
%% 
%% This  work may be  distributed and/or  modified under  the conditions  of the
%% LaTeX Project Public License (LPPL),  either version 1.3c  of this license or
%% (at your option) any later version.  The latest version of this license is in
%% the file:
%% 
%%   http://www.latex-project.org/lppl.txt
%% 
%% This work is "maintained" (as per LPPL maintenance status) by
%%   Jonathan P. Spratte.
%% 
%% This work consists of the file  ducksay.dtx
%% and the derived files           ducksay.pdf
%%                                 ducksay.sty
%%                                 ducksay.code.v1.tex
%%                                 ducksay.code.v2.tex and
%%                                 ducksay.animals.tex.
%% 
\NeedsTeXFormat{LaTeX2e}
\@ifundefined{NewDocumentCommand}{\RequirePackage{xparse}}{}

\def\ducksay@version{2.7}
\def\ducksay@date{2024-03-29}

\ProvidesExplPackage
  {ducksay}           {\ducksay@date}
  {\ducksay@version}  {cowsay for LaTeX}

\int_new:N \l_ducksay_msg_width_int
\int_new:N \l_ducksay_msg_height_int
\int_new:N \l_ducksay_tail_symbol_count_int
\seq_new:N \l_ducksay_msg_lines_seq
\seq_new:N \l_ducksay_defined_animals_seq
\tl_new:N \l_ducksay_align_tl
\tl_new:N \l_ducksay_msg_align_tl
\tl_new:N \l_ducksay_animal_tl
\tl_new:N \l_ducksay_body_tl
\tl_new:N \l_ducksay_bubble_tl
\tl_new:N \l_ducksay_tmpa_tl
\tl_new:N \l_ducksay_tail_symbol_out_one_tl
\tl_new:N \l_ducksay_tail_symbol_out_two_tl
\tl_new:N \l_ducksay_tail_symbol_in_tl
\bool_new:N \l_ducksay_version_one_bool
\bool_new:N \l_ducksay_version_two_bool
\bool_new:N \l_ducksay_random_animal_bool
\box_new:N \l_ducksay_tmpa_box
\regex_const:Nn \c_ducksay_textcolor_regex
  { \cO(?:\\textcolor\{(.*?)\}\{(.*?)\}) }
\regex_const:Nn \c_ducksay_color_delim_regex
  { \cO(?:\\bgroup\\color\{(.*?)\}(.*)\\egroup) }
\regex_const:Nn \c_ducksay_color_regex
  { \cO(?:\\color\{(.*?)\}) }
\msg_new:nnn { ducksay } { load-time-only }
  { The~`#1`~key~is~to~be~used~only~during~package~load~time. }
\keys_define:nn { ducksay }
  {
    ,bubble .tl_set:N      = \l_ducksay_bubble_tl
    ,body   .tl_set:N      = \l_ducksay_body_tl
    ,align  .tl_set:N      = \l_ducksay_align_tl
    ,align  .value_required:n = true
    ,wd     .int_set:N     = \l_ducksay_msg_width_int
    ,wd     .initial:n     = -\c_max_int
    ,wd     .value_required:n = true
    ,ht     .int_set:N     = \l_ducksay_msg_height_int
    ,ht     .initial:n     = -\c_max_int
    ,ht     .value_required:n = true
    ,animal .code:n        =
      { \keys_define:nn { ducksay } { default_animal .meta:n = { #1 } } }
    ,animal .initial:n     = duck
    ,msg-align .tl_set:N   = \l_ducksay_msg_align_tl
    ,msg-align .initial:n  = l
    ,msg-align .value_required:n = true
    ,rel-align .tl_set:N   = \l_ducksay_rel_align_tl
    ,rel-align .initial:n  = l
    ,rel-align .value_required:n = true
    ,ligatures .tl_set:N   = \l_ducksay_ligatures_tl
    ,ligatures .initial:n  = { `<>,'- }
    ,tail-1    .tl_set:N   = \l_ducksay_tail_symbol_out_one_tl
    ,tail-1    .initial:x  = \c_backslash_str
    ,tail-2    .tl_set:N   = \l_ducksay_tail_symbol_out_two_tl
    ,tail-2    .initial:x  = \c_backslash_str
    ,no-tail   .meta:n     = { tail-1 = { ~ }, tail-2 = { ~ } }
    ,think     .meta:n     = { tail-1 = { O }, tail-2 = { o } }
    ,random    .bool_set:N = \l_ducksay_random_animal_bool
    ,say       .code:n     =
      {
        \exp_args:Nx \DucksayOptions
          { tail-1 = { \c_backslash_str }, tail-2 = { \c_backslash_str } }
      }
    ,schroedinger .code:n  =
      {
        \int_compare:nNnTF { \int_rand:n { 2 } } = \c_one_int
          { \keys_set:nn { ducksay } { animal = schroedinger-dead } }
          { \keys_set:nn { ducksay } { animal = schroedinger-alive } }
      }
    ,schroedinger .value_forbidden:n = true
    ,version   .choice:
    ,version / 1 .code:n   =
      {
        \bool_set_false:N \l_ducksay_version_two_bool
        \bool_set_true:N  \l_ducksay_version_one_bool
      }
    ,version / 2 .code:n   =
      {
        \bool_set_false:N \l_ducksay_version_one_bool
        \bool_set_true:N  \l_ducksay_version_two_bool
      }
    ,version   .initial:n  = 2
  }
\cs_if_exist:NTF \ProcessKeyOptions
  { \ProcessKeyOptions [ ducksay ] }
  {
    \RequirePackage { l3keys2e }
    \ProcessKeysOptions { ducksay }
  }
\keys_define:nn { ducksay }
  {
    version .code:n = \msg_error:nnn { ducksay } { load-time-only } { version }
  }
\keys_define:nn { ducksay / add-animal }
  {
    ,tail-symbol .code:n    =
      \tl_set:Nx \l_ducksay_tail_symbol_in_tl { \tl_to_str:n { #1 } }
    ,tail-symbol .initial:o = \c_backslash_str
    ,tail-count  .int_set:N = \l_ducksay_tail_symbol_count_int
    ,tail-count  .initial:n = 2
  }
\cs_generate_variant:Nn \tl_replace_once:Nnn { NVn }
\cs_generate_variant:Nn \tl_replace_all:Nnn { NVn }
\cs_generate_variant:Nn \keys_set:nn { nx }
\cs_set_eq:NN \__ducksay_everyeof:w \tex_everyeof:D
\cs_set_eq:NN \__ducksay_scantokens:w \tex_scantokens:D
\IfFormatAtLeastTF{2024-06-01}
  {
    \cs_new_protected:Npn \ducksay_replace_verb_newline:Nn #1 #2
      { \tl_replace_all:Nnn #1 \obeyedline {#2} }
  }
  {
    \cs_new_protected:Npx \ducksay_replace_verb_newline:Nn #1 #2
      { \tl_replace_all:Nnn #1 { \char_generate:nn { 13 } { 12 } } {#2} }
  }
\IfFormatAtLeastTF{2024-06-01}
  {
    \cs_new_protected:Npn \ducksay_replace_verb_newline_newline:Nn #1 #2
      { \tl_replace_all:Nnn #1 { \obeyedline \obeyedline } {#2} }
  }
  {
    \cs_new_protected:Npx \ducksay_replace_verb_newline_newline:Nn #1 #2
      {
        \tl_replace_all:Nnn #1
          { \char_generate:nn { 13 } { 12 } \char_generate:nn { 13 } { 12 } }
          {#2}
      }
  }
\cs_new_protected:Npn \ducksay_process_verb_newline:nnn #1 #2 #3
  {
    \tl_set:Nn \ProcessedArgument { #3 }
    \ducksay_replace_verb_newline_newline:Nn \ProcessedArgument { #2 }
    \ducksay_replace_verb_newline:Nn \ProcessedArgument { #1 }
  }
\cs_new_protected:Npn \ducksay_add_animal_inner:nnnn #1 #2 #3 #4
  {
    \group_begin:
      \keys_set:nn { ducksay / add-animal } { #1 }
      \tl_set:Nn \l_ducksay_tmpa_tl { \ #3 }
      \int_compare:nNnTF { \l_ducksay_tail_symbol_count_int } < { \c_zero_int }
        {
          \tl_replace_once:NVn
            \l_ducksay_tmpa_tl
            \l_ducksay_tail_symbol_in_tl
            \l_ducksay_tail_symbol_out_one_tl
          \tl_replace_all:NVn
            \l_ducksay_tmpa_tl
            \l_ducksay_tail_symbol_in_tl
            \l_ducksay_tail_symbol_out_two_tl
        }
        {
          \int_compare:nNnT { \l_ducksay_tail_symbol_count_int } >
            { \c_zero_int }
            {
              \tl_replace_once:NVn
                \l_ducksay_tmpa_tl
                \l_ducksay_tail_symbol_in_tl
                \l_ducksay_tail_symbol_out_one_tl
              \int_step_inline:nnn { 2 } { \l_ducksay_tail_symbol_count_int }
                {
                  \tl_replace_once:NVn
                    \l_ducksay_tmpa_tl
                    \l_ducksay_tail_symbol_in_tl
                    \l_ducksay_tail_symbol_out_two_tl
                }
            }
        }
      \tl_map_inline:Nn \l_ducksay_ligatures_tl
        { \tl_replace_all:Nnn \l_ducksay_tmpa_tl { ##1 } { { ##1 } } }
      \ducksay_replace_verb_newline:Nn \l_ducksay_tmpa_tl
        { \tabularnewline\null }
      \exp_args:NNnV
    \group_end:
    \tl_set:cn { l_ducksay_animal_#2_tl } \l_ducksay_tmpa_tl
    \exp_args:Nnx \keys_define:nn { ducksay }
      {
        #2 .code:n =
          {
            \exp_not:n { \tl_set_eq:NN \l_ducksay_animal_tl }
            \exp_not:c { l_ducksay_animal_#2_tl }
            \exp_not:n { \exp_args:NV \DucksayOptions }
            \exp_not:c { l_ducksay_animal_#2_options_tl }
          }
      }
    \tl_if_exist:cF { l_ducksay_animal_#2_options_tl }
      { \tl_new:c { l_ducksay_animal_#2_options_tl } }
    \IfBooleanT { #4 }
      { \keys_define:nn { ducksay } { default_animal .meta:n = { #2 } } }
    \seq_if_in:NnF \l_ducksay_defined_animals_seq { #2 }
      { \seq_push:Nn \l_ducksay_defined_animals_seq { #2 } }
  }
\cs_generate_variant:Nn \ducksay_add_animal_inner:nnnn { nnVn }
\cs_new_protected:Npn \ducksay_default_or_random_animal:
  {
    \tl_if_empty:NT \l_ducksay_animal_tl
      {
        \bool_if:NTF \l_ducksay_random_animal_bool
          {
            \keys_set:nx { ducksay }
              { \seq_rand_item:N \l_ducksay_defined_animals_seq }
          }
          { \keys_set:nn { ducksay } { default_animal } }
      }
  }
\NewDocumentCommand \DefaultAnimal { m }
  {
    \keys_define:nn { ducksay } { default_animal .meta:n = { #1 } }
  }
\NewDocumentCommand \DucksayOptions { m }
  {
    \keys_set:nn { ducksay } { #1 }
  }
\NewDocumentCommand \AddAnimal { s O{} m +v }
  {
    \ducksay_add_animal_inner:nnnn { #2 } { #3 } { #4 } { #1 }
  }
\NewDocumentCommand \AddColoredAnimal { s O{} m +v }
  {
    \tl_set:Nn \l_ducksay_tmpa_tl { #4 }
    \regex_replace_all:NnN \c_ducksay_color_delim_regex
      { \c{bgroup}\c{color}\cB\{\1\cE\}\2\c{egroup} }
      \l_ducksay_tmpa_tl
    \regex_replace_all:NnN \c_ducksay_color_regex
      { \c{color}\cB\{\1\cE\} }
      \l_ducksay_tmpa_tl
    \regex_replace_all:NnN \c_ducksay_textcolor_regex
      { \c{textcolor}\cB\{\1\cE\}\cB\{\2\cE\} }
      \l_ducksay_tmpa_tl
    \ducksay_add_animal_inner:nnVn { #2 } { #3 } \l_ducksay_tmpa_tl { #1 }
  }
\NewDocumentCommand \AnimalOptions { s m m }
  {
    \tl_if_exist:cTF { l_ducksay_animal_#2_options_tl }
      {
        \IfBooleanTF { #1 }
          { \tl_set:cn }
          { \tl_put_right:cn }
      }
      { \tl_set:cn }
    { l_ducksay_animal_#2_options_tl } { #3, }
  }
\bool_if:NT \l_ducksay_version_one_bool
  { \file_input:n { ducksay.code.v1.tex } }
\bool_if:NT \l_ducksay_version_two_bool
  { \file_input:n { ducksay.code.v2.tex } }
\ExplSyntaxOff
\input{ducksay.animals.tex}
%% 
%%
%% End of file `ducksay.sty'.
