4

I have need to check each paragraph ending end-period(.) is available or not. If missing need to put end-period LaTeX code \textcolor{red}{.}

As per Automatically adding space before punctuation in LuaLaTeX this code is working without know how to find endperiod with entermarks.

My MWE is:

\documentclass{article}
\usepackage{luacode}
\usepackage{etoolbox}

\usepackage{luacode}
\usepackage{etoolbox}

\newrobustcmd\dblpnct[1]{%
  \ifhmode\unskip\fi
  \nolinebreak#1%
}
\begin{luacode}
function dosub(s)
    s = string.gsub(s, '([a-z])\\par', '\\dblpnct{\\hspace{0.1em}}!')
    return(s)
end
\end{luacode}

\AtBeginDocument{%
  \luaexec{luatexbase.add_to_callback("process_input_buffer", dosub, "dosub")}%
}

\begin{document}

\title{Art Title}

\author{Kavi}

\maketitle

\section{Intro.}

This is the sample paragraph text without end period paragraph

This is the sample paragraph text with end period paragraph.

This is the Sample another paragraph text with end period paragraph. This is the sample paragraph text with end period paragraph. This is the sample paragraph text with end period paragraph. This is the sample paragraph text with end period paragraph. This is the sample paragraph text with end period paragraph.

This is the another any sample paragraph text without end period paragraph This is the another any sample paragraph text without end period paragraph This is the another any sample paragraph text without end period paragraph This is the another any sample paragraph text without end period paragraph

\begin{enumerate}
\item list-item1 without end period
\item list-item2 with end period.
\item list-item3 with end period.
\item list-item4 without end period
\end{enumerate}

\end{document}

Expected output is:

Input LaTeX:

This is the sample paragraph text without end period paragraph

Result LaTeX:

This is the sample paragraph text without end period paragraph\textcolor{red}{.}

How to do using LuaScript?

1
  • 1
    Welcome! Could you explain the purpose? A paragraph can easily end with some other punctuation mark, so whether there is anything missing or not can't be determined just by looking for a full-stop.
    – cfr
    Commented Jun 14 at 19:21

2 Answers 2

6

I will assume that the following assumptions about the input stream are valid:

  • Paragraphs -- in the TeX-specific sense of the word -- are contained in a single input line.
  • Input lines that are either empty or begin with \ (e.g., \section{Introduction} or \end{enumerate}) are not paragraphs in the TeX-specific sense of the word and should therefore not be checked further.
  • If a given given input line would otherwise start with \ but is supposed to be a paragraph after all, just insert a whitespace before the backslash character in question. E.g., instead of letting a line start with \item, let it start with \item (note the whitespace character).
  • The paragraph-ending punctuation marks aren't just . ("dot", aka "full stop") but also ? and ! (question and exclamation mark, respectively).

Please indicate if your document doesn't satisfy (or cannot be made to satisfy) these requirements.

The following solution provides a Lua function, called add_red_dot, that does all of the work by operating on the input stream at a very early stage (basically, as a pre-processor, before TeX starts its usual work). Note the use of ^ and $ in the string.find pattern matching operations to anchor the search at the start and end of the string, respectively. The solution also provides two LaTeX utility macros, called \ActivateRedDot and \DeactivateRedDot. Use \ActivateRedDot to activate the Lua function (generally, at some point after \begin{document}) and \DeactivateRedDot to suspend the operation of add_red_dot. The latter command is useful if a part of the .tex file contains verbatim material or other material (such as displayed equations) that needn't have lines that end with a punctuation mark. After the special-material part is done, you can use \ActivateRedDot to reactivate add_red_dot.

enter image description here

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{xcolor}  % for '\textcolor' macro

\directlua{
function add_red_dot ( s )
   if not ( s=="" or string.find ( s , "^\\") ) and
      not ( string.find ( s , "[.?!]$") ) then 
          s = s .. "\\textcolor{red}{\\textbf{.}}"
   end
   return ( s )
end
}

%% provide two LaTeX utility macros
\newcommand\ActivateRedDot{\directlua{%
   luatexbase.add_to_callback(
   "process_input_buffer" , add_red_dot, "addreddot" )}}    
\newcommand\DeactivateRedDot{\directlua{%
   luatexbase.remove_from_callback(
   "process_input_buffer", "addreddot")}}

%% enable the Lua function by default
\AtBeginDocument{\ActivateRedDot} 

\begin{document}  

\title{Art Title}
\author{Kavi}
\date{\today}
\maketitle

\section{Intro.}

This is a sample paragraph without end punctuation mark 

This is a sample paragraph with end punctuation mark.

This is a sample paragraph with end punctuation mark. This is a sample paragraph with end punctuation mark.

This is a sample paragraph without end punctuation mark. This is a sample paragraph without end punctuation mark

\begin{enumerate}
 \item list-item1 without end punctuation mark
 \item list-item2 with end punctuation mark?
 \item list-item3 with end punctuation mark!
 \item list-item4 without end punctuation mark
