我有一个接受文本输入的后记代码。我想在文本达到特定长度时对其进行换行或添加省略号,但我不知道该怎么做。
%%% A4 size
<< /PageSize [595 842] >> setpagedevice
clippath pathbbox /ury exch def /urx exch def /lly exch def /llx exch def
%%% Unit
/cm { 72 2.54 div mul } bind def
%%% Temporary
/Fix_long 4.2 cm def
/Fix_short 3.2 cm def
%%% Set Image Scale
/SetFixScale { 2 copy gt { Fix_long Fix_short }{ Fix_short Fix_long }ifelse scale } bind def
%%% Set put coordinate
/SetXAdjust { 2 copy gt
{ X_Step Fix_long sub 2 div floor }
{ Fix_long Fix_short sub 2 div} ifelse /XAdjust exch def
} bind def
/YAdjust 2 cm def
%%% Temporary
/Row 4 def
/Column 3 def
/X_Step urx llx sub Row div floor def
/Y_Step ury lly sub Column div floor def
/Row_pos 0 def
/Column_pos 1 def
/SetPutPosition {
llx X_Step Row_pos mul add
ury Y_Step Column_pos mul sub translate
DrawFrame
DrawFileName
XAdjust YAdjust translate
Row 1 sub Row_pos eq { /Row_pos 0 def /Column_pos Column_pos 1 add def }{ /Row_pos Row_pos 1 add def } ifelse
Column_pos Column gt { /Column_pos 1 def } if
} bind def
/DrawFrame { gsave .5 setlinewidth 0 0 X_Step Y_Step rectstroke grestore } bind def
/DrawFileName { 15 15 moveto 4 -1 roll show } bind def
在/DrwaFileName 部分,我想将文本换行/剪切并添加省略号。我该怎么做?有这个功能吗?
最佳答案
没有内置函数可以实现此目的,因此您必须进行一些字符串处理。至少有两种方法,具体取决于您想要如何测量“长度”。
对于更简单的情况,我们将“长度”视为字符数。 postscript 运算符length
将返回字符串中的字符数。所以从你的功能开始,
/DrawFileName { 15 15 moveto 4 -1 roll show } bind def
% ^
% we'll insert our code here, ---------|
% where the string is on top of the stack,
% replacing the call to show
首先检查现有长度与我们允许的最大大小。
dup length 10 gt {
}{
show
} ifelse
如果长度不大于 10,则 else 子句仅调用 show。接下来我们将填写 then 子句来修剪字符串。
dup length 10 gt {
0 10 getinterval
show
}{
show
} ifelse
嗯,我本来不想谈论优化,但我们现在可以考虑这一点。在添加省略号部分之前。两种情况都会调用 show
,因此我们只需在 ifelse
结构之外调用一次即可。
dup length 10 gt {
0 10 getinterval
}{
} ifelse
show
当然,现在我们不需要 ifelse
因为 else 子句是空的。
dup length 10 gt {
0 10 getinterval
} if
show
这样更好。现在,对于省略号,我们可以使用 putinterval
运算符将一个字符串复制到另一个字符串。
dup length 10 gt {
0 10 getinterval
dup 7 (...) putinterval
} if
show
编辑:当然,由于 postscript 是一种图形语言,我们可能会对字符串在页面上的排版长度感兴趣。为此,有一个 stringwidth
运算符,它返回调用 show
后 currentpoint
将移动的量。因此,如果您只是将 show
调用替换为 stringwidth rmoveto
,它将留下适当大小的间隙,但不会设置任何文本。因此,回到开头,替换对 show
的调用,即。假设在代码片段开头的堆栈顶部有一个字符串。
dup stringwidth pop 50 gt {
} if
show
对于西方字母,stringwidth
返回的 dy 值将始终为 0。由于上下文是文件名,因此这似乎是一个安全的假设。因此,我们只需弹出
它并将dx结果与50个用户空间点进行比较。
现在,如果太长怎么办?在哪里进行切割?这是值得思考的事情。做出一个思考的表情。哼。如果我们考虑到我们还要在此处添加省略号,那么我们希望从字段宽度中减去它,并将字符串截断到其左侧。因此,我的计划是逐个字符地循环字符串并检查并显示每个字符,将省略号字符串留在堆栈上以供最终的显示
。这是部分填写。
dup stringwidth pop 50 gt { % str
50 (...) stringwidth pop sub % str Max new maximum length
exch % Max str
{ % Max c forall yields the integer value
( ) dup 0 4 3 roll put % Max (c) put it back in a string
dup stringwidth pop % Max (c) dx
2 index 2 copy lt % Max (c) dx Max dx<Max?
{ % Max (c) dx Max dx<Max
}{ % Max (c) dx Max dx>=Max
} ifelse
} forall
(...)
} if
show
循环遍历每个字符,检查字符串宽度,与最大值进行比较。如果小于最大值,我们要继续显示字符串,并从最大值中减去宽度。 如果没有,我们要清理堆栈并退出循环。
dup stringwidth pop 50 gt { % str
50 (...) stringwidth pop sub % str Max new maximum length
exch % Max str
{ % Max c forall yields the integer value
( ) dup 0 4 3 roll put % Max (c) put it back in a string
dup stringwidth pop % Max (c) dx
2 index 2 copy lt % Max (c) dx Max dx<Max?
{ % Max (c) dx Max dx<Max
exch sub % Max (c) Max-dx
3 1 roll exch pop % Max-dx (c)
show % Max-dx
}{ % Max (c) dx Max dx>=Max
pop pop pop pop exit
} ifelse
} forall
(...) % place (...) on stack for show
} if
show
我认为这应该可以完成工作。
为了换行文本,我们已经把自己逼到了一个角落。字符串的其余部分需要通过剩余的迭代来收集,然后重新组装成一个字符串,然后再重新进行整个困惑。让我想一下。 ...
或者它可以将当前点重新定位在循环的中间。使用 X 坐标和 Y 增量(或者实际上是减量,因为我们可能正在向下移动页面)。类似的东西
currentpoint exch pop % currentY
X exch % X currentY
dY sub % X currentY-dY
moveto
关于postscript - 如何使用 postscript 在文本上换行或添加省略号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26457871/