Since TeX and LaTeX can print out any text, it should be possible to write a self-replicating document, i.e., a document that is typeset as a PDF/DVI of itself. Have you seen something like that?
A long time ago, in a country far far away, under the influence of Hoefstader's Godel, Escher, Bach, I spent a merry few minutes playing with programs that would print out themselves. One goal was to make a minimal such program in a particular language, another was to have a general scheme that could be added to make any program (in that language) do this (in addition to what the program was supposed to do). In pursuit of that latter goal I figured out some general ingredients that could be used to do this. These were:
- The ability to convert from an integer to a character.
- The ability to make decisions.
- The ability to iterate over a list.
With these, the scheme is as follows. Create a list containing the code converted into some integer representation of the symbols it contains. Insert into that list a special character (usually 0
is a safe bet) at a particular point. Then the program iterates through the list. Its normal behaviour is to convert each integer into the character it represents and output that. However, when it encounters 0
it simply outputs the list.
Here's a TeX version of that:
\tt
\parindent0pt
\emergencystretch3em
\def\A{92, 116, 116, 10, 92, 112, 97, 114, 105, 110, 100, 101, 110, 116, 48, 112, 116,
10, 92, 101, 109, 101, 114, 103, 101, 110, 99, 121, 115, 116, 114, 101, 116, 99, 104,
51, 101, 109, 10, 92, 100, 101, 102, 92, 65, 123, 0, 125, 10, 92, 108, 111, 110, 103, 92,
100, 101, 102, 92, 84, 35, 49, 44, 123, 37, 10, 92, 105, 102, 110, 117, 109, 35, 49, 60,
48, 92, 114, 101, 108, 97, 120, 10, 92, 101, 108, 115, 101, 10, 92, 105, 102, 110, 117,
109, 35, 49, 62, 48, 92, 114, 101, 108, 97, 120, 10, 92, 105, 102, 110, 117, 109, 35, 49,
61, 49, 48, 92, 114, 101, 108, 97, 120, 10, 92, 112, 97, 114, 10, 92, 101, 108, 115, 101,
10, 92, 99, 104, 97, 114, 35, 49, 10, 92, 102, 105, 10, 92, 101, 108, 115, 101, 10, 92,
65, 10, 92, 102, 105, 10, 92, 101, 120, 112, 97, 110, 100, 97, 102, 116, 101, 114, 92,
84, 92, 102, 105, 125, 10, 92, 101, 120, 112, 97, 110, 100, 97, 102, 116, 101, 114, 92,
84, 92, 65, 92, 98, 121, 101, -1, }
\long\def\T#1,{%
\ifnum#1<0\relax
\else
\ifnum#1>0\relax
\ifnum#1=10\relax
\par
\else
\char#1
\fi
\else
\A
\fi
\expandafter\T\fi}
\expandafter\T\A\bye
This produces:
-
3This is a fairly good general approach to self-replication! – fgysin reinstate Monica Feb 5 '13 at 14:58
Save as quine.tex
and compile with tex
(or pdftex
for PDF output):
\def\T{
\tt \hsize 32.5em\parindent 0pt\def \S {\def \S ##1>{}}\S \string
\def \string \T \string {\par \expandafter \S \meaning \T \string
}\par \expandafter \S \meaning \T \footline {} \end }
\tt \hsize 32.5em\parindent 0pt\def \S {\def \S ##1>{}}\S \string
\def \string \T \string {\par \expandafter \S \meaning \T \string
}\par \expandafter \S \meaning \T \footline {} \end
It is due to Péter Szabó and has been published on TUGboat, vol. 29 (2008), p. 207 as part of the TeX Pearls section at EuroBachoTeX 2007.
Here's the output:
Here is a simple example:
\documentclass{article}
\pagestyle{empty}
\usepackage{listings}
\begin{document}
\lstinputlisting{\jobname}
\end{document}
The result looks as the original:
But if you want to be able to copy from the PDF, you must use this code:
\documentclass{article}
\pagestyle{empty}
\usepackage{listings}
\lstset{basicstyle=\ttfamily,flexiblecolumns=true}
\begin{document}
\lstinputlisting{\jobname}
\end{document}
The result:
-
14Usually it is not allowed to read the source file for such challenges. When doing so, the challenge gets almost trivial. – Martin Scharrer♦ Jan 14 '13 at 15:31
-
1@MartinScharrer I know... but the above question had no such restriction! :-) – Paul Gaborit Jan 14 '13 at 15:46
-
6
-
6Not from me! (Maybe there should be a "Nice try" badge for situations like this.) And cheating artfully is art, too! – mafp Jan 15 '13 at 16:23
-
1+1 to compensate for the downvote...nothing in the question said you couldn't input the file itself! – Scott H. Jan 15 '13 at 16:46
If inputting the file itself is allowed, here's a shorter version (Plain TeX):
\def\q{\par\begingroup\tt
\obeylines \catcode`\\=12
\catcode`{12\catcode`}=12
\obeyspaces\input\jobname
\endgroup}\q\bye
Alternative version:
\let~=\catcode\def\q{{~`\\12 ~`{12 ~`}12 ~`~12\tt
\obeyspaces\obeylines\input\jobname\relax}}\q\bye
-
4The callenge here is writting a program/document which prints itself without reading its own source code. Doing so would be too easy in almost every programming language (where the program has access to its source code). – Martin Scharrer♦ Jan 14 '13 at 15:32
-
3@MartinScharrer Yes, of course. That's why I added the initial disclaimer. But in this case there are some subtleties with category codes that aren't present in other languages. – egreg Jan 14 '13 at 15:34
Much impressed and motivated by Andrew Stacey
's beautiful answer, I obtained another way to implement his idea about how can go about this. It is a bit different as I use active characters and delimited macros and less of \char
although I did use it.
Update: I am adding another shorter method. It is less analogous to Andrew
's solution.
LaTeX Update: I am adding a LaTeX solution, in the same spirit. I could have spared a few braces in the \(re)newcommand
's but I was already feeling guilty about not using any package... and also about having authorized a \let
primitive into the code...
Plain TeX Update: one more incarnation in Plain TeX.
\tt\obeylines\obeyspaces\nopagenumbers
\def\stop{\par\vfill\supereject\end}
\catcode42=13 \catcode60=13 \catcode62=13
\catcode63=13 \catcode43=13
\chardef<123 \chardef>125 \chardef?35
\def+{\char92stop}\let*\string
\long\def\a{
*\tt*\obeylines*\obeyspaces*\nopagenumbers
*\def*\stop<*\par*\vfill*\supereject*\end>
*\catcode42=13 *\catcode60=13 *\catcode62=13
*\catcode63=13 *\catcode43=13
*\chardef*<123 *\chardef*>125 *\chardef*?35
*\def*+<*\char92stop>*\let***\string
*\long*\def*\a<!>
*\long*\def*\t?1!?2+<?1<*\def**<*\string***\string>
*\def*<<*\string*<>*\def*><*\string*>>
*\def*?<*\string*?>*\def*+<*\string*+>
*\a>?2+>
*\expandafter*\t*\a*\stop}
\long\def\t#1!#2\stop{#1{\def*{\string*\string}
\def<{\string<}\def>{\string>}
\def?{\string?}\def+{\string+}
\a}#2\stop}
\expandafter\t\a\stop
\tt\obeylines\obeyspaces\nopagenumbers
\let~\string \chardef\<=123 \chardef\>=125
\def\4{{\def~{\string~\string}\def\4{\string\4}
\def\<{\string\<}\def\>{\string\>}\a}\>
~\a\par\vfill\eject\end}
\def\a{
~\tt~\obeylines~\obeyspaces~\nopagenumbers
~\let~~~\string ~\chardef~\<=123 ~\chardef~\>=125
~\def~\4\<\<~\def~~\<~\string~~~\string\>~\def~\4\<~\string~\4\>
~\def~\<\<~\string~\<\>~\def~\>\<~\string~\>\>~\a\>~\>
~~~\a~\par~\vfill~\eject~\end\>
~\def~\a\<
\4}
\a
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
\obeylines\thispagestyle{empty}
\let~\textbackslash
\newcommand{\asciitilde}{\raisebox{-.5\height}{\textasciitilde}}
\newcommand{\mymyself}{{\let~\asciitilde
\renewcommand{\{}{\textbackslash\textbraceleft}
\renewcommand{\}}{\textbackslash\textbraceright}
\renewcommand{\asciitilde}{\textbackslash asciitilde}
\renewcommand{\mymyself}{\textbackslash mymyself}\myself}}
\newcommand{\myself}{
~documentclass\{article\}
~usepackage[T1]\{fontenc\}
~begin\{document\}
~obeylines~thispagestyle\{empty\}
~let\asciitilde~textbackslash
~newcommand\{~asciitilde\}\{~raisebox\{-.5~height\}\{~textasciitilde\}\}
~newcommand\{~mymyself\}\{\{~let\asciitilde~asciitilde
~renewcommand\{~\{\}\{~textbackslash~textbraceleft\}
~renewcommand\{~\}\}\{~textbackslash~textbraceright\}
~renewcommand\{~asciitilde\}\{~textbackslash asciitilde\}
~renewcommand\{~mymyself\}\{~textbackslash mymyself\}~myself\}\}
~newcommand\{~myself\}\{\mymyself\}
~myself
~end\{document\}}
\myself
\end{document}
\tt\obeylines
\nopagenumbers\let~\string
\def\a{~\tt~\obeylines
~\nopagenumbers~\let~~~\string
~\def~\a~{\b~}
~\def~\b~{~{~\def~~~{~\string~~~\string~}~\def~\b~{~\string~\b~}~\a~}~}
~\a~\b~ye}
\def\b{{\def~{\string~\string}\def\b{\string\b}\a}}
\a\bye
-
-
1Yes. As I said in my header, Andrew's answer was the guiding light. I had some unhappy tries with catcodes, then it became easy when I realized active characters were better. The second example is a bit more inscrutable but it uses the same basic technique from the first one which is to have a prefix either print the control sequence following it verbatim, or when it turns to output the
list
, to also print itself. The first example is easier: there is a header and a footer, and then the\a
macro is the coded verbatim version with a!
in the middle outputting\a
verbatim. – user4686 Jan 15 '13 at 21:01 -
1... well I wanted to make
!
output\a
but in the end I used the trick of the delimited macro so that!
does not by itself do anything special. Then in the second method I finally got the\4
doing thisoutputting the list
thing. This was my initial idea, but I could not immediately make it work, so I ended up with the first method initially. – user4686 Jan 15 '13 at 21:03 -
The LaTeX example could do without
\usepackage[T1]{fontenc}
but the tilde would be smaller. On the other hand the backslash would be a bit heavier (and nicer in my opinion). – user4686 Jan 16 '13 at 9:37
.dtx
file is a variant of the above concept (textdoc docstrip). – Yiannis Lazarides Jan 14 '13 at 13:05