Postscript에서의 골프 팁? 고유 한

덜 대중적인 언어 중 하나로서 포스트 스크립트 해커의 전위에 관한 문헌을 찾기가 어렵습니다. 그렇다면 골퍼들은 Postscript의 고유 한 세부 표현을 극복하기 위해 스택 모델 (또는 다른 기능)을 활용하기 위해 어떤 발견을 했습니까?



답변

임베디드 디코더

포스트 스크립트 프로그램에는 고유 한 (?) 기능이있어 자체 프로그램 텍스트를 데이터로 읽을 수 있습니다. 이는 일반적으로 사용되는 image수신 연산자 데이터 수집 – 절차를 입력으로하고,이 과정은 종종 용도 currentfile이어서 readline, readstring또는 readhexstring. 그러나 다른 방법으로 보아도, image또 다른 반복 연산자이므로 모든 루프가 미리 읽을 수 있습니다 . Green Book의 라인 프린터 에뮬레이터를 예로들 수 있습니다.

token연산자를 사용하면 파일이나 문자열에서 스캐너를 호출하여 숫자 나 공백을 제거합니다 (또는 다른 답변 참조)-구분 된 이름.

PS의 간단한 PS 인터프리터 :

{currentfile token not {exit} if dup type /arraytype ne {exec} if }loop

이진 연산자 문자열 디코더

원시 바이너리 토큰 을 얻을 수없는 것처럼 보이므로 (다른 답변 참조) 바이너리 토큰 메커니즘을 이용하여 코드를 8 비트 문자열로 압축하는 “임베디드 디코딩”아이디어를 사용했습니다 문자열 에서 즉시 명령을 조작하고 구문 분석합니다 .

/.{
    <920>  % two-byte binary-encoded name template with 0x92 prefix
    dup 1 4 3 roll put  % insert number into string
    cvx exec  % and execute it
}def
/${
    //.   %the /. procedure body defined above
    73 .  %"forall" (by code number)
}def

.절차는 2 바이트 스트링 스택와 두번째 바이트로서 삽입을 행 번호를 얻어, 실행 시스템의 이름을 지정하는 바이너리 토큰 프리픽스 바이트, 상기 제 1 바이트. 16 진수 문자열의 홀수 개의 니블이 추가 0 니블로 채워지는 스캐너 규칙을 사용하여 16 진 문자열의 바이트를 저장하므로 3 개의 16 진 니블은 2 바이트 문자열을 생성합니다. 그런 다음 문자열을 실행 파일 로 표시 하고 exec호출하여 스캐너를 호출하고 원하는 실행 시스템 이름을 생성 한 다음 이름을로드하고 연산자를 실행합니다. 은 $은 USING, 스택 스트링의 각 바이트에이를 수행 .절차를 두번 루핑 조작을 실행 한 후 일단 루프 체로서, 및 forall숫자로.

