%%
%% This is file 'bxjaprnind.sty'.
%% 
%% Copyright (c) 2012-2021 Takayuki YATO (aka. "ZR")
%%   GitHub:   https://github.com/zr-tex8r
%%   Twitter:  @zr_tex8r
%%
%% This package is distributed under the MIT License.
%%

%% package declaration
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{bxjaprnind}[2021/06/18 v0.4a]
\def\bxpi@pkgname{bxjaprnind}

%% code guards
\edef\bxpi@restore@codes{%
\catcode33=\the\catcode33%
\catcode34=\the\catcode34%
\catcode39=\the\catcode39%
\catcode45=\the\catcode45%
\catcode46=\the\catcode46%
\catcode47=\the\catcode47%
\catcode58=\the\catcode58%
\catcode59=\the\catcode59%
\catcode60=\the\catcode60%
\catcode62=\the\catcode62%
\endlinechar=\the\endlinechar%
\relax}%
\catcode33=12 % <!>
\catcode34=12 % <">
\catcode39=12 % <'>
\catcode45=12 % <->
\catcode46=12 % <.>
\catcode47=12 % </>
\catcode58=12 % <:>
\catcode59=12 % <;>
\catcode60=12 % <<>
\catcode62=12 % <>>
\AtEndOfPackage{%
\bxpi@restore@codes
\undef\bxpi@restore@codes}

%--------------------------------------- prologue

%% packages
\RequirePackage{bxtoolbox}

%% variables
\newbool{bxpi@everyhook}
\newbool{bxpi@force}
\newdimen\bxpi@dima

%--------------------------------------- options

%% force
\DeclareOption{force}{%
  \bxpi@forcetrue
}
%% dispatch
\ProcessOptions*

%--------------------------------------- set the paragraph hook

%% Checks if everyhook package is available
\bxpi@everyhookfalse
\ifbxineTeX
  \IfFileExists{everyhook.sty}{%
    \bxpi@everyhooktrue
  }{}
\fi

\ifbxpi@everyhook
  % if everyhook is available...
  \RequirePackage{everyhook}[2011/02/04]

  % register the hook
  \PushPostHook{par}{\bxpi@par@hook}

\else
  % otherwise...
  % makes a hook to \everypar for myself
  \let\bxpi@everypar\everypar
  \newtoks\everypar
  \everypar\bxpi@everypar
  \bxpi@everypar{\the\expandafter\everypar\bxpi@par@hook}%

  \ifbxpi@force
    \PackageError\bxpi@pkgname{%
      Option 'force' is not supported because\MessageBreak
      package 'everyhook' is not available%
    }{\@ehc}
    \bxpi@forcefalse
  \fi
\fi
\endlinechar=-1 %
%--------------------------------------- the newline hook

