% \iffalse meta-comment
%
% Copyright (C) 2026 by Hugo Heagren <hugo@heagren.com>
% ---------------------------------------------------------------------------
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% 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.3c or later is part of all distributions of LaTeX
% version 2008-05-04 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Hugo Heagren.
%
% This work consists of the files countwords.dtx and countwords.ins
% and the derived filebase countwords.sty.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{countwords.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{countwords}
%<*package>
    [2026/04/03 1.0 Exact word counts]
%</package>
%
%<*driver>
\documentclass{ltxdoc}

\usepackage[T1]{fontenc}
\usepackage{listings}

\lstset{
  basicstyle=\MacroFont,
  keepspaces=true,
  numbers=left,
  xleftmargin=5.0ex,
  numberstyle=\scriptsize,
}

\usepackage{hyperref}

\usepackage[date=year]{biblatex}
\addbibresource{./references.bib}

\EnableCrossrefs
\CodelineNumbered
\RecordChanges
\begin{document}
  \DocInput{countwords.dtx}
  \PrintChanges
  \PrintIndex
\end{document}
%</driver>
% \fi
%
% \CheckSum{17}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{<+version+>}{<+date+>}{Converted to DTX file}
%
% \DoNotIndex{\newcommand,\newenvironment}
%
% \GetFileInfo{countwords.dtx}
% \title{The \textsf{countwords} package}

% \author{Hugo Heagren\thanks{The bulk of the actual code is in lua
% and was written by Philipp Gesang \cite{gesang12_wordcount}.} \\
% \texttt{\href{mailto:hugo@heagren.com}{hugo@heagren.com}}}

% \date{\fileversion~from \filedate}
%
% \maketitle
%
% \section{Introduction}
%
% This is a simple package for generating \emph{exact} wordcounts in
% \LaTeX{} projects. It counts words, storing the value in a standard
% \LaTeX{} counter, which can then be printed in the normal way. Word
% counting can be paused and resumed, so you can skip certain
% environments like mathematics, and multiple word counts can happen
% in parallel (you could keep separate global and per-chapter counts,
% for example).
%
% A note on \textsf{TeXcount} \cite{rødland_texcount}.
% \textsf{TeXcount} is a popular way of counting words in \LaTeX{}
% projects. It is an external script, which is run \emph{on} the
% \LaTeX{} file, and produces an estimate of the number of words in
% the final document. You can't use \textsf{TeXcount} to print a
% wordcount for a document within that very document.\footnote{Well
% you \emph{can} with some jiggerypokery, but it isn't pretty, and
% this isn't what \textsf{TeXcount} was designed to do.}
% \textsf{countwords} is a \LaTeX{} package which works \emph{within}
% the document. \textsf{countwords} also prints \emph{exact} word
% counts, because it counts the number of printed characters in the
% final document as they are rendered; \textsf{TeXcount} prints a
% reasonable estimate.
% 
% \section{Usage}
% 
% \textsf{countwords} requires Lua\LaTeX. Load as usual:
%
% \lstinputlisting{./countwords-load-example.tex}
%
% The package has one option, \texttt{threshold}, set with
% \texttt{threshold=\(\langle{}number\rangle\)} This is the minimum number of
% characters that a string must contain to count as a single word. So
% setting it to 1 means that `I' and `a' count as words (as well as
% anything longer); setting it to 3 means that `and' counts as a word,
% but not `I', `a' or `as'. If unspecified it defaults to 1 (which is
% usually the most sensible for prose writing).
%
% \textsf{countwords} stores all wordcounts in standard \LaTeX
% counters, and does not create or manage these itself. So you must
% create a counter to store the wordcount in:
% 
% \lstinputlisting[firstnumber=last]{./countwords-counter-example.tex}
% 
% \DescribeMacro{\countwordsstart\{\(\langle{}counter\rangle{}\)\}}
% Issue this command to start counting words into
% \(\langle{}counter\rangle{}\). After this, whenever \LaTeX{} encounters a string
% of consecutive characters of longer than or equal to the threshold,
% the \(\langle{}counter\rangle{}\) will increment by one.
%
% \DescribeMacro{\countwordsstop\{\(\langle{}counter\rangle{}\)\}}
% Issue this command to stop counting words in
% \(\langle{}counter\rangle{}\). After this, \textsf{countwords} will not alter the
% value of \(\langle{}counter\rangle{}\).
% 
% \section{Examples}
% \subsection{Simple example}
% \lstinputlisting{./countwords-simple-example.tex}
%
% \subsection{Printing count at the beginning}
% 
% The \textsf{totcount} package \cite{koutavas_totcount} can be used
% to print the eventual total of a counter before that total is
% reached.
% 
% \lstinputlisting{./countwords-totcount-example.tex}
% 
% \subsection{Skipping maths}
%
% By starting and stopping the wordcount, things like display
% mathematics can be skipped. Similar techniques could automatically
% skip footnotes or citations.
% \lstinputlisting{./countwords-maths-example.tex}
% 
% \StopEventually{}
%
% \section{Implementation}
% \iffalse
%<*package>
% \fi
% 
%    \begin{macrocode}
\RequirePackage{luatexbase}
\RequirePackage{luapackageloader}
%    \end{macrocode}
% \subsection{Lua}
%    \begin{macrocode}
\directlua{countwords = require("countwords")}
%    \end{macrocode}
% \subsection{Options}
%
%    \begin{macrocode}
\DeclareKeys
{
  threshold.code = \directlua{ countwords.set_threshold(\number#1) },
}
\SetKeys{threshold=1}
\DeclareUnknownKeyHandler{\PackageWarning{countwords}{Unknown option `#1'}}
\ProcessKeyOptions
%    \end{macrocode}
% \subsection{Add callback}
%    \begin{macrocode}
\directlua{
  luatexbase.add_to_callback(
  "pre_linebreak_filter",
  countwords.callback,
  "wordcount"
  )
}%
%    \end{macrocode}
% \subsection{Document commands}
%
%
% \begin{macro}{\countwordsstart}
%    \begin{macrocode}
\def\countwordsstart#1{%
  \directlua{ countwords.enable_counter("#1") }
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\countwordsstop}
%    \begin{macrocode}
\def\countwordsstop#1{%
  \directlua{ countwords.disable_counter("#1") }
}
%    \end{macrocode}
% \end{macro}
%

%
% \printbibliography
% 
% \iffalse
%</package>
% \fi
%
% \Finale
\endinput

% \endinput
% Local Variables:
% mode: docTeX
% TeX-master: t
% End:
