双面书中的广泛列表

双面书中的广泛列表

在此 MWE 上,我尝试通过设置使列表环境大于文本宽度linewidth = \textwidth+\marginparsep+\marginparwidth。但是,结果不是我想要的。在第 2 页上,列表环境应从左边距开始。

在此处输入图片描述

\documentclass[a4paper, 12pt, twoside]{book}

\usepackage[includeall]{geometry}

\usepackage{sourcecodepro}
\usepackage{listings}
\usepackage{calc}
\newlength\lstlen
\setlength{\lstlen}{\textwidth+\marginparsep+\marginparwidth}

\lstset{%
    basicstyle          = \ttfamily\small,
    language            = c,
    columns             = fullflexible,
    flexiblecolumns     = false,
    emptylines          = *1,
    tabsize             = 4,
    breaklines          = true,
    showstringspaces    = false,
    linewidth           = \lstlen,
    frame               = single,
}

\usepackage{lipsum}
\begin{document}
    \lipsum[1-4]
    \begin{lstlisting}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>

#include <cairo.h>

#ifndef M_PI
#define M_PI 3.1415927
#endif

#define GR(X,Y) (d[(*s)*(Y)+bpp*(X)+((2)%bpp)])
#define GG(X,Y) (d[(*s)*(Y)+bpp*(X)+((1)%bpp)])
#define GB(X,Y) (d[(*s)*(Y)+bpp*(X)+((0)%bpp)])
#define SR(X,Y) (ht[4*tw*((Y)%th)+4*((X)%tw)+2])
#define SG(X,Y) (ht[4*tw*((Y)%th)+4*((X)%tw)+1])
#define SB(X,Y) (ht[4*tw*((Y)%th)+4*((X)%tw)+0])
#define RAD(A)  (M_PI*((double)(A))/180.0)
uint8_t *houghtransform(uint8_t *d, int *w, int *h, int *s, int bpp)
{
  int rho, theta, y, x, W = *w, H = *h;
  int th = sqrt(W*W + H*H)/2.0;
  int tw = 360;
  uint8_t *ht = malloc(th*tw*4);
  memset(ht, 0, 4*th*tw); // black bg

  for(rho = 0; rho < th; rho++)
  {
    for(theta = 0; theta < tw/*720*/; theta++)
    {
      double C = cos(RAD(theta));
      double S = sin(RAD(theta));
      uint32_t totalred = 0;
      uint32_t totalgreen = 0;
      uint32_t totalblue = 0;
      uint32_t totalpix = 0;
      if ( theta < 45 || (theta > 135 && theta < 225) || theta > 315) {
    for(y = 0; y < H; y++) {
      double dx = W/2.0 + (rho - (H/2.0-y)*S)/C;
      if ( dx < 0 || dx >= W ) continue;
      x = floor(dx+.5);
      if (x == W) continue;
      totalpix++;
      totalred += GR(x, y);
      totalgreen += GG(x, y);
      totalblue += GB(x, y);
    }
      } else {
    for(x = 0; x < W; x++) {
      double dy = H/2.0 - (rho - (x - W/2.0)*C)/S;
      if ( dy < 0 || dy >= H ) continue;
      y = floor(dy+.5);
      if (y == H) continue;
      totalpix++;
      totalred += GR(x, y);
      totalgreen += GG(x, y);
      totalblue += GB(x, y);      
    }
      }
      if ( totalpix > 0 ) {
    double dp = totalpix;
    SR(theta, rho) = (int)(totalred/dp)   &0xff;
    SG(theta, rho) = (int)(totalgreen/dp) &0xff;
    SB(theta, rho) = (int)(totalblue/dp)  &0xff;
      }
    }
  }

  *h = th;   // sqrt(W*W+H*H)/2
  *w = tw;   // 360
  *s = 4*tw;
  return ht;
}

int main(int argc, char **argv)
{
  cairo_surface_t *inputimg = NULL;
  cairo_surface_t *houghimg = NULL;

  uint8_t *houghdata = NULL, *inputdata = NULL;
  int w, h, s, bpp;

  if ( argc < 3 ) return EXIT_FAILURE;

  inputimg = cairo_image_surface_create_from_png(argv[1]);

  w = cairo_image_surface_get_width(inputimg);
  h = cairo_image_surface_get_height(inputimg);
  s = cairo_image_surface_get_stride(inputimg);  
  bpp = cairo_image_surface_get_format(inputimg);
  switch(bpp)
  {
  case CAIRO_FORMAT_ARGB32: bpp = 4; break;
  case CAIRO_FORMAT_RGB24:  bpp = 3; break;
  case CAIRO_FORMAT_A8:     bpp = 1; break;
  default:
    fprintf(stderr, "unsupported\n");
    goto destroy;
  }

  inputdata = cairo_image_surface_get_data(inputimg);
  houghdata = houghtransform(inputdata, &w, &h, &s, bpp);

  printf("w=%d, h=%d\n", w, h);
  houghimg = cairo_image_surface_create_for_data(houghdata,
                         CAIRO_FORMAT_RGB24,
                         w, h, s);
  cairo_surface_write_to_png(houghimg, argv[2]);

destroy:
  if (inputimg != NULL) cairo_surface_destroy(inputimg);
  if (houghimg != NULL) cairo_surface_destroy(houghimg);

  return EXIT_SUCCESS;
}
    \end{lstlisting}
\end{document}

答案1

这里的问题是,整个列表的排版左边距与文本的其余部分相同。要获得所需的内容,必须在 TeX 分页算法之外进行分页,然后在偶数页上将其排版移到左侧(进入 marginpar 区域),然后再放到页面上。这可以通过软件包实现framed,通过将分页的片段放在一种虚拟“框架”中,使其在页面上正确定位,即在奇数页上向右突出,在偶数页上向左突出。

