GeneralTemporarily add marginparwidth to textwidth

LaTeX specific issues not fitting into one of the other forums of this category.
rplantz
Posts: 16
Joined: Mon Jan 21, 2008 12:35 am

Temporarily add marginparwidth to textwidth

Post by rplantz »

I have written a book about assembly language programming using latex. I have quite a few margin notes in a marginparwidth of 72 pt. My book has quite a few code examples, for which I use the listings package.

It's all very nice, but I get lots of overfull hbox warnings. In the code listing areas, it would be nice to expand textwidth to include the margin note area.

I tried using a "narrow" macro and adding negative amounts to the margins in a list environment. But it fails when the code flows to another page in my two-sided book.

Is there a way to do this?

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

And: Currently, Packt sells ebooks for $4.99 each if you buy 5 of their over 1000 ebooks. If you choose only a single one, $9.99. How about combining 3 LaTeX books with Python, gnuplot, mathplotlib, Matlab, ChatGPT or other AI books? Epub and PDF. Bundle (3 books, add more for higher discount): https://packt.link/MDH5p

Juanjo
Posts: 657
Joined: Sat Jan 27, 2007 12:46 am

Temporarily add marginparwidth to textwidth

Post by Juanjo »

Is this what are you searching for?

Code: Select all

\documentclass{article}

\newenvironment{widepar}%
  {\setlength{\rightskip}{-\marginparsep}\addtolength{\rightskip}{-\marginparwidth}}{\par}

\begin{document}

This is a normal paragraph. Text is left and right justified. 
This is a normal paragraph. Text is left and right justified.
This is a normal paragraph. Text is left and right justified.

This is still a normal paragraph, but it also has a marginal note.
\marginpar{\footnotesize This is the text of the marginal note} Text is left and right justified.

This is again a normal paragraph. Text is left and right justified. 
This is again a normal paragraph. Text is left and right justified.

\begin{widepar}
Lines in this paragraph extend on the right margin, occupying the space reserved to marginal notes.
Lines in this paragraph extend on the right margin, occupying the space reserved to marginal notes.
\newpage
A new page has started. As wanted, lines still extend on the right margin, occupying the space 
reserved to marginal notes. 
\end{widepar}

We conclude with a normal paragraph. Text is left and right justified. 
We conclude with a normal paragraph. Text is left and right justified. 

\end{document}

rplantz
Posts: 16
Joined: Mon Jan 21, 2008 12:35 am

Temporarily add marginparwidth to textwidth

Post by rplantz »

Thank you for your suggestion, Juanjo, but it's not quite what I'm looking for.

I am looking for a way to essentially add \marginparwidth + \marginparsep to \textwidth within a page, then restore things on a subsequent page. This would allow me to use \lstinputlisting to include my code, which may be wider than the overall document \textwidth. So on an even numbered page the left side of my code would begin in what is normally the \marginpar area. On an odd numbered page wide code would extend into the \marginpar area.

It could be that the easiest way is for me to modify my code such that it fits into the normal \textwidth area.

I have located

Code: Select all