보다 간결하게,이 절차는 다음과 같습니다.

 /.{<920>dup 1 4 3 roll put cvx exec}def/${//. 73 .}def
%123457890123456789012345678901234567890123456789012345
%        1         2         3         4         5

따라서 55 문자는 이진 토큰 문자열을 구입합니다. 또는 문자 (당신이 공간을 종료하면 아마 7) 6, 당신은로드 할 수 있습니다에 대한 G 라이브러리(G)run있는 정의 .$상기와 (몇 가지 다른 + 아스키-도달 코드의 범위를 확장하기 위해).

크로스 워드 퍼즐 답변 에 더 자세히 설명되어 있습니다.


답변

그래픽 출력을 생성하고 콘솔 출력은 중요하지 않습니다 때 사용하는 =대신 pop.


답변

16 진 문자열을 ASCII85로 교체

아마 오래된 뉴스이지만 방금 배웠습니다. 🙂

인코딩 필터 및 잘라 내기 및 붙여 넣기와 함께 대화식으로 포스트 스크립트 인터프리터를 사용하여 수행 할 수 있습니다. 그러나 dc“손으로” 하는 방법을 보여 드리겠습니다 .

여기에 16 진 문자열이 있습니다. 우리는 이것을 4 바이트 청크로 나눕니다.

95 20 6e d8   d0 59 49 35   50 74 ba c5   08 2d

dc를 시작하면 32 비트 (부호없는) 빅 엔디안 바이트 순서 번호로 입력합니다. 그런 다음 mod -off base-85 자리수 (0이 될 때까지 5가 있어야 함).

0> dc
16i
95206
일체 포함
d85 % n85 /
82
d85 % n85 /
83
d85 % n85 /
82
d85 % n85 /
78
d85 % n85 /
47
d85 % n85 /
0

마지막 청크를 00 00로 채우면 (소수), 패딩 한 바이트 수를 생략합니다.

47 78 82 83 82   66 81 72 79 83   25 72 82 25 69  2 53 30 [2 53]

인쇄 가능한 ASCII 및 of의 범위로 이동하려면 33을 추가하십시오! ASCII85.

80 111 115 116 115 99 114 105 112 116 58 105 115 58 102 35 86 63 다음
을 디코딩합니다 : Postscript : is : f # V? %%% 죄송합니다! ‘재미’라고 말해야합니다! 나는 어딘가에 망쳤다. 🙂

그것을 감싸면 <~~>레벨 2 Postscript는 16 진수보다 저렴한 8 비트 데이터에 액세스 할 수 있습니다.


답변

간단한 설명은 다음과 같습니다 . [...>>begin키워드를 제거하기 위해 여러 정의를 래핑 합니다 def(nb. [와 동일 <<).

 def def
[>>begin

기억하십시오 : 이상두 … 함께 무리 ! 😉


답변

대부분의 포스트 스크립트 연산자 구문 식별자 (따라서 공간 – (또는 otherwise-이어야 함)로 구분), 이름이지만 [, ], <<, 및 >>자기 구분하고 스캐너 공간을 개입없이 감지합니다. 같은 이유로 일반적인 /literal구문 으로 이러한 이름을 참조 할 수 없습니다 (예 /[: 두 개의 토큰 : 빈 리터럴 이름은에 해당 ()cvn cvlit하고 실행 파일 이름은에 [해당 ([)cvn cvx exec).

이름으로 언급 할 수없는 이러한 이름을 재정의하기 위해 사전에서 키로 사용될 때 암시 적으로 이름으로 변환 된 문자열을 사용할 수 있습니다 (편리한!).

이 예제는 이러한 연산자를 남용하여 산술을 수행하는 것을 보여줍니다.

%!
([)0 def
(])1 def
(<<){add}def
(>>){mul}def
 ]]<<]]]<<<<>> =
%1 1 add 1 1 1 add add mul = %prints 6

또한 <<[(와 mark) 모두 같은 일을 의미한다.


나만의 포스트 스크립트 인터프리터 인 xpost 도 약간의 제한이 있지만 올바른 중괄호를 사용할 수 있습니다. 토론


답변

긴 연산자 이름을 반복해서 사용

이미 <<>>begin사전을 사용중인 경우 /?{}재정의 당 4 자의 상수 오버 헤드가 있습니다. 따라서 길이 n의 N 번 반복 연산자는
(4 + n )-( N * ( n -1)) 의 문자 수 변경을 생성합니다 .

이 공식을 0으로 설정하면 손익 분기점 의 방정식이 제공 됩니다. 이것으로부터 우리는 다른 변수와 관련하여 각 변수에 대해
n =-( N -4) / (1- N ) 및
N = (4 + n ) / ( n -1)을 산출 할 수 있습니다 .

“우리는 얼마나 많은 ‘인쇄’를 사용하는 것이 가치가 있는가?”와 같은 질문에 대답 할 수 없습니다. n = 5이므로 N = 9/4입니다. 인쇄를 1/4 번 효과적으로 호출 할 수 없으므로 천장을 가져옵니다. 따라서 3은 3을 사용합니다. 그리고 실제로,

print print print
/P{print}p p p

(물론 이미 <<>>begin정의를 활성화하는 데 드는 비용을 지불했다고 가정하십시오 ).

물론 이진 토큰은 이런 종류의 똥을 만들어 시스템 이름 테이블에서 처음 255 개의 이름을 2 바이트 (0x92, 0x ??)로 표시합니다. 또한 이진 토큰은 자체적으로 구분되므로 첫 번째 바이트의 높은 비트가 ASCII 범위를 벗어나기 때문에 전후에 공백이 필요하지 않습니다.


답변

이진 토큰

PostScript 프로그램 의 궁극적 인 압축을 위해 최종 프론티어는 더 이상 ASCII 정리 프로그램이 없어도 긴 운영자 이름을 완전히 제거 할 수있는 이진 토큰 입니다.

압축 된 포스트 스크립트 코드 블록으로 시작

[/T[70{R 0 rlineto}48{}49{}43{A rotate}45{A neg rotate}91{currentdict
end[/.[currentpoint matrix currentmatrix]cvx>>begin begin}93{. setmatrix
moveto currentdict end end begin}>>/S{dup B eq{T begin exch{load exec}forall
end}{exch{load exch 1 add S}forall}ifelse 1 sub }>>begin moveto 0 S stroke

PLRM 의 뒷면에있는 모든 이름을 찾습니다 (부록 F, 795-797 페이지).

appearance
in
vim    dec  meaning

<92>   146  'executable system name' binary token prefix
^A     1    add
^M     13   begin
^^     30   currentdict
'      39   currentmatrix
(      40   currentpoint
2      50   cvx
8      56   dup
9      57   end
=      61   eq  !)
>      62   exch
?      63   exec
I      73   forall
U      85   ifelse
d      100  load
h      104  matrix
k      107  moveto
n      110  neg
<85>   133  rlineto
<88>   136  rotate
§      167 stroke
©      169 sub

그런 다음 접두사로 146(소수) 바이트를 입력하십시오. 임의의 바이트를 입력하기위한 vim 도움말

그런 다음 vim에서 압축 파일을 직접 입력 할 수 있습니다.

[/ T [{R 70 0 ^V146 ^V133 48} {49} {43} {A ^V146 ^V136} {A 45 ^V146 ^V110 ^V146 ^V136} 91 { ^V146 ^V30^V 146 ^V57 /. ^V146 ^V40 ^V146 ^V104
^V146 ^V39] ^V146 ^V50 >>
^V146 ^V13 ^V146 ^V13 {93}.
^V146 ^V156
^V146 ^V107 ^V146 ^V30
^V146 ^V57 ^V146 ^V57
^V146 ^V13 >>} / {S ^V146 ^V56 B ^V146 ^V61 {T ^V146 ^V13
^V146 ^V62 { ^V146 ^V100
^V146 ^V63}^V146 ^V73
^V146 ^V57} { ^V146 ^V62 {
^V146 ^V100 ^V146 ^V62

…- ^V62 를 끝내고 1을 시작하려면 여기에 공백을 입력해야 하지만 나중에 백업하고 삭제할 수 있습니다 …

1 개 ^V146 ^V1S} ^V146 ^V73}
^V146 ^V85

…- ^V85 를 끝내고 1을 시작하려면 여기에 공백을 입력해야 하지만 나중에 백업하고 삭제할 수 있습니다 …

1 ^V146 ^V169 >>} ^V146 ^V13
^V146 ^V107

… 3 자리 코드의 3 번째 자리는 바이트 입력을 종료하므로 다음 0은 정상적이고 편리합니다 …

0 S ^V146 ^V167

다음과 같이 화면에 표시됩니다 (vim) :

[/T[70{R 0<92><85>}48{}49{}43{A<92><88>}45{A<92>n<92><88>}
91{<92>^^<92>9[/.[<92>(<92>h<92>']<92>2>>
<92>^M<92>^M}93{.<92><9c><92>k<92>^^<92>9<92>9<92>^M}
>>/S{<92>8B<92>={T<92>^M<92>>{<92>d<92>?}<92>I<92>9}{<92>>
{<92>d<92>>1<92>^AS}<92>I}<92>U1<92>©}>><92>^M
<92>k0 S<92>§

목적이 단지 그림을 보여주는 것이라면 이것은 전적으로 생략 될 수 있습니다. Ghostscript는 필요없이 대부분의 것을 화면에 페인트 showpage합니다.

¡    161   showpage

[ 이것은 실제로 작동하지 않습니다. 고스트 스크립트는 나에게주고 undefined그리고 syntaxerror이러한 토큰. 어쩌면 몇 가지있다 모드 나 활성화해야합니다. ]