인디자인으로 평범한 단행본 작업을 하면 본문 시안을 만들기 전에 거의 예외 없이 해야 하는 것들이 있다. 판형을 정하고, 판면을 설정한다. 판면을 설정하는 방식은 디자이너에 따라 다르겠지만, 나는 행의 수와 폰트 크기, 글줄 사이 값을 정한 뒤 여백을 분별하는 쪽을 선호한다. 그러고 나면 본문 폰트와 자간 등 본문 스타일을 설정한다. 들여쓰기 값, 격자 정렬, GREP 스타일 설정 등은 대체로 뒤따르는 루틴이다. 그리고 빼놓을 수 없는 것이 페이지 번호를 넣는 것이다. 마스터 페이지 한편에 텍스트 프레임을 만들고, [현재 페이지 번호]1를 삽입하는 작업은 페이지 번호를 임의로 넣지 않는 책인 경우가 아니라면, 반드시 거쳐야 할 과정이다.
고작 텍스트 프레임에 페이지 번호 넣는 게 뭐가 그렇게 대수냐고, 콕 꼬집는지 싶을 것이다. 서두가 길었지만 이제 그걸 클릭 한번으로 할 수 있게 만들고 싶어서다. 사실 나처럼 초보 스크립터에게 중요한 기준은 ‘오, 이거 해볼만 할 거 같은데?’와 같은 대상의 만만함(혹은 만만해보임)이다. 대상이 너무 복잡해서, 난이도가 급격하게 올라가면 풀리지 않는 오류 앞에서 쉽게 좌절할 게 분명하다. 그리고 그와 유사하게 중요한 건 스크립트로 만들려는 대상이 거의 예외 없이 혹은 많이 실행되는지와 같은 보편성의 여부다. 지엽적인 쓸모도 쓸모겠지만, 굳이 그 좁은 경우를 위해 머리를 쥐어 뜯으며 고민할 필요는 적은 것이다.
- [CP]스크립트 설치하기 ← 설치하는 법을 모르겠다면 참고!
코드 해설
‘페이지번호_만들기.jsx’는 일단 문서 여백을 정하는 등의 초기 작업을 마친 상태를 가정한다. 문서를 하나 이상 열라는 경고를 만들면 좋았겠지만 스크립터 역량 상의 한계로 인디자인 자체 오류로 갈음한다(나중에 고치게 되면 업데이트를 하겠다)…. 어쨌든 문서가 안 열려 있으면 오류 창이 뜰 것이다. 그게 인디자인 자체 오류다.
var doc = app.activeDocument;
var pageHeight = doc.documentPreferences.pageHeight;
var pageWidth = doc.documentPreferences.pageWidth;
var m1 = doc.pages[-1].marginPreferences;
var m2 = doc.pages[0].marginPreferences;
몇가지 변수를 선언한다. doc은 현재 활성화된 문서(app.activeDocument;)를, pageHeight는 현재 활성화된 문서의 페이지 높이(doc.documentPreferences.pageHeight;)다. pageWidth는 마찬가지로 현재 활성화된 문서의 너비(doc.documentPreferences.pageWidth)다. m1과 m2는 각각 이전 페이지(doc.pages[-1])와 현재 페이지(doc.pages[0])의 여백 설정 정보에 대한 것이다.
app.doScript(function() {
var master1 = doc.masterSpreads.item(0).pages.item(0).textFrames.add();
master1.geometricBounds = [pageHeight-m1.bottom, m1.right, pageHeight, pageWidth-m1.left];
master1.contents = SpecialCharacters.AUTO_PAGE_NUMBER;
master1.textFramePreferences.verticalJustification = VerticalJustification.CENTER_ALIGN;
with(master1.paragraphs.everyItem()) {
justification = Justification.AWAY_FROM_BINDING_SIDE;
appliedFont = "Garamond Premier Pro";
fontStyle = "Regular";
pointSize = "10pt";
}
doScript는 어플리케이션(app)의 메소드인데, 말 그대로 스크립트를 실행하게 한다. 메소드 괄호에 여러 가지 요소가 들어가는데, 첫 번째는 함수, 두 번째는 사용 언어, 세 번째는 배열, 네 번째는 어떻게 스크립트를 끌 것인지, 다섯 번째는 스크립트를 끄는 것의 이름인데, 다섯 번째는 생략해도 실행에 문제가 없다. 아직 함수가 어떻게 제대로 돌아가는지 확실히 깨닫지 못해서 일전에 차용한 적 있는 doScript 구문을 이용했다. 이것 덕분에 실행취소를 하면 스크립트 이전 상태로 깔끔하게 돌아갈 수 있다.
master1이라는 변수는 마스터 스프레드의 첫 페이지, 즉 왼쪽 면(doc.masterSpreads.item(0).pages.item(0))에 텍스트 프레임을 추가하겠다(textFrames.add();)는 선언이다. 다음 geometricBounds(가 조금 머리가 아팠는데, geometricBounds는 속성인데, 텍스트 프레임의 좌표를 설정할 수 있게 해준다. 페이지 번호가 입력될 텍스트 프레임의 좌표 네 개를 각각 [위, 왼쪽, 아래, 오른쪽] 순으로 구해야 한다. 위에서 굳이 페이지 높이와 여백 값을 변수로 선언한 게 아니다. 그걸 더하고 빼는 식으로 산수를 해야 좌표가 구해지기 때문이다. 페이지 번호가 입력될 텍스트 프레임은 거의 웬만하면 하단부에 위치한다. 일단 그걸 가정하고 판면 바로 아래 여백만큼 차지 하는 텍스트 프레임을 만들기로 했다. 그렇다면 ‘위’는 페이지 높이에서 아랫 여백을 뺀 값(pageHeight-m1.bottom)이 된다. 왼쪽은 오른쪽(바깥쪽) 여백 자체 값(m1.right),아래는 페이지 높이 자체 값(pageHeight), 오른쪽은 페이지 너비에서 왼쪽(안쪽) 여백을 뺀 값(pageWidth-m1.left)이 된다. 사실 이렇게 깔끔하게 구해진 건 절대 아니고 정말 헷갈려서 이상한 산수놀음만 하다가 얼레벌레 맞춘 격이었다.
다음은 그렇게 얹은 텍스트 프레임에 내용을 채우는 속성이다(master1.contents). [현재 페이지 번호]에 해당하는 특수 문자로 설정해줬다(SpecialCharacters.AUTO_PAGE_NUMBER;). 그리고 텍스트 프레임의 세로 정렬(master1.textFramePreferences.verticalJustification)을 가운데로 해줬다(VerticalJustification.CENTER_ALIGN;).
그 다음에는 텍스트 프레임 내용으로 들어가는 단락에 대한 설정이다(with(master1.paragraphs.everyItem()) {). with문은 일정 부분 중첩되는 속성에 대해서 깔끔하게 식을 짤 수 있게 해준다. 단락의 정렬은 ‘제본 영역 반대 방향으로 정렬(justification = Justification.AWAY_FROM_BINDING_SIDE;)’, 폰트는 가장 무난한 가라몬드 레귤러 10pt로 설정했다(appliedFont = "Garamond Premier Pro"; fontStyle = "Regular"; pointSize = "10pt").
var master2 = doc.masterSpreads.item(0).pages.item(1).textFrames.add();
master2.geometricBounds = [pageHeight-m2.bottom, pageWidth+m2.left, pageHeight, pageWidth*2-m2.right];
master2.contents = SpecialCharacters.AUTO_PAGE_NUMBER;
master2.textFramePreferences.verticalJustification = VerticalJustification.CENTER_ALIGN;
with(master2.paragraphs.everyItem()) {
justification = Justification.AWAY_FROM_BINDING_SIDE;
appliedFont = "Garamond Premier Pro";
fontStyle = "Regular";
pointSize = "10pt";
}
master2는 오른쪽 페이지에 똑같이 텍스트 프레임을 만드는 설정이기에, master1과 거의 다른 게 없다. 설정하는 페이지와(pages.item(1)) 텍스트 프레임을 얹을 좌표가 달라진다([pageHeight-m2.bottom, pageWidth+m2.left, pageHeight, pageWidth*2-m2.right];). 그 외에는 모든 설정이 같다.
}, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT);
이제 함수를 닫고 app.doScript의 나머지 부분을 적어주면 된다. 스크립트 언어는 자바스크립트이고, 배열은 미정(undefined), 종료 모드는 전체 스크립트를 종료하는 것(ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT);)으로 설정했다.
이렇게 얼레벌레 스크립트 하나를 만들어서 해설까지 해봤다. 뒤늦게 발견되는 아쉬운 점들이 적잖이 있지만, 능력 부족으로 고치지 못하는 게 슬프다. 하지만 계속 훌륭한 남이 적어 놓은 것들에 집착하다보면 새로 보이는 게 있을 거라 생각한다.
1 인디자인 인터페이스 상으로는 [문자] → [특수 문자 삽입] → [표시자] → [현재 페이지 번호]를 따른다. 인디자인에 조금이라도 익숙한 사용자라면 맥 OS 기준 cmd+opt+shift+N 단축키로 기억해놓고 있을 것이다.