\newenvironment{narrow}[2]{%
  \begin{list}{}{%
  \setlength{\topsep}{0pt}%
  \setlength{\leftmargin}{#1}%
  \setlength{\rightmargin}{#2}%
  \setlength{\listparindent}{\parindent}%
  \setlength{\itemindent}{\parindent}%
  \setlength{\parsep}{\parskip}}%
\item[]}{\end{list}}
which allows me to adjust wide floats horizontally but providing negative values for the arguments. With a little ifthenelse logic I can make it work for both sides of the page. This works for floats because they end up entirely on one page. It fails for my code listings because they can span more than one page.
User avatar
Juanjo
Posts: 657
Joined: Sat Jan 27, 2007 12:46 am

Temporarily add marginparwidth to textwidth

Post by Juanjo »

Let's suggest a different idea. I guess that you only want to enlarge the page width when including listings. So you can play with the xleftmargin and xrightmargin keywords in the \lstinputlisting command. Suppose you place this code in the preamble, after loading listings:

Code: Select all

\newlength{\additionalspace}
\setlength{\additionalspace}{-\marginparsep}\addtolength{\additionalspace}{-\marginparwidth}

\newcommand{\mylstinputlisting}[2][]{%
   \ifodd\value{page}
      \lstset{xleftmargin=0pt,xrightmargin=\additionalspace}
      \lstinputlisting[#1]{#2}
   \else
      \lstset{xleftmargin=\additionalspace,xrightmargin=0pt}
      \lstinputlisting[#1]{#2}
  \fi}
Then, you could use \mylstinputlisting instead of \lstinputlisting. Automatically, the listed code will occupy the left or right margins, if needed. Of course, this fails for listings which extend through more than one page. I do not see how to detect the point where the page changes, in order to revert the values of xleftmargin and xrightmargin. Some collaboration of your part is required for fine tuning in such a case. So, instead of a long listing, say \mylstinputlisting{myfile}, write something like

Code: Select all

\mylstinputlisting[firstline=1,lastline=30]{myfile} \newpage
\mylstinputlisting[firstline=31]{myfile}
rplantz
Posts: 16
Joined: Mon Jan 21, 2008 12:35 am

Re: Temporarily add marginparwidth to textwidth

Post by rplantz »

Thanks for the additional suggestion, Juanjo.

I have over 200 code listings in my book, so I'm trying to avoid tweaking at the page level. I think it will be easier for me to tweak my code source files. But if I run into a place where that's not good enough, I will use your suggestions.

I still find it a bit frustrating that I can't simply define an environment where \marginparwidth and \marginparsep are added to \textwidth. On the other hand, I originally wrote the book in Word. The many frustrations of that program caused me to learn LaTeX, which is several orders of magnitude better and has saved me many, many days of frustration.
99problems
Posts: 2
Joined: Sat Jan 26, 2008 2:27 am

Re: Temporarily add marginparwidth to textwidth

Post by 99problems »

So, is it not possible to vary the margin width within a latex document? I have a table that is wider than the text width but not page width and it would be convenient for me to display it within these specifications. I've experienced a great deal of aggravation in searching for a solution; I've seen use of the tabular* environment but have not been able to get the table properly centered. Obviously, I'm no latex wizz, so any pointers in the right direction would be great.
User avatar
Juanjo
Posts: 657
Joined: Sat Jan 27, 2007 12:46 am

Temporarily add marginparwidth to textwidth

Post by Juanjo »

99problems wrote:So, is it not possible to vary the margin width within a latex document?
No, you can vary it, as shown on my post above. Try this code:

Code: Select all

\documentclass{article}

\newenvironment{custommargins}[2]%
  {\addtolength{\leftskip}{#1}\addtolength{\rightskip}{#2}}{\par}

\begin{document}
\noindent\leftarrowfill Text line in a normal paragraph\rightarrowfill \par
\noindent\leftarrowfill Text line in a normal paragraph\rightarrowfill

\begin{custommargins}{0cm}{-2cm}
  \noindent\leftarrowfill Same left margin. Smaller right margin\rightarrowfill \par
  \noindent\leftarrowfill Text lines are longer\rightarrowfill
\end{custommargins}

\begin{custommargins}{0cm}{2cm}
  \noindent\leftarrowfill Same left margin. Greater right margin\rightarrowfill \par
  \noindent\leftarrowfill Text lines are shorter\rightarrowfill
\end{custommargins}

\begin{custommargins}{-2cm}{2cm}
  \noindent\leftarrowfill Smaller left margin. Greater right margin\rightarrowfill \par
  \noindent\leftarrowfill Text lines are shifted on the left\rightarrowfill
\end{custommargins}

\begin{center}
  \begin{custommargins}{-2cm}{-2cm}
   \leftarrowfill Table centered in a line 4 cm longer\rightarrowfill \par
    \begin{tabular}{|c|c|c|c|c|c|c|c|}
     \hline \multicolumn{8}{|c|}{A wide table} \\ \hline
     One.One & One.Two & One.Three & One.Four & One.Five 
             & One.Six & One.Seven & One.Eight \\
     Two.One & Two.Two & Two.Three & Two.Four & Two.Five
             & Two.Six & Two.Seven & Two.Eight \\ \hline
    \end{tabular}
  \end{custommargins} 
\end{center}
\end{document}
Play with the arguments of custonmargins to see what happens.

Although you have freedom to change margins, I think it is not a good practice to modify the layout from one page to another, or even in the same page.
I have a table that is wider than the text width but not page width and it would be convenient for me to display it within these specifications. I've experienced a great deal of aggravation in searching for a solution; I've seen use of the tabular* environment but have not been able to get the table properly centered. Obviously, I'm no latex wizz, so any pointers in the right direction would be great.
This thread may help you to fit the table in the page.
99problems
Posts: 2
Joined: Sat Jan 26, 2008 2:27 am

Re: Temporarily add marginparwidth to textwidth

Post by 99problems »

Thanks man. Perfect.
rplantz
Posts: 16
Joined: Mon Jan 21, 2008 12:35 am

Temporarily add marginparwidth to textwidth

Post by rplantz »

99problems wrote:So, is it not possible to vary the margin width within a latex document? I have a table that is wider than the text width but not page width and it would be convenient for me to display it within these specifications. I've experienced a great deal of aggravation in searching for a solution; I've seen use of the tabular* environment but have not been able to get the table properly centered. Obviously, I'm no latex wizz, so any pointers in the right direction would be great.
For my wide tables I use the "narrow" macro that I gave above. I got it from section 23.2 in "Using Imported Graphics in LaTeX and pdfLaTeX" (version 3.0) by Keith Reckdahl. A search will quickly bring up a pdf copy you can download.

He shows how to use it for double-sided pages. For example, I did:

Code: Select all

\begin{table}[!ht]
\ifthenelse{\isodd{\pageref{tb:number_syntax}}}%
{% BEGIN ODD-PAGE
  \begin{narrow}{0in}{-0.6in}
\begin{tabular}{rlrlrlrl}
%%%% my table
\end{tabular}
   \caption[ASCII code for representing characters.]{ASCII code for representing characters.
   The bit patterns (bit pat.) are shown in hexadecimal.}
   \label{tb:ascii}
   \end{narrow}
}% END ODD-PAGE
{% BEGIN EVEN-PAGE
  \begin{narrow}{-0.6in}{0in}
\begin{tabular}{rlrlrlrl}
%%%% my table
\end{tabular}
   \caption[ASCII code for representing characters.]{ASCII code for representing characters.
   The bit patterns (bit pat.) are shown in hexadecimal.}
   \label{tb:ascii}
   \end{narrow}
}% END EVEN-PAGE
Notice that the arguments to the narrow environment are negative, and they are reversed depending on whether it's an odd or even page.

This will _not_ work if the table extends across page because the temporary margin adjustment depends on the page number of the \label.

One of the main reasons I'm using the listings package for my code listings is so that they will extend across pages in a nice way. I originally did them in floats, which meant I had to divide my long code into smaller files --- a real pain. I decided that it's better to tweak my code (the code I'm displaying in my book, not my LaTeX code) so that it fits within \textwidth.
loukote
Posts: 3
Joined: Tue Feb 03, 2009 11:52 pm

Temporarily add marginparwidth to textwidth

Post by loukote »

Hi,

just to report that the custommargins environment as defined above can be used to print large figures too. (Not only larger graphics -- figures are problematic since floating.) For this, put a minipage in the figure environment and then the custommargins environment inside of both:

Code: Select all

\begin{figure}
  \begin{minipage}{\textwidth}
    \begin{center}
      \begin{custommargins}{-1.5cm}{-1.5cm}
        \includegraphics[width=#3\linewidth]{figs/myFigure}
        \caption{The caption text}
        \label{fig:andItsLabel}
      \end{custommargins}
    \end{center}
  \end{minipage}
\end{figure}
This way only the figure is wider than the page and remains floating.

Regards,
Ondra
Post Reply