%%
%% This is file `fistrum.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% fistrum.dtx  (with options: `package')
%% 
%% This file is part of the package fistrum for use with LaTeX2e.
%% 
%% Function: Access to 150 paragraphs of pecadorrr text.
%% 
%% This program may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%%    http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%% 
%% Please send error reports and suggestions for improvements to
%%     https://github.com/daviddavo/fistrum
%% 
\def\fistrumversion{0.1}
\def\fistrumdate{2023-02-28}
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{l3keys2e}
\@ifundefined{NewDocumentCommand}
  {\RequirePackage{xparse}}{}
\ProvidesExplPackage {fistrum} {\fistrumdate} {\fistrumversion}
  {150 paragraphs of Lorem Fistrum dummy text}
\int_new:N \g__fistrum_par_int
\tl_new:N \g__fistrum_language_tl
\tl_new:N \g_fistrum_default_range_tl
\tl_new:N \l__fistrum_output_tl
\str_new:N \g__fistrum_text_str
\str_new:N \l__fistrum_sep_set_str
\bool_new:N \l__fistrum_autolang_bool
\quark_new:N \q__fistrum_mark
\scan_new:N \s__fistrum
\str_new:N \l__fistrum_tmpa_str
\int_new:N \l__fistrum_a_int
\int_new:N \l__fistrum_b_int
\cs_new_eq:NN \__fistrum_tmp:w ?
\clist_map_inline:nn { start, itemstart, itemseparator, itemend, end }
  {
    \clist_map_inline:nn { par, sentence }
      {
        \clist_map_inline:nn { { }, star, nostar }
          { \tl_new:c { l__fistrum_##1_#1_####1_tl } }
      }
    \tl_new:c { l__fistrum_par_#1_parsepar_tl }
  }
\tl_set:Nn \l__fistrum_par_itemseparator_parsepar_tl { ~ }
\cs_new_protected:Npn \__fistrum_parse_par_range:nNN #1 #2 #3
  {
    \tl_if_blank:nTF {#1}
      { \exp_args:NV \__fistrum_parse_range_arg:nNNn \g_fistrum_default_range_tl }
      { \__fistrum_parse_range_arg:nNNn {#1} }
          #2 #3 { \g__fistrum_par_int }
  }
\cs_new_protected:Npn \__fistrum_parse_sentence_range:nNN #1 #2 #3
  { \__fistrum_parse_range_arg:nNNn {#1} #2 #3 { \c_max_int } }
\cs_new_protected:Npn \__fistrum_parse_range_arg:nNNn #1
  {
    \exp_last_unbraced:No \__fistrum_parse_range_arg:wnNNn
      \tl_to_str:n { #1 - - } \s__fistrum {#1}
  }
\cs_new_protected:Npn \__fistrum_parse_range_arg:wnNNn
    #1 - #2 - #3 \s__fistrum #4 #5#6 #7
  {
    \str_if_eq:nnTF {#3} { - }
      {
        \__fistrum_int_set:Nnn #5 {#1} { 1 }
        \__fistrum_int_set:Nnn #6 {#2} {#7}
      }
      {
        \tl_if_empty:nTF {#3}
          {
            \__fistrum_int_set:Nnn #5 {#1} { \ERROR }
            \int_set_eq:NN #6 #5
          }
          {
            \msg_error:nnn { fistrum } { invalid-range } {#4}
            \__fistrum_parse_range_arg:nNNn { 2 - 1 } #5 #6 {#7}
          }
      }
  }
\cs_new_protected:Npn \__fistrum_int_set:Nnn #1 #2 #3
  { \int_set:Nn #1 { \tl_if_blank:nT {#2} {#3} #2 } }
\cs_generate_variant:Nn \__fistrum_parse_par_range:nNN { e }
\cs_generate_variant:Nn \__fistrum_parse_sentence_range:nNN { e }
\cs_new:Npn \__fistrum_sep_item:nn #1 #2
  { \exp_not:v { l__fistrum_#1_#2_ \l__fistrum_sep_set_str _tl } }
\cs_new:Npn \fistrum_get_range:nn #1 #2
  {
    \__fistrum_sep_item:nn { par } { start }
    \use:e
      {
        \exp_not:N \__fistrum_get_paragraph:ww
        \__fistrum_build_list:nn {#1} {#2}
        \exp_not:N \q__fistrum_mark ;
        \exp_not:N \q__fistrum_mark ; \s__fistrum
      }
    \__fistrum_sep_item:nn { par } { end }
  }
\cs_new:Npn \__fistrum_build_list:nn #1 #2
  {
    \int_step_function:nnN
      { \int_max:nn {#1} { 1 } }
      { \int_min:nn {#2} { \g__fistrum_par_int } }
      \__fistrum_build_list_aux:n
  }
\cs_new:Npn \__fistrum_build_list_aux:n #1 { #1 ; }
\cs_new:Npn \__fistrum_get_paragraph:ww #1 ; #2 ;
  {
    \if_meaning:w \q__fistrum_mark #2
      \if_meaning:w \q__fistrum_mark #1
        \__fistrum_get_paragraph_end:w
      \else:
        \fistrum_get_paragraph:n {#1}
      \fi:
    \else:
      \fistrum_get_paragraph:n {#1}
      \__fistrum_sep_item:nn { par } { itemseparator }
    \fi:
    \__fistrum_get_paragraph:ww #2 ;
  }
\cs_new:Npn \__fistrum_get_paragraph_end:w #1 \s__fistrum { \fi: \fi: }
\cs_new:Npn \fistrum_get_paragraph:n #1
  {
    \__fistrum_sep_item:nn { par } { itemstart }
    \__fistrum_unexpanded_par:n {#1}
    \__fistrum_sep_item:nn { par } { itemend }
  }
\cs_new:Npn \__fistrum_unexpanded_par:n #1
  {
    \bool_lazy_and:nnT
        { \int_compare_p:nNn { 0 } < {#1} }
        { \int_compare_p:nNn {#1}  < { \g__fistrum_par_int + 1 } }
      { \exp_not:v { g__fistrum_par_#1_tl } }
  }
\cs_new:Npn \fistrum_get_sentences:nnn #1 #2 #3
  {
    \__fistrum_sep_item:nn { sentence } { start }
    \exp_args:Ne \use_ii_i:nn { { \int_max:nn {#1} { 1 } } }
      { \__fistrum_get_sentences:nnnw { 1 } } {#2}
      #3 ~ \q__fistrum_mark .~ \s__fistrum
    \__fistrum_sep_item:nn { sentence } { end }
  }
\cs_new:Npn \__fistrum_get_sentences:nnnw #1 #2 #3 #4 .~
  {
    \int_compare:nNnT {#1} > {#3} { \__fistrum_get_sentences_end:w }
    \use:nn { \if_meaning:w \q__fistrum_mark } #4
      \exp_after:wN \__fistrum_get_sentences_end:w
    \else:
      \int_compare:nNnF {#1} < {#2}
        {
          \int_compare:nNnF {#1} = {#2}
            { \__fistrum_sep_item:nn { sentence } { itemseparator } }
          \__fistrum_sep_item:nn { sentence } { itemstart }
          \exp_not:n { #4 . }
          \__fistrum_sep_item:nn { sentence } { itemend }
        }
    \fi:
    \exp_args:Nf \__fistrum_get_sentences:nnnw { \int_eval:n { #1 + 1 } }
      {#2} {#3}
  }
\cs_new:Npn \__fistrum_get_sentences_end:w #1 \s__fistrum { }
\cs_generate_variant:Nn \fistrum_get_sentences:nnn { nnV }
\NewDocumentCommand \fistrumPar { m }
  {
    \__fistrum_deprecated:n { FistrumPar }
    \__fistrum_unexpanded_par:n {#1} \par
  }
\cs_new_protected:Npn \__fistrum_element_set:nnn #1 #2 #3
  { \tl_set:cn { l__fistrum_ #1 _ \IfBooleanF {#2} { no } star _tl } {#3} }
\cs_new_protected:Npn \__fistrum_deprecated:n #1
  {
    \msg_warning:nnn { fistrum } { cmd-deprecated } {#1}
    \cs_gset_eq:NN \__fistrum_deprecated:n \use_none:n
  }
\cs_set_protected:Npn \__fistrum_tmp:w #1 #2 #3 #4
  {
    \str_set:Nx \l__fistrum_tmpa_str
      { #2 \tl_if_empty:nTF {#4} {#3} { start } }
    \use:e
      {
        \NewDocumentCommand \exp_not:c { SetFistrum #1 List #2 #3 }
            { s +m \tl_if_empty:nF {#4} { +m } }
          {
            \__fistrum_deprecated:n { SetFistrum #1 List #2 #3 }
            \__fistrum_element_set:nnn
              { \exp_args:Ne \str_lowercase:n { #1_\l__fistrum_tmpa_str } }
              {##1} {##2}
            \tl_if_empty:nT {#4} { \use_none:nnnn }
            \__fistrum_element_set:nnn { \str_lowercase:n { #1_#2 #4 } }
              {##1} {##3}
          }
      }
  }
\clist_map_inline:nn { Par, Sentence }
  {
    \clist_map_inline:nn
      { { Start } { }, { End } { }, { Surrounders } { end } }
      { \__fistrum_tmp:w {#1} { Item } ##1 \__fistrum_tmp:w {#1} { } ##1 }
    \__fistrum_tmp:w {#1} { Item } { Separator } { }
  }
\NewDocumentCommand \SetFistrumDefault { m }
  {
    \__fistrum_parse_par_range:eNN {#1} \l__fistrum_a_int \l__fistrum_b_int
    \tl_gset:Nx \g_fistrum_default_range_tl
      { \int_use:N \l__fistrum_a_int - \int_use:N \l__fistrum_b_int }
  }
\NewDocumentCommand \fistrum { s O { \g_fistrum_default_range_tl } o }
  {
    \__fistrum_do:nnnn {#1} {#2} {#3}
      {
        \__fistrum_set_hyphens:
        \tl_use:N ##1
        \__fistrum_restore_hyphens:
      }
  }
\NewDocumentCommand \unpackfistrum { s O { \g_fistrum_default_range_tl } o }
  { \__fistrum_do:nnnn {#1} {#2} {#3} { \tl_gset_eq:NN \fistrumexp ##1 } }
\cs_new_eq:NN \fistrumexp \prg_do_nothing:
\cs_new_protected:Npn \__fistrum_do:nnnn #1 #2 #3 #4
  {
    \cs_set_protected:Npn \__fistrum_do:N ##1 {#4}
    \__fistrum_parse_par_range:eNN {#2} \l__fistrum_a_int \l__fistrum_b_int
    \str_set_eq:NN \l__fistrum_tmpa_str \l__fistrum_sep_set_str
    \str_set:Nx \l__fistrum_sep_set_str { \IfBooleanF {#1} { no } star }
    \bool_lazy_or:nnTF
        { \tl_if_novalue_p:n {#3} }
        { \tl_if_blank_p:n {#3} }
      {
        \tl_set:Nx \l__fistrum_output_tl
          { \fistrum_get_range:nn { \l__fistrum_a_int } { \l__fistrum_b_int } }
      }
      {
        \str_set:Nn \l__fistrum_sep_set_str { parsepar }
        \tl_set:Nx \l__fistrum_output_tl
          { \fistrum_get_range:nn { \l__fistrum_a_int } { \l__fistrum_b_int } }
        \str_set:Nx \l__fistrum_sep_set_str { \IfBooleanF {#1} { no } star }
        \__fistrum_parse_sentence_range:eNN {#3} \l__fistrum_a_int \l__fistrum_b_int
        \tl_set:Nx \l__fistrum_output_tl
          {
            \fistrum_get_sentences:nnV { \l__fistrum_a_int } { \l__fistrum_b_int }
              \l__fistrum_output_tl
          }
      }
    \str_set_eq:NN \l__fistrum_sep_set_str \l__fistrum_tmpa_str
    \__fistrum_do:N \l__fistrum_output_tl
  }
\cs_new_eq:NN \__fistrum_do:N ?
\cs_new_protected:Npn \__fistrum_set_hyphens:
  {
    \bool_if:NTF \l__fistrum_autolang_bool
      { \use:n } { \use_none:n }
      {
        \cs_if_exist:NTF \hyphenrules
          {
            \cs_if_exist:cTF { ver@polyglossia.sty }
              { \__fistrum_set_hyphens_polyglossia: }
              { \__fistrum_set_hyphens_babel: }
          }
          { \__fistrum_set_hyphens_raw: }
      }
  }
\cs_new_protected:Npn \__fistrum_restore_hyphens:
  { \prg_do_nothing: }
\cs_new_protected:Npn \__fistrum_set_hyphens_babel:
  {
    \cs_if_exist:cTF { l@ \g__fistrum_language_tl }
      {
        \exp_args:NV \hyphenrules \g__fistrum_language_tl
        \cs_set_protected:Npx \__fistrum_restore_hyphens:
          { \exp_not:N \hyphenrules { \languagename } }
      }
      { \__fistrum_lang_not_available: }
  }
\cs_new_protected:Npn \__fistrum_set_hyphens_polyglossia:
  {
    \cs_if_exist:cTF { \g__fistrum_language_tl @loaded }
      {
        \exp_args:NnV \begin{hyphenrules} \g__fistrum_language_tl
        \cs_set_protected:Npn \__fistrum_restore_hyphens:
          { \end{hyphenrules} }
      }
      { \__fistrum_set_hyphens_raw: }
  }
\cs_new_protected:Npn \__fistrum_set_hyphens_raw:
  {
    \cs_if_exist:cTF { l@ \g__fistrum_language_tl }
      {
        \use:x
          {
            \language \use:c { l@ \g__fistrum_language_tl }
            \cs_set_protected:Npn \__fistrum_restore_hyphens:
              { \language \int_eval:n { \language } \scan_stop: }
          }
      }
      { \__fistrum_lang_not_available: }
  }
\cs_new_protected:Npn \__fistrum_lang_not_available:
  {
    \str_if_eq:VVF \g__fistrum_language_tl \languagename
      {
        \msg_warning:nnx { fistrum } { missing-language }
          { \g__fistrum_language_tl }
        \tl_gset_eq:NN \g__fistrum_language_tl \languagename
      }
  }
\cs_new_protected:Npn \NewFistrumPar #1
  {
    \int_gincr:N \g__fistrum_par_int
    \tl_gclear_new:c { g__fistrum_par_ \int_use:N \g__fistrum_par_int _tl }
    \tl_gset:cn { g__fistrum_par_ \int_use:N \g__fistrum_par_int _tl } {#1}
  }
\NewDocumentCommand \SetFistrumText { m }
  {
    \str_if_eq:VnF \g__fistrum_text_str {#1}
      {
        \tl_gset:Nn \g__fistrum_language_tl { english }
        \int_gzero:N \g__fistrum_par_int
        \file_input:n { #1.ftd }
        \str_gset:Nn \g__fistrum_text_str {#1}
      }
  }
\NewDocumentCommand \SetFistrumLanguage { m }
  { \tl_gset:Nn \g__fistrum_language_tl {#1} }
\cs_new_protected:Npn \__fistrum_delim_restore:nnn #1 #2 #3
  {
    \keys_set:nn { fistrum }
      {
        #1-before  = , #1-begin  = , #1-end  = , #1-after  = ,
        #1-before* = , #1-begin* = , #1-end* = , #1-after* = ,
        #1-sep = {#2}, #1-sep* = {#3}
      }
  }
\cs_new_protected:Nn \__fistrum_restore_sentence_list:
  { \__fistrum_delim_restore:nnn { sentence } { ~ } { ~ } }
\cs_new_eq:NN \__fistrum_restore_par_list: ?
\cs_new_protected:Npn \fistrumRestoreParList
  {
    \__fistrum_deprecated:n { FistrumRestoreParList }
    \__fistrum_restore_par_list:
  }
\cs_new_protected:Npn \fistrumRestoreSentenceList
  {
    \__fistrum_deprecated:n { FistrumRestoreSentenceList }
    \__fistrum_restore_sentence_list:
  }
\cs_new_protected:Npn \fistrumRestoreAll
  {
    \__fistrum_deprecated:n { FistrumRestoreAll }
    \__fistrum_restore_par_list: \__fistrum_restore_sentence_list:
  }
\NewDocumentCommand \setfistrum { +m }
  { \keys_set:nn { fistrum } {#1} }
\keys_define:nn { fistrum }
  {
    nopar .choice: ,
    nopar / true .code:n =
      {
        \cs_gset_protected:Npn \__fistrum_restore_par_list:
          { \__fistrum_delim_restore:nnn { par } { ~ } { \par } }
      } ,
    nopar / false .code:n =
      {
        \cs_gset_protected:Nn \__fistrum_restore_par_list:
          { \__fistrum_delim_restore:nnn { par } { \par } { ~ } }
      } ,
    nopar .initial:n = false ,
    nopar .default:n = true  ,
    auto-lang .bool_set:N = \l__fistrum_autolang_bool ,
    auto-lang .initial:n = true ,
    auto-lang .default:n = true ,
    text .code:n = \SetFistrumText{#1} ,
    text .value_required:n = true ,
    language .tl_gset:N = \g__fistrum_language_tl ,
    language .value_required:n = true ,
    default-range .code:n = \SetFistrumDefault{#1} ,
    default-range .initial:n = 1-7 ,
    default-range .default:n = 1-7 ,
  }
\cs_set_protected:Npn \__fistrum_tmp:w #1 #2 #3
  {
    \keys_define:nn { fistrum }
      {
        #1-before #2 .tl_set:c = l__fistrum_#1_start         _#3star_tl ,
        #1-begin  #2 .tl_set:c = l__fistrum_#1_itemstart     _#3star_tl ,
        #1-sep    #2 .tl_set:c = l__fistrum_#1_itemseparator _#3star_tl ,
        #1-end    #2 .tl_set:c = l__fistrum_#1_itemend       _#3star_tl ,
        #1-after  #2 .tl_set:c = l__fistrum_#1_end           _#3star_tl ,
      }
  }
\__fistrum_tmp:w { par } { } { no } \__fistrum_tmp:w { sentence } { } { no }
\__fistrum_tmp:w { par }  *  {    } \__fistrum_tmp:w { sentence }  *  {    }
\ExplSyntaxOff
\setfistrum{text=fistrum-es}
\ProcessKeysOptions{fistrum}
\ExplSyntaxOn
\__fistrum_restore_par_list:
\__fistrum_restore_sentence_list:
\msg_new:nnn { fistrum } { invalid-range }
  { Invalid~number~or~range~'#1'. }
\msg_new:nnn { fistrum } { cmd-deprecated }
  {
    Command~'\iow_char:N\\#1'~deprecated. \\
    See~the~fistrum~documentation~for~help.
  }
\msg_new:nnn { fistrum } { missing-language }
  {
    Unknown~language~'#1'.~Hyphenation~patterns~for~
    '\languagename'~will~be~used~instead.
    \sys_if_engine_luatex:T
      {
        \\ \\
        \cs_if_exist:cTF { ver@polyglossia.sty }
          {
            With~polyglossia,~you~have~to~explicitly~load~languages~
            with~\iow_char:N\\setotherlanguage{#1}~or~similar.
          }
          {
            With~LuaTeX,~fistrum~requires~babel~to~get~proper~
            hyphenation~(you~can~use~
            \iow_char:N\\usepackage[base]{babel}).
          }
      }
  }
%% 
%%
%% End of file `fistrum.sty'.