\end{enumerate}

\DeactivateRedDot  % deactivate the Lua function

\medskip
\begin{itemize}
 \item list-item1 without end punctuation mark
\end{itemize}

\end{document}

Addendum to address the OP's follow-up question: If input lines that start with \item (without leading whitespace) are supposed to be included in being treated by the add_red_dot Lua function, I suggest you employ the following variant of the Lua function:

function add_red_dot ( s )
   if ( not ( s=="" or string.find ( s , "^\\") ) 
         or string.find ( s , "^\\item") )
      and not ( string.find ( s , "[.?!]$") ) then 
         s = s .. "\\textcolor{red}{\\textbf{.}}"
   end
   return ( s )
end

The change consists in adding the condition string.find ( s , "^\\item").

4
  • Thanks for your answer. However i would like to ignore some tags like \begin{tabular} and change \item to ` \item`. It's possible?
    – Kavi
    Commented Jun 15 at 11:11
  • @Kavi - I think you shouldn't exempt just \begin{tabular} but, rather, the entire tabular environment, i.e., everything from \begin{tabular} up to and including \end{tabular}. That's best handled by executing \DeactivateRedDot immediately before \begin{tabular} and running \ActivateRedDot immediately after \end{tabular}. I'm afraid I don't quite understand what you mean by "change \item to ` \item`". Please clarify.
    – Mico
    Commented Jun 15 at 12:16
  • Very nice answer. If LaTeX file have without space before \item need to give space before single word-space ` \item`. I hope it's clear. Like find without space \item and replace with space \item.
    – Kavi
    Commented Jun 15 at 13:08
  • @Kavi - Please see the addendum I just posted.
    – Mico
    Commented Jun 15 at 13:17
6

Maybe you can combine para/end hook with lua code to read the character preceding a command.

Define a command to check if the preceding character is a punctuation

\NewDocumentCommand{\checkpunct}{}
  {%
    \directlua%
      {
        local n=tex.nest[tex.nest.ptr].tail
        if ( n.id == 29 and n.char ~= 33 and n.char ~= 46 and n.char ~= 63 ) % 33 = ! / 46 = . / 63 = ?
        then
            tex.print("\\missingpunct{}")
        end
      }%
  }

n.id is 29 for glyphs and n.char correspond to the ASCII code (so 33 means !, 46 means .and 63 means ?). The macro \missingunct mark the missing punctuation

\newcommand*{\missingpunct}{\textcolor{red}{.}}

Then add the command to the para/end hook

\AddToHook{para/end}{\checkpunct{}}

This works, but also adds end periods after title and headings. So it it would be better do define a dedicated environment

\NewDocumentEnvironment{checkpunctuation}{ }
    { \AddToHook{para/end}[checkpunctuation]{\checkpunct{}} }
    { \RemoveFromHook{para/end}[checkpunctuation] }

Example:

\documentclass{article}

\usepackage{xcolor}

\newcommand*{\missingpunct}{\textcolor{red}{.}}

\NewDocumentCommand{\checkpunct}{}
  {%
    \directlua%
      {
        local n=tex.nest[tex.nest.ptr].tail
        if ( n.id == 29 and n.char ~= 33 and n.char ~= 46 and n.char ~= 63 ) % 33 = ! / 46 = . / 63 = ?
        then
            tex.print("\\missingpunct{}")
        end
      }%
  }

\NewDocumentEnvironment{checkpunctuation}{ }
    { \AddToHook{para/end}[checkpunctuation]{\checkpunct{}} }
    { \RemoveFromHook{para/end}[checkpunctuation] }

\begin{document}

\title{Art Title}

\author{Kavi}

\maketitle

\section{Intro.}

\begin{checkpunctuation}

This is the sample paragraph text without end period paragraph

This is the sample paragraph text with end period paragraph.

This is the Sample another paragraph text with end period paragraph. This is the sample paragraph text with end period paragraph. This is the sample paragraph text with end period paragraph. This is the sample paragraph text with end period paragraph. This is the sample paragraph text with end period paragraph.

This is the another any sample paragraph text without end period paragraph This is the another any sample paragraph text without end period paragraph This is the another any sample paragraph text without end period paragraph This is the another any sample paragraph text without end period paragraph

\begin{enumerate}
\item list-item1 without end period
\item list-item2 with end period.
\item list-item3 with end period.
\item list-item4 without end period
\end{enumerate}

\end{checkpunctuation}

\end{document}

Example

3
  • Nice, why are you using tex.nest?
    – yannisl
    Commented Jun 15 at 4:46
  • @yannisl I don't really master luatex. I took if from tex.stackexchange.com/a/575465/316068.
    – jlab
    Commented Jun 15 at 7:38
  • 1
    Thanks, I will check it in the manual and David's example you linked is cler.
    – yannisl
    Commented Jun 15 at 8:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .