Text FormattingUnix shell scripts TeX : how to make them "copy/paste -able"

Information and discussion about LaTeX's general text formatting features (e.g. bold, italic, enumerations, ...)
Post Reply
siarsky
Posts: 4
Joined: Sun Jan 04, 2009 12:47 am

Unix shell scripts TeX : how to make them "copy/paste -able"

Post by siarsky »

Hello

After searching web and finding no answer, I am trying
to post to this forum and hope to find answers, maybe they
are very simple and I am looking on problems from a wrong side...

I am using a Latex/pdftex for writing a documentation with
some Unix shell examples. What I want to achieve is that
every Unix shell example can be copy pasted from the
PDF into the shell without getting any errors in Unix shell.

Image, you would like to print the following shell example
in Latex with pdftex:

ls -l | grep ^d | grep U1000000001 | grep 00 | awk '{print "tar cvz "$9" >/backup/"$9".tar.gz"}'

and want to copy paste it afterwards from PDF into shell and get expected
results.

I know the following approaches :

Approach A: listings
----------
\usepackage{listings}
\usepackage{upquote} %to force Latex not substitute ' by `
\lstset{
language=sh
,breaklines=true
,basicstyle=\ttfamily
, showstringspaces=false}
\begin{lstlisting}
ls -l | grep ^d | grep U1000000001 | grep 00 | awk '{print "tar cvz "$9" >/backup/"$9".tar.gz"}'
\end{lstlisting}

Approach B: verbatim
----------
\usepackage{upquote} %to force Latex not substitute ' by `
\begin{verbatim}
ls -l | grep ^d | grep U1000000001 | grep 00 | awk '{print "tar cvz "$9" >/backup/"$9".tar.gz"}'
\end{verbatim}

Approach C: escape all special characters
----------
\usepackage{upquote} %to force Latex not substitute ' by `
ls -l | grep \verb=^=d | grep U1000000001 | grep 00 | awk \verb='=\{print "tar cvz "\$9" >/backup/"\$9".tar.gz"\}\verb='=\\

no approach really fulfills my requirements, which are:

Requirement________________________________A______B_______C
-------------------------------------------------------
1. Simple copy/paste from Unix shell________YES____YES_____NO
into Latex without escaping
2. Automatic breaklining, if the example_____YES____NO_____YES
is longer than one line
3. Automatic breaklinig really works_________NO____NO_____NO
for shell examples (copy/pasted works):
NO for all approaches => conclusion:
I have to break shell examples manually
using shell end of line "\" character
4. If there is a manual break of a shell_______NO____NO_____NO
example with "\", add no additional
spaces after the "\" character, so that
copy/pasted example works in the shell
5. if an example is too long for one line,______NO____NO_____NO
and has to be broken and the break occurs
at the end of the page, move the entire
shell example on the next page (to avoid
copying of the section name by copy/paste)
6. do not add any spaces into the key_________NO____YES_____YES
words, so that shell examples can be
copy pasted
-------------------------------------------------------

Explanations of requirements:
--------------------------
Requirement 4: I can rewrite the example in shell as:
ls -l | grep ^d | grep U1000000001 | grep 00 | awk \
'{print "tar cvz "$9" >/backup/"$9".tar.gz"}'

which is correct shell script. But I can not print it in Latex, because
Latex (verbatim, listings, latex) adds additional spaces after \ character.

\ with additional spaces does not mean the same in shell, so copy paste
of such example does not work:
-bash: {print "tar cvz "$9" >/backup/"$9".tar.gz"}: No such file or directory

Working solution (break after the pipe | character):
ls -l | grep ^d | grep U1000000001 | grep 00 |
awk '{print "tar cvz "$9" >/backup/"$9".tar.gz"}'

If spaces occur after pipe characters, unix shell ignore
them.
PROBLEM: shell examples without pipes : how to break
them?

Requirement 5: I do not know, how to tell Latex: print
the example always on one page, never on two pages.

Imagine, the first line is printed as a last line of a page:
ls -l | grep ^d | grep U1000000001 | grep 00 |

then there is chapter name in the heading of the next page:
16 CHAPTER 3. INSTALLATION OVER REMOTE CONNECTION

and then the second line of the shell example comes as a
first line of the next page:
awk '{print "tar cvz "$9" >/backup/"$9".tar.gz"}'

