我和同事写了一本有 m 页的书。我们的编辑想要 n << m 页。为了好玩,我想向他提交我们书的两个版本。
一个版本会从最终输出中随机抑制(m-n)页(我想即时进行,即在页面发出后丢弃该页面)。
一个版本随机抑制一小部分字符,以便文档大约有 n 页。
我以为chickenize
包裹可以提供帮助,但是,它却没有提供如此有用的功能。
你有什么主意吗?
答案1
部分解决
这个问题(问题的第一部分)非常诱人,即使我的解决方案不提供黑客攻击,我也无法抗拒它。随着我不断提高 LuaTeX 技能,这个野兽,对不起,我的键盘打错了那个词,我的意思是那个美丽,这个任务是一个挑战。
简单说一下LuaTeX代码的作用:
- 它生成一本200页长的模拟书(
mybook.{tex|pdf}
)。 - 使用伪随机数,它 (
dump-me.tex
) 从包含进程开始时所有页面的 Lua 表 (变量) 中转储页面。我们不能直接使用从 1 到剩余页面数的区间内的伪随机数,因为某些特定数字可能会重复出现,例如一行 55、32、64、89,然后又是 55。我转储了 56 页,可以在第 8 行指定,我们在此输入所需页面数。 - 它会生成四个 TeX 文件并对其进行处理,以将 PDF 放入您的工作目录 (
1-shuffled, 1-unshuffled, 2-sorted, 2-unsorted
)。一个版本是一本未排序的新书,第二个版本是转储页面的未排序版本。 - 它不会触及工作目录中的那些乱七八糟的文件(根本不会删除或清理任何东西)。我宁愿提前写好它,因为代码在后台使用命令 shell。一般来说,这被认为是有风险的。
- 然后,我手动对其中一个文件进行了后期处理以用于本文(
completion.tex
)。
我附上代码:
%! lualatex --shell-escape dump-me.tex
% or
%! lualatex --enable-write18 dump-me.tex
% used in IDEs or use the command shell instead.
% I wish to have a book of 144 pages,
% therefore dump 56 of 200 pages in the example.
\def\wishtohavepages{144}
\def\mybook{mybook.pdf}
% "\\noexpand\\mybook" is a usual way
\directlua{mybookname="\mybook"}
% These days we typeset+indent our work in editor and
% program+store log information in document... ;-)
\documentclass[a4paper]{article}
\usepackage{luacode}
\pagestyle{empty}
\usepackage{pdfpages}
\parindent=0pt
\usepackage{filecontents}
\begin{filecontents}{mybook.tex}
%! {pdf|xe|lua}latex mybook.tex
\documentclass[a4paper]{article}
\usepackage{graphicx}
\pagestyle{empty}
\begin{document}
\font\myfont=cmr10 at 200pt \myfont
\newcount\mytemp \mytemp=0
\loop\newpage
\mbox{}\vfil\hfil\thepage
\advance\mytemp by 1
\ifnum\mytemp<200\repeat
\end{document}
\end{filecontents}
\begin{document}
% First and last regular TeX line...
% Bye-bye TeX, welcome LuaTeX...
\textbf{Summary (log file)}
% Getting PDF from mybook.tex...
\begin{luacode*}
print("") print("") -- rather then backslash n backslash n
print("Processing mybook.tex...")
os.execute("lualatex --interaction=batchmode mybook.tex")
\end{luacode*}
% Load the PDF back to get number of pages...
\pdfximage{\mybook}
\begin{luacode*}
-- Additional help function
function parit()
tex.print("\\par\\medskip")
end -- of parit function
-- Print results
function printme(s,exportto)
s=table.concat(s,",") -- to string with commas
toprocess="\\documentclass{article}\
\\usepackage{pdfpages}\
\\begin{document}\
\\includepdf[pages={"..s.."},fitpaper]{"..mybookname.."}\
\\end{document}"
-- Preparing the TeX file...
-- print(toprocess)
whereto=io.open(exportto,"w")
whereto:write(toprocess)
whereto:close()
-- Run the beast!... ;-)
print("") -- rather then \n, untested across operating systems
print("Processing "..exportto.."...")
os.execute("lualatex --interaction=batchmode "..exportto)
end -- of printme function
-- http://lua-users.org/wiki/CopyTable
-- Is there an easier way of copying tables? But this works...
-- Malipivo doesn't know on March 21, 2014.
function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[deepcopy(orig_key)] = deepcopy(orig_value)
end
setmetatable(copy, deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
-- The core function
function randomizer(pages,wishtohave)
dump=pages-wishtohave
-- a simple verification of dump value
if dump>pages then dump=pages end
math.randomseed(1) -- to have repeateable results
local fulltable={}
for number=1,pages do
fulltable[number]=number
end -- of for cycle
local sorted={} -- dumped pages
local unsorted={} -- dumped pages
local shuffled={} -- the rest of the pages (requested file)
local unshuffled={} -- the rest of the pages (requested file)
local shorttable=fulltable -- a temporary table, items are being removed
for number=1, pages do
dumping=math.random(1,pages-number+1) -- nth value to dump
if number<=dump then
table.insert(sorted,shorttable[dumping])
else
table.insert(shuffled,shorttable[dumping])
end
table.remove(shorttable,dumping)
end -- of for
parit()
tex.print("Shuffled remaining pages\\par")
tex.print(shuffled)
parit()
tex.print("Unshuffled remaining pages\\par")
unshuffled=deepcopy(shuffled)
table.sort(unshuffled)
tex.print(unshuffled)
parit()
tex.print("Unsorted dumped pages\\par")
unsorted=deepcopy(sorted)
tex.print(unsorted)
parit()
tex.print("Sorted dumped pages\\par")
table.sort(sorted)
tex.print(sorted)
parit()
-- Enough talking to TeX, now, prepare the real PDF files...
--print("") -- Escape middle of the line in command shell...
printme(shuffled,"1-shuffled.tex")
printme(unshuffled,"1-unshuffled.tex")
printme(unsorted,"2-unsorted.tex")
printme(sorted,"2-sorted.tex")
-- A return to the real world...
end -- of function randomizer
\end{luacode*}
% Real typesetting...
% The beast and its beauty... :-)
\directlua{randomizer(\the\pdflastximagepages,\wishtohavepages)}
% Some starting point references...
% http://wiki.contextgarden.net/Programming_in_LuaTeX
% http://wiki.luatex.org/index.php/Writing_Lua_in_TeX
\end{document}
我们通过以下方式处理主要代码:
lualatex --shell-escape dump-me.tex
或
lualatex --enable-write18 dump-me.tex
它依赖于你的 TeX 发行版。如果一切运行顺利,你应该会在终端的某个地方看到这五行。
正在处理 mybook.tex...
正在处理 1-shuffled.tex……
正在处理 1-unshuffled.tex……
正在处理 2-unsorted.tex……
正在处理 2-sorted.tex...
主文件动态生成并处理这些文件,这是第一个文件的内容1-shuffled.tex
:
\documentclass{article}
\usepackage{pdfpages}
\begin{document}
\includepdf[pages={58,168,7,75,19,137,12,5,184,57,56,120,140,167,145,97,43,150,94,89,190,147,23,117,78,146,122,111,68,31,46,85,161,103,196,152,66,33,132,98,14,142,100,27,189,28,182,138,62,83,15,193,134,32,176,166,114,41,40,162,88,26,102,151,80,55,115,135,155,144,87,20,69,175,8,104,131,81,17,191,185,108,64,86,67,172,54,84,50,197,52,154,116,36,158,177,73,99,181,6,195,112,10,106,38,169,128,130,42,171,21,16,143,60,188,51,65,22,153,159,129,109,139,47,11,2,25,178,183,63,45,123,9,71,95,157,133,93,48,124,76,194,82,186},fitpaper]{mybook.pdf}
\end{document}
最后,您应该看到一个结果页面,我附上了该页面的预览。
如果您检查工作目录,就会发现有 4 个新的 PDF 文件。我们可能会在 TeX 中对其中一个、部分或全部进行后期处理。我手动挑选了一个 PDF 文件。
%! lualatex completion.tex
\documentclass[a4paper]{article}
\usepackage{pdfpages}
\begin{document}
\includepdf[pages={-},nup=12x12,frame]{1-shuffled.pdf}
\end{document}
这可能是您想要交给编辑的文件。一页空白的页面,里面几乎是完整的书,页面被打乱了…… :-)
答案2
这是使用 latex 方法解决第一个问题的方法,使用atbegshi
包和tikz
生成随机页面(我lcg
先尝试使用,但它似乎使用文件保存的时间来为其随机生成器播种,结果随机页面不是那么随机,除非你保存了文件……)。它不像 Malipivo 的答案那么全面
您可以使用 设置在序言中要打印的页数\NumberOfPagesToPrint
。
\documentclass{article}
\newcount\NumberOfPagesToPrint % total number of pages to print
\NumberOfPagesToPrint=8
\makeatletter
\usepackage{tikz}
\usepackage{atbegshi}
% total number of pages in (main) document
\AtEndDocument{\immediate\write\@auxout{\string\newlabel{TotalNumberOfPages}{{0}{\thepage}}}}
\newcount\@PagesStillToPrint
\newcount\@TotalPages
\AtBeginDocument{
\ifdefined\r@TotalNumberOfPages
\@TotalPages=\number\pageref{TotalNumberOfPages}
\else
\@TotalPages=\NumberOfPagesToPrint
\fi
\@PagesStillToPrint=\@TotalPages
\advance\@PagesStillToPrint -\NumberOfPagesToPrint
}
\newif\if@notShipping
\AtBeginShipout{
% randomly decide to ship this page UNLESS we need to print all
% of the remaining pages in order to fulfil our page quota
\ifnum\@PagesStillToPrint>\@TotalPages
% already printed enough pages
\AtBeginShipoutDiscard%
\else
\ifnum\c@page>\@PagesStillToPrint % need all remaining pages
\@notShippingfalse
\else % randomly decide whether to print this page
\pgfmathrandominteger{\@shippingProb}{0}{1}
\ifnum\@shippingProb=1
\@notShippingfalse
\else
\@notShippingtrue
\fi
\fi
\if@notShipping
\AtBeginShipoutDiscard%
\else
\global\advance\@PagesStillToPrint by 1 % =total pages - pages left
\fi
\fi
}
\makeatother
\begin{document}
Page 1\newpage
Page 2\newpage
Page 3\newpage
Page 4\newpage
Page 5\newpage
Page 6\newpage
Page 7\newpage
Page 8\newpage
Page 9\newpage
Page 10\newpage
Page 11\newpage
Page 12\newpage
Page 13\newpage
Page 14\newpage
Page 15\newpage
Page 16\newpage
Page 17\newpage
\end{document}