%% adds hooks to (subcommands of) \\
\preto\@xnewline{\bxpi@init@param}
\let\bxpi@org@@newline\@newline
\def\@newline[#1]{
  \bxpi@parse@arg{#1}
  \expandafter\bxpi@org@@newline\expandafter[\bxpi@res]
}
\begingroup
  \toks@\expandafter{\@gnewline{#1}}
  \edef\bxpi@next{
    \gdef\noexpand\@gnewline##1{
      \the\toks@
      \noexpand\bxpi@paren@indent
    }
  }
  \bxpi@next
\endgroup

%--------------------------------------- helpers

%% \bxpi@inhibitglue
\ifdef\inhibitglue{
  \let\bxpi@inhibitglue\inhibitglue
}{%else
  \let\bxpi@inhibitglue\relax
  \PackageWarningNoLine\bxpi@pkgname{
    Command \string\inhibitglue\space
    unavailable in current settings;\MessageBreak
    the package may not work properly
  }
}

%--------------------------------------- main

%% \bxpi@parhead
\def\bxpi@parhead{0}
%% \bxpi@linehead
\def\bxpi@linehead{0}
%% \bxpi@dialogue
\def\bxpi@dialogue{0.5}
%% \bxpi@lineheadforce
\def\bxpi@lineheadforce{1}
%% switch bxpi@d@parprnind
\newbool{bxpi@d@parprnind}\bxpi@d@parprnindtrue
%% switch bxpi@d@lineprnind
\newbool{bxpi@d@lineprnind}\bxpi@d@lineprnindtrue
%% switch bxpi@diaprnind
\newbool{bxpi@diaprnind}\bxpi@diaprnindfalse
%% switch bxpi@prnind
\newbool{bxpi@prnind}
%% switch bxpi@forceind
\newbool{bxpi@forceind}
%% \bxpi@choice
\let\bxpi@choice\relax
%% \bxpi@special
\let\bxpi@special\relax

%%<*> \useparheadparenindent
\bxNewrobustcmd*{\useparheadparenindent}{
  \bxpi@d@parprnindtrue
}

%%<*> \nouseparheadparenindent
\bxNewrobustcmd*{\nouseparheadparenindent}{
  \bxpi@d@parprnindfalse
}

%%<*> \uselineheadparenindent
\bxNewrobustcmd*{\uselineheadparenindent}{
  \bxpi@d@lineprnindtrue
}

%%<*> \nouselineheadparenindent
\bxNewrobustcmd*{\nouselineheadparenindent}{
  \bxpi@d@lineprnindfalse
}

%%<*> \usedialogueparenindent
\bxNewrobustcmd*{\usedialogueparenindent}{
  \bxpi@diaprnindtrue
}

%%<*> \nousedialogueparenindent
\bxNewrobustcmd*{\nousedialogueparenindent}{
  \bxpi@diaprnindfalse
}

%%<*> \parheadparenindentamount
% Sets the value of \bxpi@parhead.
\bxNewrobustcmd*{\parheadparenindentamount}[1]{
  \edef\bxpi@parhead{#1}
}

%<*> \lineheadparenindentamount
% Sets the value of \bxpi@linehead.
\bxNewrobustcmd*{\lineheadparenindentamount}[1]{
  \edef\bxpi@linehead{#1}
}

%<*> \lineheadforceindentamount
% Sets the value of \bxpi@lineheadforce.
\bxNewrobustcmd*{\lineheadforceindentamount}[1]{
  \edef\bxpi@lineheadforce{#1}
}

%<*> \dialogueparenindentamount
% Sets the value of \bxpi@dialogue.
\bxNewrobustcmd*{\dialogueparenindentamount}[1]{
  \edef\bxpi@dialogue{#1}
}

%%<*> \prnind
%
\bxNewrobustcmd*{\prnind}{
  \leavevmode\relax
  \bxpi@prnindtrue
  \bxpi@forceindfalse
  \let\bxpi@choice=m
  \let\bxpi@special\relax
  \kernel@ifnextchar[{
    \bxpi@prnind@a
  }{%else
    \let\bxpi@value\bxpi@parhead
    \bxpi@paren@indent
  }
}
\def\bxpi@prnind@a[#1]{
  \def\bxpi@value{#1}
  \bxpi@paren@indent
}

%% \bxpi@init@param
% Initializes the parameters.
% (Invoked at every \\.)
\def\bxpi@init@param{
  \bxpi@prnind@linedflt
  \bxpi@forceindfalse
  \let\bxpi@choice=l
  \let\bxpi@value\bxpi@linehead
  \let\bxpi@special\relax
}

%% \bxpi@parse@arg{<str>}
% Parses the option argument of \\. It reads the prefix > and !
% and sets the switches bxpi@forceind and bxpi@prnind, then
% sets the remaining string to \bxpi@res, which is passed to
% the original argument parser (\@newline).
\def\bxpi@parse@arg#1{
  \bxpi@parse@arg@a#1\bxpi@end
}
\def\bxpi@parse@arg@a{
  \futurelet\bxpi@tok\bxpi@parse@arg@b
}
\def\bxpi@parse@arg@b{
  \bxIfx{\bxpi@tok\bgroup}{
    \bxpi@parse@arg@c
  }{%else
    \bxpi@parse@arg@d
  }
}
\def\bxpi@parse@arg@c#1\bxpi@end{
  \ifstrempty{#1}{
    \def\bxpi@res{\z@}
  }{%else
    \def\bxpi@res{#1}
  }
}
\def\bxpi@parse@arg@d#1{
  \bxIfx{,#1}{
    \bxpi@parse@arg@a
  }{\bxIfx{!#1}{
    \ifbxpi@prnind \bxpi@prnindfalse
    \else \bxpi@prnindtrue
    \fi
    \bxpi@parse@arg@a
  }{\bxIfx{>#1}{
    \bxpi@forceindtrue
    \bxpi@parse@arg@a
  }{
    \bxpi@parse@arg@c#1
  }}}
}

%% \bxpi@par@hook
\def\bxpi@par@hook{
  \bxpi@prnind@pardflt
  \bxpi@forceindfalse
  \let\bxpi@choice=p
  \let\bxpi@value\bxpi@parhead
  \let\bxpi@special\relax
  \futurelet\bxpi@tok\bxpi@par@hook@a
}
\def\bxpi@par@hook@a{
%\bxDebug{peek:\meaning\bxpi@tok}
  \bxIfx{\bxpi@tok\special}{
    \bxpi@par@hook@b
  }{%else
    \bxpi@paren@indent
  }
}
\def\bxpi@par@hook@b#1#2{
  \def\bxpi@special{#2}
\bxDebug{special:#2}
  \bxpi@paren@indent
}

%% \bxpi@paren@indent
\def\bxpi@paren@indent{
  \bxpi@dima=-\maxdimen
  \ifbxpi@forceind
    \bxGetZenkakuWidth
    \bxpi@dima=\bxResDim
    % empty boxes never warn undefhull
    \hb@xt@\bxpi@lineheadforce\bxpi@dima{}
\bxDebug{forceind:\bxpi@lineheadforce}
  \fi
  \ifbool{bxpi@prnind}{
    \futurelet\bxpi@tok\bxpi@prnindent@a
  }{%else
    \bxpi@put@special
    \ignorespaces
  }
}
\expandafter\def\expandafter\bxpi@prnindent@space\space{
  \futurelet\bxpi@tok\bxpi@prnindent@a
}
\def\bxpi@prnindent@a{
  \bxIfx{\@sptoken\bxpi@tok}{
    \bxpi@prnindent@space
  }{\bxIfCharToken\bxpi@tok{
    \bxpi@prnindent@b
  }{%else
    \bxpi@put@special
    \ignorespaces
  }}
}
\def\bxpi@prnindent@b#1{
  \bxpi@if@open@paren#1{
    \ifbxpi@diaprnind
      \if m\bxpi@choice \else
        \bxpi@if@dia@open@paren#1{
          \let\bxpi@value\bxpi@dialogue
          \if p\bxpi@choice
            {\setbox0=\lastbox}
\bxDebug{cancel parindent}
          \fi
        }
      \fi
    \fi
    \bxpi@prnindent@c
  }
  \bxpi@put@special
  #1
}
\def\bxpi@prnindent@c{
  \ifdim \bxpi@dima<\z@
    \bxGetZenkakuWidth
    \bxpi@dima=\bxResDim
  \fi
  \kern\bxpi@value\bxpi@dima
\bxDebug{parind:\bxpi@value}
  \bxpi@inhibitglue
}

%% \bxpi@put@special
\def\bxpi@put@special{
  \ifx\bxpi@special\relax\else
\bxDebug{put-special:}
    \special{\bxpi@special}
    \let\bxpi@special\relax
  \fi
}

%% \bxpi@if@open@paren
\def\bxpi@if@open@paren#1{
  \bxIfcsundef{bxpi@P/#1}
   {\@gobble}
   {\@firstofone}
}

%% \bxpi@if@dia@open@paren
\def\bxpi@if@dia@open@paren#1{
  \bxIfcsundef{bxpi@DP/#1}
   {\@gobble}
   {\@firstofone}
}

%% \bxpi@prnind@pardflt
\edef\bxpi@prnind@pardflt{
  \let\bxCsNoexpand{ifbxpi@prnind}
   \bxCsNoexpand{ifbxpi@d@parprnind}
}
%% \bxpi@prnind@linedflt
\edef\bxpi@prnind@linedflt{
  \let\bxCsNoexpand{ifbxpi@prnind}
   \bxCsNoexpand{ifbxpi@d@lineprnind}
}

%--------------------------------------- character table

%% \[bxpi@P/<char>]
\def\do#1#2{
  \bxToUcsCharDual{"#1}{"#2}
  \cslet{bxpi@P/\bxRes}{t}
}
\do{2146}{2018}
\do{2148}{201C}
\do{214A}{FF08}
\do{214C}{3014}
\do{214E}{FF3B}
\do{2150}{FF5B}
\do{2152}{3008}
\do{2154}{300A}
\do{2156}{300C}
\do{2158}{300E}
\do{215A}{3010}
\ifbxHasUcsChar
  \def\do#1{
    \bxToUcsChar{"#1}
    \cslet{bxpi@P/\bxRes}{t}
  }
\do{2985}
\do{3018}
\do{3016}
\do{00AB}
\do{301D}
\fi

%% \[bxpi@DP/<char>]
\def\do#1#2{
  \bxToUcsCharDual{"#1}{"#2}
  \cslet{bxpi@DP/\bxRes}{t}
}
\do{2156}{300C}
\do{2158}{300E}

%--------------------------------------- 'force' option
\ifbxpi@force

%% re-attach the hook at begin-document
\AfterEndPreamble{
  \let\bxpi@par@hook@again\bxpi@par@hook
  \let\bxpi@par@hook\relax
  \PushPostHook{par}{\bxpi@par@hook@again}
}

\fi
%--------------------------------------- all done
\endinput
%% EOF