%D \module
%D   [       file=typo-del, % moved from core-mis,
%D        version=20110112,
%D          title=\CONTEXT\ Typesetting Macros,
%D       subtitle=Delimited Content,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{ConTeXt Typesetting Macros / Delimited Content}

\unprotect

% THIS IS OBSOLETE:

\installcorenamespace{hyphenmarksign} % let's not waste a setuphandler (yet)

\unexpanded\def\setuphyphenmark[#1]% sign=normal|wide
  {\getdummyparameters[#1]%
   \expandnamespaceparameter\??hyphenmarksign\dummyparameter\c!sign\v!normal}

\setvalue{\??hyphenmarksign\v!normal}%
  {\let\textmodehyphen\normalhyphen
   \let\textmodehyphendiscretionary\normalhyphendiscretionary}

\setvalue{\??hyphenmarksign\v!wide}%
  {\let\textmodehyphen\composedhyphen
   \let\textmodehyphendiscretionary\composedhyphendiscretionary}

\setuphyphenmark[\c!sign=\v!wide]

\definesymbol[\c!lefthyphen]  [\languageparameter\c!lefthyphen]
\definesymbol[\c!righthyphen] [\languageparameter\c!righthyphen]
\definesymbol[\c!hyphen]      [\languageparameter\c!hyphen]

\unexpanded\def\normalhyphen
  {\hbox{\directsymbol\empty\c!hyphen}}

\unexpanded\def\composedhyphen
  {\hbox{\directsymbol\empty\c!compoundhyphen}}

\unexpanded\def\normalhyphendiscretionary
  {\discretionary
     {\hbox{\directsymbol\empty\c!righthyphen}}
     {\hbox{\directsymbol\empty\c!lefthyphen}}
     {\hbox{\directsymbol\empty\c!hyphen}}}

\unexpanded\def\composedhyphendiscretionary
  {\discretionary
     {\hbox{\directsymbol\empty\c!rightcompoundhyphen}}
     {\hbox{\directsymbol\empty\c!leftcompoundhyphen}}
     {\hbox{\directsymbol\empty\c!compoundhyphen}}}

\let\textmodehyphen             \composedhyphen
\let\textmodehyphendiscretionary\composedhyphendiscretionary

\definesymbol[\c!leftcompoundhyphen]  [\languageparameter\c!leftcompoundhyphen]
\definesymbol[\c!rightcompoundhyphen] [\languageparameter\c!rightcompoundhyphen]
\definesymbol[\c!compoundhyphen]      [\languageparameter\c!compoundhyphen]

% TILL HERE

\setnewconstant\boundarycharactermode\plusone

\unexpanded\def\midboundarycharacter#1#2%
  {\ifcase\boundarycharactermode
   \or
     %\nobreak
     \hskip\hspaceamount\currentlanguage{#2}%
     \languageparameter#1%
     %\nobreak
      \hskip\hspaceamount\currentlanguage{#2}%
   \or
     \languageparameter#1%
   \fi
   \boundarycharactermode\plusone}

\unexpanded\def\leftboundarycharacter#1#2%
  {\ifcase\boundarycharactermode
   \or
     \languageparameter#1%
     \nobreak
     \hskip\hspaceamount\currentlanguage{#2}%
   \or
     \languageparameter#1%
   \fi
   \boundarycharactermode\plusone}

\unexpanded\def\rightboundarycharacter#1#2%
  {\ifcase\boundarycharactermode
   \or
     \prewordbreak %\nobreak
     \hskip\hspaceamount\currentlanguage{#2}%
     \languageparameter#1%
   \or
     \languageparameter#1%
   \fi
   \boundarycharactermode\plusone}

\definehspace [sentence]      [\zeropoint]
\definehspace [intersentence] [.250\emwidth]

\definesymbol
  [\c!midsentence]
  [\midboundarycharacter\c!midsentence{sentence}]

\definesymbol
  [\c!leftsentence]
  [\leftboundarycharacter\c!leftsentence{sentence}]

\definesymbol
  [\c!rightsentence]
  [\rightboundarycharacter\c!rightsentence{sentence}]

\definesymbol
  [\c!leftsubsentence]
  [\leftboundarycharacter\c!leftsubsentence{sentence}]

\definesymbol
  [\c!rightsubsentence]
  [\rightboundarycharacter\c!rightsubsentence{sentence}]

\newsignal \d_typo_subsentence_signal
\newcount  \c_typo_subsentence_nesting

\let\beforesubsentence\donothing
\let\aftersubsentence \donothing

% todo: make this language option
%
% \def\beforesubsentence{\removeunwantedspaces}
% \def\aftersubsentence {\ignorespaces}

\unexpanded\def\midsentence
  {\symbol[\c!midsentence]}

\unexpanded\def\beginofsubsentence
  {\beforesubsentence
   \ifdim\lastkern=\d_typo_subsentence_signal
     \unskip
     \kern\hspaceamount\currentlanguage{intersentence}%
   \fi
   \global\advance\c_typo_subsentence_nesting\plusone
   \ifnum\c_typo_subsentence_nesting=\plusone
     \dontleavehmode % was \leaveoutervmode
   \fi
   \dostarttagged\t!subsentence\empty
   \symbol[\ifodd\c_typo_subsentence_nesting\c!leftsentence\else\c!leftsubsentence\fi]%
  }%  \ignorespaces}

\unexpanded\def\endofsubsentence % relax prevents space gobbling
  {\symbol[\ifodd\c_typo_subsentence_nesting\c!rightsentence\else\c!rightsubsentence\fi]%
   \dostoptagged
   \global\advance\c_typo_subsentence_nesting\minusone
   \unskip
   \kern\d_typo_subsentence_signal\relax
   \aftersubsentence}

\unexpanded\def\beginofsubsentencespacing % relax prevents space gobbling
  {\kern\d_typo_subsentence_signal\relax}% \ignorespaces}

\unexpanded\def\endofsubsentencespacing
  {\ifdim\lastkern=\d_typo_subsentence_signal
     \unskip
     \hskip\hspaceamount\currentlanguage{intersentence}%
     % no good, actually language dependent:
%     \ignorespaces
   \else
     \unskip
   \fi}

%D \startbuffer
%D test |<|test |<|test|>| test|>| test \par
%D test|<|test|<|test|>|test|>|test \par
%D test |<||<|test|>||>| test \par
%D test \directdiscretionary{<}test\directdiscretionary{>} test \par
%D \stopbuffer
%D
%D \typebuffer
%D \getbuffer

\unexpanded\def\startsubsentence{\beginofsubsentence     \prewordbreak\beginofsubsentencespacing}
\unexpanded\def\stopsubsentence {\endofsubsentencespacing\prewordbreak\endofsubsentence}
\unexpanded\def\subsentence     {\groupedcommand\startsubsentence\stopsubsentence}

\definehspace [quotation]      [\zeropoint]
\definehspace [interquotation] [.125em]

%definehspace [quote]  [\zeropoint]
%definehspace [speech] [\zeropoint]

\definehspace [quote]  [\hspaceamount\currentlanguage{quotation}]
\definehspace [speech] [\hspaceamount\currentlanguage{quotation}]

\definesymbol
  [\c!leftquotation]
  [\leftboundarycharacter\c!leftquotation{quotation}]

\definesymbol
  [\c!rightquotation]
  [\rightboundarycharacter\c!rightquotation{quotation}]

\definesymbol
  [\c!leftquote]
  [\leftboundarycharacter\c!leftquote{quote}]

\definesymbol
  [\c!rightquote]
  [\rightboundarycharacter\c!rightquote{quote}]

\definesymbol
  [\c!leftspeech]
  [\leftboundarycharacter\c!leftspeech{speech}]

\definesymbol
  [\c!rightspeech]
  [\rightboundarycharacter\c!rightspeech{speech}]

\definesymbol
  [\c!middlespeech]
  [\leftboundarycharacter\c!middlespeech{speech}]

\appendtoks
    \def\quotation#1{"#1"}%
    \def\quote    #1{'#1'}%
\to \everysimplifycommands

%D The next features was so desperately needed by Giuseppe
%D Bilotta that he made a module for it. Since this is a
%D typical example of core functionality, I decided to extend
%D the low level quotation macros in such a way that a speech
%D feature could be build on top of it. The speech opening and
%D closing symbols are defined per language. Italian is an
%D example of a language that has them set.

\newsignal\d_typo_delimited_signal

\let\currentdelimitedtext\s!unknown

\let\delimitedtextlevel\!!zerocount

\def\c_typo_delimited_nesting{\csname\??delimitedtextlevel\currentparentdelimitedtext\endcsname}

\def\typo_delimited_push#1%
  {\globalpushmacro\currentdelimitedtext
   \def\currentdelimitedtext{#1}%
   \let\currentparentdelimitedtext\currentdelimitedtext
   \global\advance\c_typo_delimited_nesting\plusone
   \edef\delimitedtextlevel{\number\c_typo_delimited_nesting}%
   \normalexpanded{\chaintocurrentdelimitedtext{\currentparentdelimitedtext:\delimitedtextlevel}}%
   \edef\currentdelimitedtext{\currentparentdelimitedtext:\delimitedtextlevel}}

\def\typo_delimited_pop
  {\global\advance\c_typo_delimited_nesting\minusone
   \globalpopmacro\currentdelimitedtext}

\installcorenamespace{delimitedtext}
\installcorenamespace{delimitedtextlevel}

\installcommandhandler \??delimitedtext {delimitedtext} \??delimitedtext

\appendtoks
    \expandafter\newcount\csname\??delimitedtextlevel\currentdelimitedtext\endcsname
    \setuevalue{\currentdelimitedtext        }{\delimitedtext[\currentdelimitedtext]}%
    \setuevalue{\e!start\currentdelimitedtext}{\startdelimitedtext[\currentdelimitedtext]}%
    \setuevalue{\e!stop \currentdelimitedtext}{\stopdelimitedtext}%
\to \everydefinedelimitedtext

\setupdelimitedtext
  [\c!location=\v!margin, % \v!text \v!paragraph
   \c!spacebefore=,
   \c!spaceafter=\delimitedtextparameter\c!spacebefore,
   \c!style=\v!normal,
   \c!color=,
   \c!leftmargin=\zeropoint,
   \c!rightmargin=\delimitedtextparameter\c!leftmargin,
   \c!indentnext=\v!yes,
   \c!before=,
   \c!after=,
   \c!left=,
   \c!right=,
  %\c!level=0,
   \c!method=,
   \c!repeat=\v!no]

\def\typo_delimited_repeat_ideed
  {\relax\ifcase\delimitedtextlevel\else
     \typo_delimited_handle_middle\c!middle
   \fi}

\let\typo_delimited_repeat\relax

\unexpanded\def\startdelimitedtext[#1]%
  {\begingroup
   \typo_delimited_push{#1}%
   \dostarttagged\t!delimitedblock\currentdelimitedtext
   \edef\p_method{\delimitedtextparameter\c!method}%
   \ifx\p_method\s!font
     \expandafter\typo_delimited_start_font
   \else
     \expandafter\typo_delimited_start_other
   \fi}

\let\typo_delimited_stop\relax % hooks into \everypar

\def\typo_delimited_start_font
  {\let\typo_delimited_stop\typo_delimitedtexts_finish_font
   \delimitedtextparameter\c!left
   \ignorespaces}

\def\typo_delimited_start_other
  {\edef\p_repeat{\delimitedtextparameter\c!repeat}%
   \ifx\p_repeat\v!yes
     \let\typo_delimited_repeat\typo_delimited_repeat_ideed
   \else
     \let\typo_delimited_repeat\relax
   \fi
   \edef\p_location{\delimitedtextparameter\c!location}%
   \ifx\p_location\v!paragraph
     \singleexpandafter\typo_delimited_start_par
   \else\ifx\p_location\v!margin
     \doubleexpandafter\typo_delimited_start_par
   \else
     \doubleexpandafter\typo_delimited_start_txt
   \fi\fi}

\def\typo_delimitedtexts_finish_font
  {\removeunwantedspaces\delimitedtextparameter\c!right}

\def\typo_delimited_start_par
  {\dosingleempty\typo_delimited_start_par_indeed}

\def\typo_delimited_start_par_indeed[#1]%
  {\let\typo_delimited_stop\typo_delimited_stop_par
   \doifsomething{\delimitedtextparameter\c!spacebefore}
     {\blank[\delimitedtextparameter\c!spacebefore]}%
   \delimitedtextparameter\c!before
   \edef\m_typo_delimited_narrower{#1}%
   \ifx\m_typo_delimited_narrower\empty
     \endgraf
     \doadaptleftskip {\delimitedtextparameter\c!leftmargin}%
     \doadaptrightskip{\delimitedtextparameter\c!rightmargin}%
     \let\typo_delimited_stop_par_indeed\endgraf
   \else % backward compatible direct directive
     \startnarrower[#1]%
     \let\typo_delimited_stop_par_indeed\stopnarrower
   \fi
   % so far
   \pushmacro\checkindentation
   \doifsomething{\delimitedtextparameter\c!indenting} % WS
     {\setupindenting[\delimitedtextparameter\c!indenting]}%
   \begingroup
   \usedelimitedtextstyleandcolor\c!style\c!color
   \leftdelimitedtextmark
   \ignorespaces}

\def\typo_delimited_stop_par
  {\removeunwantedspaces
   \removelastskip
   \rightdelimitedtextmark
   \carryoverpar\endgroup % new per 2013-01-21 ... please left floats
   \popmacro\checkindentation
   \typo_delimited_stop_par_indeed
   \delimitedtextparameter\c!after
   \doifsomething{\delimitedtextparameter\c!spaceafter}
     {\blank[\delimitedtextparameter\c!spaceafter]}%
   \useindentnextparameter\delimitedtextparameter
   \dorechecknextindentation}% AM: This was missing!

\def\typo_delimited_start_txt
  {\let\typo_delimited_stop\typo_delimited_stop_txt
   \begingroup
   \usedelimitedtextstyleandcolor\c!style\c!color
   \typo_delimited_handle_left\c!left
   \ignorespaces}

\def\typo_delimited_stop_txt
  {\removeunwantedspaces
   \typo_delimited_handle_right\c!right
   \endgroup}

\unexpanded\def\stopdelimitedtext
  {\typo_delimited_stop
   \dostoptagged
   \typo_delimited_pop
   \endgroup}

\unexpanded\def\delimitedtext[#1]%
  {\dontleavehmode % following ones can be omited
   \typo_delimited_push{#1}%
   \edef\p_method{\delimitedtextparameter\c!method}%
   \ifx\p_method\s!font
     \expandafter\typo_delimited_fontdriven
   \else
     \expandafter\typo_delimited_other
   \fi}

\def\typo_delimited_other
  {\edef\p_location{\delimitedtextparameter\c!location}%
   \ifx\p_location\v!paragraph
     \singleexpandafter\typo_delimited_par
   \else\ifx\p_location\v!margin
     \doubleexpandafter\typo_delimited_par
   \else
     \doubleexpandafter\typo_delimited_txt
   \fi\fi}

% shortcuts

\unexpanded\def\startdelimited{\startdelimitedtext}
\unexpanded\def\stopdelimited {\stopdelimitedtext}  % no let, dynamically assigned
           \def\delimited     {\delimitedtext}

\unexpanded\def\leftdelimitedtextmark
  {\doifsomething{\delimitedtextparameter\c!left}
     {\setbox\scratchbox\hbox{\delimitedtextparameter\c!left}%
      \dontleavehmode
      \doif{\delimitedtextparameter\c!location}\v!margin{\hskip-\wd\scratchbox}%
      \box\scratchbox}}

\unexpanded\def\rightdelimitedtextmark
  {\doifsomething{\delimitedtextparameter\c!right}
     {\hsmash{\delimitedtextparameter\c!right}}}

% \starttext
%    \hyphenatedword{groepsvrijstellingsverordeningen}\par
%    \hyphenatedword{\quote{groepsvrijstellingsverordeningen}}\par
%     \dorecurse{100}{\hskip300pt\hskip\recurselevel pt test \quote{xxx xxxx}.\par}
%     \page \setuppapersize[A5][A4]
%     \quotation {overly beautiful pusillanimous sesquipedalian
%     longwinded} test test test test test test test test test test test
%     test test test test test test test test test test test test test
%     test test test test test test test test test test test test test
%     test test test test test test test test test test test test test
%     test test test
% \stoptext

\def\typo_delimited_handle_middle#1%
  {\begingroup
   \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
   \ifdim\wd\scratchbox>\zeropoint
     \ifdim\lastkern=\d_typo_delimited_signal
       \unkern
       \hskip\hspaceamount\currentlanguage{interquotation}%
     \fi
     \ifhmode % else funny pagebeaks
       \penalty\plustenthousand
       \hskip\zeropoint % == \prewordbreak
     \fi
     \strut % new, needed below
     \delimitedtextparameter#1% unhbox\scratchbox
   % \penalty\plustenthousand % else overfull boxes, but that's better than dangling periods
     \kern\d_typo_delimited_signal % +- \prewordbreak
   \fi
   \endgroup}

\def\typo_delimited_handle_left#1%
  {\begingroup
   \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
   \ifdim\wd\scratchbox>\zeropoint
     \ifdim\lastkern=\d_typo_delimited_signal
       \unkern
       \hskip\hspaceamount\currentlanguage{interquotation}%
     \else\ifdim\lastskip=\d_typo_delimited_signal
       \unskip
       \hskip\hspaceamount\currentlanguage{interquotation}%
     \fi\fi
     \strut % new, needed below
     \ifhmode % else funny pagebeaks
       \penalty\plustenthousand
       \hskip\zeropoint % == \prewordbreak
     \fi
     \strut % new, needed below
     \delimitedtextparameter#1% unhbox\scratchbox
     \penalty\plustenthousand % new per 2013-03-09 WS mailing list
     \hskip\d_typo_delimited_signal % +- \prewordbreak
   \fi
   \endgroup}

\def\typo_delimited_handle_right#1%
  {\begingroup
   \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
   \ifdim\wd\scratchbox>\zeropoint
     \ifdim\lastkern=\d_typo_delimited_signal
       \unkern
       \penalty\plustenthousand
       \hskip\hspaceamount\currentlanguage{interquotation}%
     \else\ifdim\lastskip=\d_typo_delimited_signal
       \unskip
       \penalty\plustenthousand
       \hskip\hspaceamount\currentlanguage{interquotation}%
     \fi\fi
     \ifhmode % else funny pagebeaks
       \penalty\plustenthousand
       \hskip\zeropoint % == \prewordbreak
     \fi
     \strut % new, needed below
     \delimitedtextparameter#1% unhbox\scratchbox
     \kern\d_typo_delimited_signal % +- \prewordbreak
   \fi
   \endgroup}

\unexpanded\def\typo_delimited_par
  {\groupedcommand
     {\dostarttagged\t!delimited\currentdelimitedtext % block?
      \typo_delimited_handle_left\c!left}
     {\typo_delimited_handle_right\c!right
      \removelastskip
      \dostoptagged
      \typo_delimited_pop}}

\unexpanded\def\typo_delimited_txt
  {\doifelse{\delimitedtextparameter\c!style}\v!normal
     \typo_delimited_quoted
     \typo_delimited_attributed}

\def\typo_delimited_quoted_b
  {\dostarttagged\t!delimited\currentdelimitedtext
   \typo_delimited_handle_left\c!left}

\def\typo_delimited_quoted_e
  {\typo_delimited_handle_right\c!right
   \removelastskip
   \dostoptagged
   \typo_delimited_pop}

\def\typo_delimited_attributed_b
  {\dostarttagged\t!delimited\currentdelimitedtext
   \usedelimitedtextstyleandcolor\c!style\c!color}

\def\typo_delimited_attributed_e
  {\dostoptagged
   \typo_delimited_pop}

\def\typo_delimited_fontdriven_b
  {\dostarttagged\t!delimited\currentdelimitedtext
   \languageparameter{\c!left\currentparentdelimitedtext}}% was: \currentdelimitedtext

\def\typo_delimited_fontdriven_e
  {\languageparameter{\c!right\currentparentdelimitedtext}% was: \currentdelimitedtext
   \dostoptagged
   \typo_delimited_pop}

% We now assume proper argument usage (so no longer grouped
% command).

% \def\typo_delimited_quoted    {\groupedcommand      \typo_delimited_quoted_b    \typo_delimited_quoted_e    }
% \def\typo_delimited_attributed{\groupedcommand      \typo_delimited_attributed_b\typo_delimited_attributed_e}
% \def\typo_delimited_fontdriven{\simplegroupedcommand\typo_delimited_fontdriven_b\typo_delimited_fontdriven_e}

\def\typo_delimited_quoted    {\bgroup\typo_delimited_quoted_b    \aftergroup\typo_delimited_quoted_e    \let\next=}
\def\typo_delimited_attributed{\bgroup\typo_delimited_attributed_b\aftergroup\typo_delimited_attributed_e\let\next=}
\def\typo_delimited_fontdriven{\bgroup\typo_delimited_fontdriven_b\aftergroup\typo_delimited_fontdriven_e\let\next=}

% testcase for nesting:
%
% \quotation{... \quotation{...} ...}
% \startquotation ... \startquotation... \quotation{...} \stopquotation\space ...\stopquotation
% \setupdelimitedtext[quotation][1][left=(,right=)]
% \setupdelimitedtext[quotation][2][left={[},right={]}]
% \setupdelimitedtext[quotation][3][left=\{,right=\}]
% \quotation{... \quotation{...} ...}
% \startquotation ... \startquotation... \quotation{...} \stopquotation\space ...\stopquotation

\definedelimitedtext
  [\v!quotation]
  [\c!left={\symbol[\c!leftquotation]},
   \c!right={\symbol[\c!rightquotation]},
   \c!leftmargin=\v!standard]

\definedelimitedtext
  [\v!quote][\v!quotation]

\setupdelimitedtext
  [\v!quote]
  [\c!location=\v!text,
   \c!left={\symbol[\c!leftquote]},
   \c!right={\symbol[\c!rightquote]}]

\definedelimitedtext
   [\v!blockquote][\v!quotation]

\setupdelimitedtext
  [\v!blockquote]
  [\c!left=,
   \c!right=]

\definedelimitedtext
  [\v!speech][\v!quotation]

\setupdelimitedtext
  [\v!speech]
  [\c!repeat=\v!yes,
   \c!left={\symbol[\c!leftspeech]},
   \c!middle={\symbol[\c!middlespeech]},
   \c!right={\symbol[\c!rightspeech]}]

% how do we call an tight quote
%
% \definedelimitedtext
%    [\v!quotation][\v!quotation]
%
% \setupdelimitedtext
%   [\v!quotation]
%   [\c!indentnext=\v!no,
%    \c!spacebefore=\v!nowhite]

\unexpanded\def\setupquotation{\setupdelimitedtext[\v!quotation]}
\unexpanded\def\setupquote    {\setupdelimitedtext[\v!quote]}

\protect \endinput
