# Ignoring all but certain text

I'm wondering if there's a way to define a command so that, when a flag is specified, I can ignore everything but text within the tag. For instance, if I had

...
This is a \dontignore{bird}.


I would want the output to be either "This is a bird." or "bird" depending on whether or not I switch this flag.

Is this doable? Obviously surrounding everything but the text I want in some tag would be easy, but that seems quite inelegant.

Edit: Here's exactly what I have in mind:

\documentclass{article}
\newcommand{\dontignore}[1]{...}
\begin{document}
Hello world.  This is my full document with a lot of extra bells and whistles and lines.  But in the end, \dontignore{this is all that matters}.
\end{document}


With the flag off, the output should be

Hello world. This is my full document with a lot of extra bells and whistles and lines. But in the end, this is all that matters.

Otherwise,

this is all that matters

Optimally, I would also be able to tell LaTeX not to ignore things like section and enumerate/itemize/item commands as well, as follows

\documentclass{article}
\newcommand{\dontignore}[1]{...}
\begin{document}
\section{First part}
Hello world.  This is my full document with a lot of extra bells and whistles and lines.  But in the end, \dontignore{this is all that matters}.
\begin{enumerate}
\item \dontignore{Item 1}
\item Something like \dontignore{Item 2}
\end{enumerate}
\end{document}


to produce either everything (eg, with dontignore defined as \newcommand{\dontignore}[1]{#1}) or otherwise (with some flag specifying section, enumerate, etc.) as follows

# 1 First part

this is all that matters

1. Item 1
2. Item 2
-
So you want to get rid of This is a part depending on the context? –  percusse Jan 23 at 20:34
Welcome to TeX.sx! How should (La)TeX determine where the to-be-ignored part ends? What about ... before the line and . at the end? What is with text following that line? Do you want to ignore the whole document environment except for the \dontignore parts? Can you provide a full minimal working example (MWE)? –  Qrrbrbirlbel Jan 23 at 20:50
Are you looking for something like: \mycmd{This is a \dontignore{bird}} Or do you want the entire document to disappear outside of the \dontignore{} tags? –  Scott H. Jan 23 at 21:05
I added my MWE. As percusse said, I initially wanted to get rid of the This is a, but optimally I would like to be able to compile and tell the compiler to ignore all text outside of specific commands or environments. –  vmkrish Jan 23 at 21:16

In the following you get one or the other output shown above depending on whether this line is commented out or not

%\let\ignoreflag\relax


\documentclass{article}

\long\def\dontignore#1{#1}
\makeatletter

\long\def\ignoreflag{%
\@makeother\{%
\@makeother\}%
\xignore}
\long\def\xignore#1\dontignore#2{%
\catcode\{\@ne
\catcode\}\tw@
\afterassignment\xxdontignore\toks@\bgroup}
\long\def\xxdontignore{%
\the\toks@\ignoreflag}
\makeatother

%\let\ignoreflag\relax
\begin{document}
\ignoreflag

This is some text

\begin{itemize}
\item aaa
\item bbb
\item ccc \dontignore{hello }
\end{itemize}

more text
\dontignore{
\begin{enumerate}
\item this
\item that
\end{enumerate}
}

more stuff

\dontignore{\end{document}}

-
Thanks, this looks perfect, although I can't say that I understand anything that you wrote. Do you know of any resources that might help me understand it? –  vmkrish Jan 23 at 22:20
texbook or (free) tex by topic or this site (search for delimited macros) –  David Carlisle Jan 23 at 22:42

Here is a LuaTeX based solution (in ConTeXt)

• I assume that the content is surrounding in an environment \startignore ... \stopignore.

• Ignoring is enabled or disabled using a mode (and, therefore, can be controlled via the command line)

• The gobbling of everything not inside \dontignore{...} tags is done in Lua using an lpeg parser that captures the contents \dontignore. The parser handles nested {...} correctly.

I don't know the LuaLaTeX equivalent of ConTeXt buffers, so I am not sure how to translate this to LuaLaTeX.

\let\dontignore\firstofoneargument

\startluacode
local lpegmatch, patterns = lpeg.match, lpeg.patterns
local P, V, Cs, C = lpeg.P, lpeg.V, lpeg.Cs, lpeg.C
local format = string.format

local backslash    = P("\\")
local csname       = backslash * P("dontignore")
local whitespace   = lpeg.patterns.whitespace
local leftbrace    = P("{")
local rightbrace   = P("}")
local nonbrace     = 1 - leftbrace - rightbrace
local nested       = P { leftbrace * (nonbrace + V(1))^0 * rightbrace }
-- I am not sure if it makes sense to add spaces around the captured text or
-- not. Below I assume that you want spaces around the next. If not, then
-- you can just use
--      local value        = P(csname * whitespace^0 * leftbrace * C((nested + nonbrace)^0) * rightbrace) / context
local value        = P(csname * whitespace^0 * leftbrace * C((nested + nonbrace)^0) * rightbrace) / (function(s) context(" %s ", s) end)
local nonvalue     = (1 - value)
local parser       = ( (nonvalue^0 * value * nonvalue^0)^0 )

thirddata = thirddata or {}

local getcontent = buffers.getcontent

-- Function that ignores all the data except that in \dontignore
thirddata.ignoredata = function (name)
lpegmatch(parser, getcontent(name))
end
\stopluacode

\unexpanded\def\startignoring
{\grabbufferdata[ignorebuffer][startignoring][stopignoring]}

\unexpanded\def\stopignoring
{\doifmodeelse{ignore}
{\ctxlua{thirddata.ignoredata('ignorebuffer')}}
{\getbuffer[ignorebuffer]}}


This can be used as follows

\starttext

\enablemode[ignore]

\startignoring
\startitemize[n]
\item This is \dontignore{item 1}
\item And this is \dontignore{item 2}
\stopitemize
\stopignoring

\disablemode[ignore]

\startignoring
\startitemize[n]
\item This is \dontignore{item 1}
\item And this is \dontignore{item 2}
\stopitemize
\stopignoring

\stoptext


which gives

The advantage of parsing content in Lua is that the anything outside \dontignore does not need to be valid TeX code. Therefore, even something like

\startignoring
\undefined \dontignore{Does this work}
\stopignoring


works correctly (of course, this will fail when ignore mode is disabled).

-
\documentclass{article}
\newif\ifToggle \Togglefalse % change to \Toggletrue
\makeatletter
\def\myText#1{\expandafter\myText@i#1\@nil}
\def\myText@i#1\dontignore#2\END#3\@nil{\ifToggle#1\fi#2\ifToggle#3\fi}
\makeatother
\begin{document}
\myText{%
Hello world.  This is my full document with a lot of extra
bells and whistles and lines.  But in the end, \dontignore this
is all that matters \END some more text.}
\end{document}


with \Toggletrue all text is printed.

-