当我使用 tikz 之类的包时,解决方案很简单。但我不应该使用包。我需要在 latex 中使用 post script。我试图在宏中使用两条直线和两条曲线绘制这个椭圆,我需要将 currentpoint 传递给宏。我不知道如何将 currentpoint 传递给宏。有没有办法将 currentpoint(具有 x、y)传递给宏,以便使用这些 x 和 y 点绘制直线和曲线?我提到我不应该在我的程序中使用包,因为这是我的项目,我的教授让我在 LATEX 中使用 postscript 编写这个程序。
下面是我需要用我的程序执行的操作的示例:
据我所知,在我输入单词 LaTEX 后,当我说 \special{pS: currentpoint} 时,它指向单词 LaTEX 后面的点的 x 和 y 坐标。如果我将这些坐标传递给我的宏并计算点:
下面是我的代码:
\documentclass{article}
\usepackage{calc}
\begin{document}
\newcommand{\drawoval}[4] {
\newcommand\x{#1}
\newcommand\y{#2}
\newcommand\length{#3}
\newcommand\height{#4}
\newcommand\x1{\the\numexpr\x-\length}
\newcommand\y1{\the\y}
\newcommand\x2{\the\x}
\newcommand\y2{\the\y}
\newcommand\x3{\the\numexpr\x+5}
\newcommand\y3{\the\numexpr\y+\height/2}
\newcommand\x4{\the\x}
\newcommand\y4{\the\numexpr\y+\height}
\newcommand\x5{\the\numexpr\x-\length}
\newcommand\y5{\the\numexpr\y+\height}
\newcommand\x6{\the\numexpr\x-\length+5}
\newcommand\y6{\the\numexpr\y+\height/2}
\special{pS: x1 y1 x6 y6 x5 y5 curveto 1 0 0 setrgbcolor stroke}
\special{pS: x2 y2 x3 y3 x4 y4 curveto 1 0 0 setrgbcolor stroke}
\special{pS: x1 y1} \special{pS: x2 y2 moveto lineto 1 0 0 setrgbcolor stroke}
\special{pS: x5 y5} \special{pS: x4 y4 moveto lineto 1 0 0 setrgbcolor stroke}
}
\newlength{\wordlength}
\newlength{\wordheight}
\settowidth{\wordlength}{Postscript}
\settoheight{\wordheight}{Postscript}
% This is the part where I am struck
This is an example of what I need to do in my program using Postscript in LaTEX \drawoval{x coordinate of currentpoint}{y coordinate of currentpoint}{\the\wordlength}{\the\wordheight} program
%\drawoval{\special{pS: currentpoint}}
\end{document}
下面的程序可以运行,但是当我尝试多次调用宏 \drawoval 时,会出现错误。请告诉我如何避免这种情况。
\documentclass{article}%%
\usepackage{calc}%%
\begin{document}%%
\makeatletter%%
\def\strippt{\strip@pt}%%
\makeatother%%
\newsavebox\wordbox%%
\newcommand{\drawoval}[1] {%%
\sbox\wordbox{#1}%%
\def\mywidth{\wd\wordbox}%%
\def\myheight{\ht\wordbox}%%
\newcommand\newwidth{\strippt\dimexpr\mywidth+4pt \relax}%%
\newcommand\newwordwidth{\strippt\dimexpr\mywidth+0pt \relax}%%
\newcommand\newheight{\strippt\dimexpr\myheight+6pt \relax}%%
\newcommand\rightpoint{\strippt\dimexpr\mywidth+9pt \relax}%%
\special{" 4 -8 moveto
-2 2 -2 4 4 \newheight\space curveto
\newwordwidth\space 0 rlineto
\newwidth\space -8 moveto
\rightpoint\space 2 \rightpoint\space 4 \newwidth\space \newheight\space curveto
4 -8 moveto
\newwordwidth\space 0 rlineto
1 0 0 setrgbcolor
stroke}
#1
}%%
This is the \drawoval{demo program} of my project%%
\end{document}%%
答案1
由于这是家庭作业,我不会在这里提供完整的答案(也许几周后会安全过去)。但是,我会提供一些有关您的代码的提示。
要点 1:过多的空白
您的解决方案中存在大量多余的空白。特别是空行,将被视为新段落——这可能不是您想要的。所有以控制序列以外的任何内容结尾的行也会产生虚假空白。在每行末尾添加注释以排除空白。不过,行首的空白不是问题。
第 2 点:合法的控制序列名称
控制序列名称不能使用非字母字符来定义。因此,您无法\x1
直接使用 来定义控制序列\newcommand
(有多种方法可以做到这一点,但这里不需要它们)。相反,您可以定义\newcommand\tmpxi
、\newcommand\tmpxii
等等。
第 3 点:\numexpr
vs\dimexpr
\numexpr
只适用于整数值。如果你输入的不是整数,那么它会截断数字。如果你想操纵长度,请使用\dimexpr
。但是,PostScripts 不会期望你输入单位。因此,你需要一种方法来在将长度输入到 PostScript 代码之前将单位从长度中剥离出来。你可以使用\strip@pt
例如,你可能想要定义
\makeatletter
\newcommand\tmpxi{\strip@pt\dimexpr\x-\length}
\makeatother
它们\makeat...
必须能够@
表现得像字母字符(见上面的第 2 点)。
要点 4:获取所需的 PostScript 坐标矩阵
您可能希望使用\special{"
而不是\special{ps:
,以便 PostScript 遵循您想要的长度。请参阅我自己对此有疑问,希望得到解释
第 5 点:控制序列后面的空格
在控制序列之后,空白将被吞噬。这可能会对 PostScript 代码产生意想不到的影响。例如,
\def\tmpxi{10}
\special{"
0 0 moveto
\tmpxi 0 lineto
stroke
}
你会得到一个错误,因为 LaTeX 读取后会将其发送给dvi
驱动程序
0 0 moveto
100 lineto
stroke
为了解决这个问题你可以写
\def\tmpxi{10}
\special{"
0 0 moveto
\tmpxi\space 0 lineto
stroke
}
第 6 点:绝对命令与相对命令
rmoveto
如果你使用相对命令和,那么你可能会更容易一些rlineto
。这样你就不需要太担心在哪里currentpoint
了。
建议 1:保存箱
如果您想要换行某个特定的单词,您可以创建一个命令将该单词保存到一个框中,测量该框的尺寸,然后使用这些尺寸更轻松地计算出在哪里画线。
例如
\newsavebox\mycontentbox
\newcommand\myoval[1]{%%
\sbox\mycontentbox{#1}%%
\def\mywidth{\wd\mycontentbox}%%
...
}
访问尺寸的其他命令是
\dp=depth
\ht=height (above the baseline)
最后结果
坚持这些一般原则,这就是我可以轻松制作的东西(盒子,而不是椭圆形尽管)
最后一点,在我的工作中我从来没有提到过currentpoint
。另外你应该注意到,我没有对盒子本身如何粗鲁地侵占周围空间做出任何纠正。
解决方案
这是一个解决方案。有几点需要注意。首先,我尽量避免创建 LaTeX 宏。它们不是必需的;postscript 可以完成所有必要的算术计算。其次,现在我看到了你整理的更多内容,我会在前言到您的文档,而不是身体。第三,我对背景条纹的创建非常马虎:特别是,我不太注意它们相对于盒子本身的起点和终点。为了使事物终止于我希望它们终止的地方,我创建了路径,然后调用了后记clip
。最后,我在后记代码中定义了几个函数,以使路径代码和条纹代码更易于阅读。
\documentclass{article}
\usepackage[margin=1in]{geometry}
\makeatletter
\newsavebox\myovalbox
\newcommand\myoval[1]{%%
\sbox\myovalbox{#1}%%
\special{"
/mytxtht \strip@pt\ht\myovalbox\space def
/mytxtdp \strip@pt\dp\myovalbox\space def
/mytxtwd \strip@pt\wd\myovalbox\space def
%%
/mytxtboxsep 3 def
/myboxwd { mytxtboxsep dup add mytxtwd add } def
/myboxdp { mytxtboxsep mytxtdp add } def
/myboxht { mytxtboxsep dup add mytxtht mytxtdp add add } def
%%
/myboxhstart { mytxtboxsep neg } def
/myboxvstart { myboxdp neg } def
%%
/myinterstripesep 4 def
/mystripeprotrusion 6 def
/mystriperise { mystripeprotrusion dup add myboxht add } def
/mystriperun 8 def
/mystripebot { mystripeprotrusion myboxdp add neg } def
/mystripestart { mytxtboxsep dup add myinterstripesep add neg } def
/mystripeend { mytxtboxsep myboxwd add} def
%% draw the box
newpath
1 0 0 setrgbcolor
myboxhstart myboxvstart moveto
myboxwd 0 rlineto
0 myboxht rlineto
myboxwd neg 0 rlineto
closepath
clip
%% for loop: start-value increment end-value { iteration action } for
%% the for loop takes the current value of the loop and
%% places it at the beginning of iteration action, hence
%% the "moveto" below appears to only have one argument
mystripestart myinterstripesep mystripeend
{ mystripebot moveto
mystriperun mystriperise rlineto
}
for
stroke
%%
}%%
\usebox{\myovalbox}}
\makeatother
\begin{document}
This is an example of what I need to do in my program using \myoval{Postscript in LaTeX} program.
\end{document}
网上有很多关于 PostScript 编码的资源。在发布的在这个网站. 即,
\def
关于vs 的最后一点\newcommand
也许值得你花点时间仔细阅读以下问题和答案:\def
和有什么区别\newcommand
。很容易误用\def
和破坏基本命令,从而对代码造成灾难性的影响。我自己的方法是使用和\def
来\newcommand
表示\newcommand
我打算在文档(用户界面)级别使用的命令。我使用\def
和来表示使用户级界面执行我想要的操作的底层命令。而且,这个网站上有相当多的人似乎采取这种方法。如果你不确定哪些宏名已经被使用,那么你可以采取以下方法
\newcommand\mymacroname{}
\def\mymacroname{<my real definition>}
这种方法的优点是,如果\mymacroname
已经定义了,则会发出警告,\newcommand
这样您就不会意外地破坏您可能依赖的东西(并且有很多宏是您在不知情的情况下依赖的)。您可能会想,如果我这样做,为什么还要费心使用\def
?好吧,\def
您可以使用非常规方式将参数传递给\newcommand
。有一个包xparse
实际上允许您以比危险性小得多的方式创建这种非常规方法\def
:值得一读。
我使用时做的第二件事\def
是给它提供一个复杂的名称,以明确三件事:(1)我是它的作者,(2)我使用它的目的,(3)它的用途。因此,对于上面的宏\myoval
,我可能有各种宏名称:
\def\ae@boxtext@determine@dimensions#1{....}
其中,ae
表示我是谁、boxtext
表示我使用此命令的目的,并determine@dimensions
说明了该宏应该做什么。
答案2
我可以在这里使用 给出“圆角框问题”的解决方案\pdfliteral
。仅用于与 PostScript 解决方案进行比较。这可以帮助您完成作业,因为您可以看到如何避免使用curveto
运算符的想法。此解决方案只是对我的另一个答案的轻微修改这里
\def\mybox#1{\leavevmode \setbox0=\hbox{#1}%
\edef\posxA{\expandafter\ignorept\the\wd0 \space}%
\hbox{\kern3pt\pdfliteral{q 1 0 0 rg 1 0 0 RG .9963 0 0 .9963 0 0 cm
1 j 6 w 0 0 \posxA 5.5 re B 5 w 1 g 1 G 0 0 \posxA 5.5 re B Q}%
\box0 \kern3pt}%
}
{\lccode`\?=`\p \lccode`\!=`\t \lowercase{\gdef\ignorept#1?!{#1}}}
This is a \mybox{test} of my \mybox{rounded box}.
结果:
主要思想是测量圆角框的宽度并将结果设置为\posxA
(无pt
单位)。运算符.9963 0 0 .9963 0 0 cm
等于 PostScript .9963 .9963 scale
,它将坐标系中的默认 PDF/PostScript 单位(bp
)转换为 TeX 单位(pt
)。然后绘制两个矩形。第一个矩形的轮廓直径为 6 pt(带圆角),颜色为红色。第二个矩形的轮廓直径为 5 pt,颜色为白色。可见结果只有第一个红色矩形的边框,厚度为 0.5pt。
答案3
为了进一步比较,这里有一个使用该gmp
包嵌入 Metapost 图形的解决方案。这里,PostScript 的使用当然完全隐藏在 MP 语言后面,因此它可能不符合 OP 作业要求。
\documentclass{article}
\usepackage[shellescape]{gmp}
\newsavebox{\ringbox}
\newcommand{\ringer}[1]{\sbox\ringbox{#1}%
\lower4pt\hbox to \wd\ringbox
{\hss\smash{\MPring{\mpdim{\wd\ringbox}}{\mpdim{\ht\ringbox}}{red}}\hss}%
\kern -\wd\ringbox \box\ringbox
}
\def\MPring#1#2#3{\begin{mpost}
w := #1; h := #2;
path c; c = quartercircle scaled 4 shifted (w,1.2h)
-- quartercircle scaled 4 rotated 90 shifted (0,1.2h)
-- quartercircle scaled 4 rotated 180 shifted (0,0)
-- quartercircle scaled 4 rotated 270 shifted (w,0)
-- cycle;
for i=-100 upto 100: draw (left--right) scaled w rotated 42 shifted (6i,0)
withcolor #3; endfor; clip currentpicture to c;
draw c withcolor #3;
\end{mpost}}
\begin{document}
In theory, the interrelation of system and/or subsystem technologies must utilize
and be functionally interwoven with the preliminary qualification limit. In
particular, any \ringer{associated supporting element} necessitates that
urgent consideration be applied to possible bidirectional logical
relationship approaches.
\end{document}
有关解释,您可以阅读gmp
CTAN 上的软件包。请注意,由于我使用了shellescape
包选项,因此您需要使用它来编译它pdflatex -shell-escape
。