这是一个解决方案,定义一个widelst环境。

\documentclass[a4paper, 12pt, twoside]{book}

\usepackage[includeall]{geometry}
\usepackage{sourcecodepro}
\usepackage{listings}
\usepackage{calc}
\newlength\lstlen
\setlength{\lstlen}{\textwidth+\marginparsep+\marginparwidth}

\usepackage{framed}
\newenvironment{widelst}
  {\def\FrameCommand##1{%
      \ifodd\value{page}\makebox[\textwidth][l]{##1}\else\makebox[\textwidth][r]{##1}\fi}%
    \MakeFramed{\FrameRestore}}
  {\endMakeFramed}

\lstset{%
    basicstyle          = \ttfamily\small,
    language            = c,
    columns             = fullflexible,
    flexiblecolumns     = false,
    emptylines          = *1,
    tabsize             = 4,
    breaklines          = true,
    showstringspaces    = false,
    linewidth           = \lstlen,
    frame               = single,
}

\usepackage{lipsum}
\begin{document}
    \lipsum[1-4]
\begin{widelst}
    \begin{lstlisting}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>

#include <cairo.h>

#ifndef M_PI
#define M_PI 3.1415927
#endif

#define GR(X,Y) (d[(*s)*(Y)+bpp*(X)+((2)%bpp)])
#define GG(X,Y) (d[(*s)*(Y)+bpp*(X)+((1)%bpp)])
#define GB(X,Y) (d[(*s)*(Y)+bpp*(X)+((0)%bpp)])
#define SR(X,Y) (ht[4*tw*((Y)%th)+4*((X)%tw)+2])
#define SG(X,Y) (ht[4*tw*((Y)%th)+4*((X)%tw)+1])
#define SB(X,Y) (ht[4*tw*((Y)%th)+4*((X)%tw)+0])
#define RAD(A)  (M_PI*((double)(A))/180.0)
uint8_t *houghtransform(uint8_t *d, int *w, int *h, int *s, int bpp)
{
  int rho, theta, y, x, W = *w, H = *h;
  int th = sqrt(W*W + H*H)/2.0;
  int tw = 360;
  uint8_t *ht = malloc(th*tw*4);
  memset(ht, 0, 4*th*tw); // black bg

  for(rho = 0; rho < th; rho++)
  {
    for(theta = 0; theta < tw/*720*/; theta++)
    {
      double C = cos(RAD(theta));
      double S = sin(RAD(theta));
      uint32_t totalred = 0;
      uint32_t totalgreen = 0;
      uint32_t totalblue = 0;
      uint32_t totalpix = 0;
      if ( theta < 45 || (theta > 135 && theta < 225) || theta > 315) {
    for(y = 0; y < H; y++) {
      double dx = W/2.0 + (rho - (H/2.0-y)*S)/C;
      if ( dx < 0 || dx >= W ) continue;
      x = floor(dx+.5);
      if (x == W) continue;
      totalpix++;
      totalred += GR(x, y);
      totalgreen += GG(x, y);
      totalblue += GB(x, y);
    }
      } else {
    for(x = 0; x < W; x++) {
      double dy = H/2.0 - (rho - (x - W/2.0)*C)/S;
      if ( dy < 0 || dy >= H ) continue;
      y = floor(dy+.5);
      if (y == H) continue;
      totalpix++;
      totalred += GR(x, y);
      totalgreen += GG(x, y);
      totalblue += GB(x, y);      
    }
      }
      if ( totalpix > 0 ) {
    double dp = totalpix;
    SR(theta, rho) = (int)(totalred/dp)   &0xff;
    SG(theta, rho) = (int)(totalgreen/dp) &0xff;
    SB(theta, rho) = (int)(totalblue/dp)  &0xff;
      }
    }
  }

  *h = th;   // sqrt(W*W+H*H)/2
  *w = tw;   // 360
  *s = 4*tw;
  return ht;
}

int main(int argc, char **argv)
{
  cairo_surface_t *inputimg = NULL;
  cairo_surface_t *houghimg = NULL;

  uint8_t *houghdata = NULL, *inputdata = NULL;
  int w, h, s, bpp;

  if ( argc < 3 ) return EXIT_FAILURE;

  inputimg = cairo_image_surface_create_from_png(argv[1]);

  w = cairo_image_surface_get_width(inputimg);
  h = cairo_image_surface_get_height(inputimg);
  s = cairo_image_surface_get_stride(inputimg);  
  bpp = cairo_image_surface_get_format(inputimg);
  switch(bpp)
  {
  case CAIRO_FORMAT_ARGB32: bpp = 4; break;
  case CAIRO_FORMAT_RGB24:  bpp = 3; break;
  case CAIRO_FORMAT_A8:     bpp = 1; break;
  default:
    fprintf(stderr, "unsupported\n");
    goto destroy;
  }

  inputdata = cairo_image_surface_get_data(inputimg);
  houghdata = houghtransform(inputdata, &w, &h, &s, bpp);

  printf("w=%d, h=%d\n", w, h);
  houghimg = cairo_image_surface_create_for_data(houghdata,
                         CAIRO_FORMAT_RGB24,
                         w, h, s);
  cairo_surface_write_to_png(houghimg, argv[2]);

destroy:
  if (inputimg != NULL) cairo_surface_destroy(inputimg);
  if (houghimg != NULL) cairo_surface_destroy(houghimg);

  return EXIT_SUCCESS;
}
    \end{lstlisting}
\end{widelst}
\end{document}

在此处输入图片描述

相关内容