So, copy/pasted example into shell looks like:

ls -l | grep ^d | grep U1000000001 | grep 00 |
16 CHAPTER 3. INSTALLATION OVER REMOTE CONNECTION
awk '{print "tar cvz "$9" >/backup/"$9".tar.gz"}'

which is definitely not a working Unix shell example.
I tried \framed, but it makes just a border.

Requirement 6: I do not know how to tell listings to not
add additional spaces into words. If you copy / paste
Approach A into shell, you get:

l s - l | g r e p ^ d | g r e p U 1 0 0 0 0 0 0 0 0 1 | g r e p 0 0 | a w k
' { p r i n t " t a r c v z " $ 9 " > / b a c k u p / " $ 9 " . t a r . g z " } '

after every character listings adds a space - such a example
does not work in the shell.

QUESTIONS:
-----------
1. how to tell Latex : do not add ANY spaces after the last character
(real-verbatim command: print just what I typed !!!!)
(Requirement 4)

2. how to tell Latex : do not print one shell example on two pages,
print it always on one page
(Requirement 5)

3. how to tell Listings : do not add any spaces into text, because
copy paste does not work
(Requirement 6)

4. how to type long unix examples, so that
they can be still copy pasted into shell (and work)?
Example:
grep "1234567890123456789012345678901234567890" /var/log/*
=> manual breaking as:
grep "12345678901234567890123\
45678901234567890" /var/log/*

can you print it in Latex, so that copy / paste into shell works?

5. is there maybe any automatic and correct breaking of shell examples
(some very very specific package?), do you know some good examples?

Thanks
Brano

PS: my document looks like:

\documentclass[12pt]{book}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage{epsfig}
\usepackage{color}
\usepackage{url}
\usepackage[utf8]{inputenc}
\usepackage{listings} %not really used, it adds spaces - you can not copy paste there is \usepackage{upquote} %to force Latex not substitute ' by `
\usepackage{framed}
\usepackage{color}
\usepackage{longtable} %thanks to http://fczaja.blogspot.com/2007/04/longtable-latex.html
\usepackage{hyperref}

\lstset{language=sh,breaklines=true,basicstyle=\ttfamily}

\begin{minipage}{0.25\textwidth}~\end{minipage}
\tableofcontents
\mainmatter
\input debian.tex
\end{document}

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org
LaTeX Beginner's Guide LaTeX Cookbook LaTeX TikZ graphics TikZによるLaTeXグラフィックス
phi
Posts: 577
Joined: Tue Oct 21, 2008 8:10 pm

Unix shell scripts TeX : how to make them "copy/paste -able"

Post by phi »

Hello,
the requirements 4 and 6 are automatically fulfilled (at least on my system) with the listings package (i.e., no spaces are inserted at any place if I use a non-proportional font); if it doesn't work on your system, check the version of the package. 3 can be done using prebreak, perhaps this doesn't work inside strings. 5 is possible if you let the listings float. It is also nice to attach the listings so that Acrobat Reader users can easily open them, but for this to work they have to be external files. Here is an example:

Code: Select all

\begin{filecontents*}{test1.txt}
ls -l | grep ^d | grep U1000000001 | grep 00 | awk '{print "tar cvz "$9" >/backup/"$9".tar.gz"}'
echo 'Hello world'
\end{filecontents*}

\begin{filecontents*}{test2.txt}
ls -l | grep ^d | grep U1000000001 | grep 00 | awk \
'{print "tar cvz "$9" >/backup/"$9".tar.gz"}' 
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
echo 'Hello world'
\end{filecontents*}


\documentclass{article}

\usepackage{textcomp}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage{listings}
\usepackage{lipsum}
\usepackage{attachfile}

\lstset{
  language=sh,
  columns=fixed,
  breaklines=true,
  breakatwhitespace=true,
  prebreak=\textbackslash,
  basicstyle=\ttfamily,
  showstringspaces=false,
  upquote=true
}


\begin{document}

\lstinputlisting[float=htbp]{test1.txt}
\attachfile{test1.txt}

\lipsum[1-2]

\lstinputlisting[float=htbp]{test2.txt}
\attachfile{test1.txt}

\end{document}
siarsky
Posts: 4
Joined: Sun Jan 04, 2009 12:47 am

Re: Unix shell scripts TeX : how to make them "copy/paste -able"

Post by siarsky »

Hello phi

You are right, it is a system dependent issue. I am working
on MacOS X, 10.5.6 with MacTex (TexShop Editor).

The problem is not really TeX, but the PDF viewer.
"Additional spaces problem" occurs only if the final PDF
is displayed in Preview, which is a default PDF viewer
application on mac.

After installing Acrobat Reader 9 and setting it as a default
PDF viewer, I have no issues anymore - I can copy paste
without any additional spaces at the end - great!

Thanks a lot for pointing me to the right direction (I lost
some days on this) and showing me a really nice example,
I will write my shell scripts exactly as you proposed.

Brano

PS: my workaround was until now, changing the font size
for verbatim environment, so that every example has enough
place on one line.
The final document was really ugly and unreadable,
but copy paste - able :)

%Put the following incantation in your preamble and you won't need to say
%\small each time any more:
%taken from http://emacsworld.blogspot.com/2008/04/ ... s-for.html
\makeatletter
\g@addto@macro\@verbatim\tiny
\makeatother
siarsky
Posts: 4
Joined: Sun Jan 04, 2009 12:47 am

Re: Unix shell scripts TeX : how to make them "copy/paste -able"

Post by siarsky »

Dear Latex user group

I was hoping to find a perfect solution for writing a Unix shell documentation,
in which all examples can be very simple copy pasted into the shell and work.

I have still an issue with lstlistings:

\documentclass[12pt]{book}
\usepackage{listings}
\usepackage{upquote} %to force Latex not substitute ' by `
\lstset{
language=sh
,breaklines=true
,basicstyle=\ttfamily
, showstringspaces=false}
\begin{document}
\begin{lstlisting}
ls -l | grep ^d | grep U1000000001 | grep 00 | awk \
'{print "tar cvz "$9" >/backup/"$9".tar.gz"}'
\end{lstlisting}
\end{document}

The result after copy paste from PDF into any editor/shell looks like:

ls -l | grep ^d | grep U1000000001 | grep 00 | awk \
'{ print "tar cvz "$9" >/ backup /"$9". tar.gz"}'

The problem is (which is not so easy to find), that before and after the
word "backup" lstlistings adds spaces, so such a example can not be
copied directly into the shell.

To be sure that it is not a PDF viewer issue on my system I have rechecked
the result in Mac and Windows Acrobat reader, in both readers additional
spaces exist - so for me it looks like a lstlisting issue.

Could you please test this small example on your system and tell me if
there are any additional spaces before and after "backup" word?

Do you know how to avoid them?

No such problem exists in the verbatim mode.

Thank you for your help
Brano
phi
Posts: 577
Joined: Tue Oct 21, 2008 8:10 pm

Re: Unix shell scripts TeX : how to make them "copy/paste -able"

Post by phi »

You're right, I got the same issue. Try to write the package maintainer; this is probably a problem deep inside the package code.
User avatar
localghost
Site Moderator
Posts: 9201
Joined: Fri Feb 02, 2007 12:06 pm

Unix shell scripts TeX : how to make them "copy/paste -able"

Post by localghost »

phi wrote:[...] Try to write the package maintainer; this is probably a problem deep inside the package code.
Not really. The option columns=fullflexible for the setup of listings should do the trick.

Code: Select all

\lstset{
  language=sh,
  breaklines=true
  basicstyle=\ttfamily
  showstringspaces=false,
  columns=fullflexible
}

Best regards
Thorsten¹
How to make a "Minimal Example"
Board Rules
Avoidable Mistakes[/size]

¹ System: openSUSE 42.2 (Linux 4.4.52), TeX Live 2016 (vanilla), TeXworks 0.6.1
phi
Posts: 577
Joined: Tue Oct 21, 2008 8:10 pm

Re: Unix shell scripts TeX : how to make them "copy/paste -able"

Post by phi »

Yes, I unfortunately confused "fixed" and "flexible" during the whole thread, of course with "flexible" all problems vanish...
siarsky
Posts: 4
Joined: Sun Jan 04, 2009 12:47 am

Re: Unix shell scripts TeX : how to make them "copy/paste -able"

Post by siarsky »

You are incredible supporters, thank you very much, it does the trick!

I read the listings documentation and I remember this section
about "columns", but I never realized it could have something
to do with my problem.

Brano
Post Reply