[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7. 입력 제어

이 장에서는 다양한 내장 매크로를 사용하여 입력을 제어하는 방법을 설명하겠다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1 입력에서 공백문자 제거하기

내장 매크로인 dnl은 모든 문자를 읽어들여서 취소해버리고 첫 번째 뉴라인 문자만 포함한다.

 
dnl

dnl은 종종 아래의 같은 define 호출시 뉴라인 문자를 제거하기 위해서 연결하여 사용한다.

 
define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
foo
⇒Macro foo.

dnl 다음의 모든 문자들과 다음 뉴라인 문자가 취소된다. 이것은 마치 주석으로 취급하는 것과 비슷하다 (see section 주석).

보통, dnl은 라인의 끝이나 어떤 다른 공백문자 다음에 바로 따라온다. GNU m4dnl이 열린괄호 다음에 따라온다면 경고메시지를 발송한다. 이 경우에 dnl은 모든 인자들을 수집하여 처리할 것이고, 매칭되는 닫는괄호를 찾을 것이 다. dnl은 출력되지 않는다. dnl은 닫는 괄호 다음부터 다음 뉴라인 문자가 나 올 때 까지 취소할 것이다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.2 인용 문자 바꾸기

기본적인 인용문자는 changequote를 사용하여 바꿀 수 있다.

 
changequote(opt start, opt end)

여기에서 start는 인용구의 시작을 알리는 새로운 구분자이고 end는 그 끝을 알리는 구분자이다. 인자가 빠지거나 잘못되었다면 기본으로 `'이 사용된 다.

changequote는 확장되지 않는다.

 
changequote([, ])
⇒
define([foo], [Macro [foo].])
⇒
foo
⇒Macro foo.

인용문자로 하나의 글자가 적당하지 않다면 어떠한 길이의 문자열로 사용해도 된다.

 
changequote([[, ]])
⇒
define([[foo]], [[Macro [[[foo]]].]])
⇒
foo
⇒Macro [foo].

인용문자를 빈 문자열로 지정한다면 인용 메카니즘을 사용할 수 없으며, 텍스트를 인용할 방법이 없어진다.

 
define(`foo', `Macro `FOO'.')
⇒
changequote(, )
⇒
foo
⇒Macro `FOO'.
`foo'
⇒`Macro `FOO'.'

m4에서 왼쪽 인용문자와 매치되지 않는 것을 포함하는 문자열을 인용할 방법 이 없다. 현재의 인용문자를 changequote로 변경하는 경우를 제외한다면…

인용할 때의 시작문자를 ‘_’(밑줄문자)로 절대 하지 말아야 한다. 그러면 입력 에서 명칭을 사용할 수 없을 것이다. 이것은 때로는 인용 메카니즘을 불가능하 게 만들 수 도 있음을 알아야 한다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3 주석 구분자 변경하기

기본적으로 주석 구분자는 내장 매크로 changecom을 사용하여 변경할 수 있다.

 
changecom(opt start, opt end)

start는 새로운 주석 구분자의 시작 문자열이고 end는 끝 구분자이다. 인자를 지정하지 않는다면 기본 주석 구분자로 #과 뉴라인 문자가 사용된다. 주석 구분 자의 길이에는 제한이 없다.

changecom은 확장되지 않는다.

 
define(`comment', `COMMENT')
⇒
# A normal comment
⇒# A normal comment
changecom(`/*', `*/')
⇒
# Not a comment anymore
⇒# Not a COMMENT anymore
But: /* this is a comment now */ while this is not a comment
⇒But: /* this is a comment now */ while this is not a COMMENT

주석안에 있는 인용 문자열도 주석으로 처리되어서 그대로 출력으로 복사된다. 만일 주석안의 텍스트를 확장하고 싶으면 주석 구분자의 시작을 인용문자로 적어라.

changecom을 아무런 인자 없이 호출한다면 주석 매카니즘은 사용 불가능 하게 된다.

 
define(`comment', `COMMENT')
⇒
changecom
⇒
# Not a comment anymore
⇒# Not a COMMENT anymore

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.4 단어의 어휘 구조 바꾸기

changeword는 시험적인 기능이다. 이 기능은 GNU m4 를 컴파일 할 적에 configure 스크립트에 –enable-changeword 옵션을 사용함으로서만 사용가능하다. 이 기능은 변경되거나 멀지 않은 미래에 없어질 것이다. changeword에 의지 하지 마라.

파일이 m4에 의해서 처리될 적에 그것은 인용된 문자열, 단어(잠재적인 매크 로 이름), 간단한 토큰(그외의 다른 하나의 문자)로 분리된다. 단어는 다음의 정규 표현식으로 정의된다.

 
[_a-zA-Z][_a-zA-Z0-9]*

changeword를 사용한다면 이러한 정규 표현식을 바꿀 수 있다. 맥빠지게 하는 m4 의 어휘규칙은 숫자로 된 파일을 번역하는 데 적용할 때에는 유용할 것이 다.

 
changeword(`[_a-zA-Z0-9]+')
define(1, 0)
⇒1

어휘규칙에 얽매이는 것은 그다지 유용하지 못하다. 왜냐하면 자칫하면 내장 매크로를 사용 할 수 없을 지도 모르기 때문이다. 따라서 우연하게 내장 매크로 를 호출하게 되는 경우는 방지할 수 있다. 예를 들면,

 
define(`_indir', defn(`indir'))
changeword(`_[_a-zA-Z0-9]*')
esyscmd(foo)
_indir(`esyscmd', `ls')

m4는 한꺼번에 단어를 문자로 만들기 때문에, changeword에게 건네지는 정규표현식에는 제한이 있다. 만일 여러분들의 시스템에서 정규 표현식이 ‘foo’와 같은 것을 허용한다면 ‘f’와 ‘fo’도 허용되어야 한다.

changeword는 또다른 기능을 가지고 있다. 정규표현식이 보조표현식을 괄호 로 묶는 것을 제공한다면, 이것의 처음 택스트 바깥쪽은 심볼을 찾기전에 취소된 다. 그래서..

 
changecom(`/*', `*/')
changeword(`#\([_a-zA-Z0-9]*\)')
#esyscmd(ls)

m4는 이제 모든 매크로 호출 이전에 ‘#’ 표시를 하도록 요구한다. 그래서 이것은 m4 를, 받아들여진 명령들을 shift 함이 없이 전처리 셀 스크립트로 사용할 수 있다. 이렇게 하여도 텍스트는 다양한 공통되는 단어를 잃어버리지 않을 것 이다.

TeX이 토큰에 기초한다면 m4의 매크로 치환은 텍스트에 기초한다. changeword는 이러한 차이점에서 오는 걱정을 없앨 수 있다. 예를 든다면 TeX과 m4에서 똑같이 재연되는 것을 다음에 보여주겠다. 먼저, TeX 버전:

 
\def\a{\message{Hello}}
\catcode`\@=0
\catcode`\\=12
⇒@a
⇒@bye

다음은 m4 버젼:

 
define(a, `errprint(`Hello')')
changeword(`@\([_a-zA-Z0-9]*\)')
⇒@a

TeX의 예에서, 첫 번째 라인은 a 매크로가 ‘Hello’ 메시지를 출력하도록 정의 하였다. 두 번째 라인은 <@>을 <\> 대신에 이스케이프 문자로 편리하게 사용할 수 있도록 정의하였다. 세 번째 라인은 <\> 를 이스케이프 문자가 아닌 일반적인 프린팅 가능한 문자로 정의하였다. 네 번째 라인은 매크로 a를 불러들이는 것이다. 따라서 TeX이 이 파일에서 실행될 때 ‘Hello’ 메시지를 보여줄 것이다.

위의 m4의 예제를 실행한다면 ‘errprint(Hello)’를 출력할 것이다. 그 이유는 TeX은 매크로가 정의되었을 때에는 정의된 매크로 어휘 분석을 하기 때문이다. m4는 텍스트를 저장하고, 어휘 분석을 매크로가 사용될 때까지 보류한다.

changeword를 사용하면 m4가 7가지 요인에 의해서 천천히 다운되어 갈 수 있음을 잊지말자.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.5 입력을 저장하기

m4 에서는 보통의 입력이 끝날 때까지의 텍스트를 저장하는 것이 가능하다. 텍 스트는 저장되고, 보통의 입력이 다 되었을 때 다시 읽어들이는 것이 가능하다. 이 특징은 정상적인 종료를 하기전에 임시 파일을 없앤다던지 하는 청소 작업을 초기화 하는 데 사용된다.

입력 텍스트를 저장하려면, 내장 매크로인 m4wrap을 사용하면 된다.

 
m4wrap(string, ...)

string과 나머지 인자는 안전한 장소에 저장되고, 입력이 다 찼을 때 다시 읽혀진다.

 
define(`cleanup', `This is the `cleanup' actions.
')
⇒
m4wrap(`cleanup')
⇒
This is the first and last normal input line.
⇒This is the first and last normal input line.
^D
⇒This is the cleanup actions.

저장된 입력은 보통의 입력이 끝났을 때와, m4를 종료하기 위해서 m4exit를 사용하지 않을 때에만 다시 읽혀진다.

저장된 텍스트를 m4wrap으로 호출하는 것은 안전하긴 하지만, 저장된 텍스트 를 다시 읽어들이는 순서는 정의되지 않았다. m4wrap이 재귀적으로 사용되지 않는다면, 저장된 텍스트의 조각은 저장된 반대 순서로 읽혀진다 (LIFO-last in, first out).


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Autobuild on February 7, 2019 using texi2html 1.82.