출력시 치환되는 매크로들을 모듈 파일로 분리
매크로들이 전부 wiki.pl 안에 들어 있기 때문에, 자신이 따로 수정한 매크로를 사용하는 경우 ext 버전이 업데이트될 때마다 위키 소스를 받아서 다시 해당 매크로를 수정하던가, 반대로 위키 소스를 받아오지 못하고 매번 관련 패치를 직접 적용하던가 해야 되는 불편함이 있어서 나온 패치이다.
이 패치의 목적은
- 매크로를 추가할 때는 해당 매크로 파일만 받아서 설치하면 되고
- 사용하지 않(기를 원하)는 매크로를 제거할 때는 해당 매크로 파일만 삭제하면 되고
- 자신이 기존의 매크로의 동작을 바꾸고 싶을 경우 별도의 매크로 파일을 만드는 것으로도 기존 매크로를 덮어쓰는 것이 가능하게 (따라서, ext 버전이 업데이트되었을 때도 그냥 받아서 덮어쓰면 된다) 하는 것이다.
- 필수 요구 사항: 없음
- 선택 요구 사항: 없음
사용법
위키 홈페이지를 운영하는 입장에서의 매크로 추가, 삭제, 재정의 방법은 UseModWiki매크로를 보라.
매크로 사용법이 달라진 것은 없고, 위키는 다음과 같이 동작한다.
- wiki.pl 의 MacroSubst()는 자체 내장된 매크로들(이런 저런 이유로 분리해 낼 수 없는 것들)을 먼저 실행한다.
- 그 다음, wiki.pl 은 ./macros/ 안에 들어 있는 *.pl 파일들의 목록을 보고 (지원할 매크로, 그 매크로의 실제 구현이 들어 있는 파일)쌍의 목록을 만든다. 파일명에서 확장자를 제외한 부분이 매크로가 된다. (예: mysign.pl 은 mysign 매크로)
- 다시 ./mymacros/ 안에 있는 *.pl 파일들의 목록을 보고 매크로 목록을 갱신한다. macros 와 mymacros 양쪽에 동일한 이름의 파일이 있다면 mymacros 쪽의 파일이 목록에 적힌다. 따라서 사용자가 기존 매크로를 덮어쓸 수 있다. 앞으로 ext 버전이 업그레이드되더라도 mymacros 디렉토리는 항상 비어 있는 채로 제공된다.
- 이렇게 마련된 목록에 대해서, 페이지 본문을 보면서 "&__LT__;매크로이름" 또는 "<매크로이름"이 있는지를 검사한다. (예: <mysign, <date, <datetime 등등...) 해당되는 문자열이 있으면, 그 매크로 파일의 내용을 읽어서 매크로를 실행한다. 즉 해당 페이지를 출력하는 데 필요한 매크로들만 읽어들인다. 따라서 페이지에 사용된 매크로의 종류가 적을 수록 오버헤드가 적다. 그렇지만 대강 시험해 본 바로는 매크로가 전부 wiki.pl 안에 있는 것에 비하면 느려진다. 그래도 무조건 모든 매크로를 읽어 들이는 것보다는 훨씬 낫다. :-)
- 여러 개의 매크로들이 있을 경우 매크로 이름의 알파벳 순서대로 실행된다.
- 자신이 새로운 매크로를 작성하고 싶다면 UseModWiki매크로와, ext 버전에 들어 있는 매크로 파일들의 소스를 참조하라.
아래의 매크로는 따로 분리하지 않았다.
- uploadedfiles,comments,longcomments - 매크로 출력에 있는 submit 버튼을 눌렀을 때 별도의 action 이 실행되어야 하는 매크로들. action 을 분리할 수 없기 때문에 매크로만 분리하는 게 의미가 없어 보임
- include 시리즈, noinclude,/noinclude - include 시리즈 매크로가 wiki.pl 곳곳에 들어 있어서 제거할 수 없고, noinclude 는 include 시리즈와 연관된 것이라서 남겼음.
- memo,/memo - MacroMemo 함수를 다른 곳에서 사용한다.
- trackbacksent, trackbackreceived - 역시 MacroMemo 함수를 재사용하고 trackback 관련 action 이 따로 있기 때문에 분리하지 않았음.
- 그외 저장될 때 치환되는 매크로와 템플릿에 사용되는 매크로들 - 차후에 궁리할 예정
부작용
짐작조차 할 수 없음. -_-; 현재까지는 이전 방식과 완전히 동일한 출력을 보여주고는 있는데...
- 기존에는 wiki.pl 에 나열된 순서대로 매크로들이 동작했지만, 이제는 알파벳 순서대로 (예: allpagesfrom, allpagesto, anchor, ..., wikiversion) 실행된다. 즉 두 개 이상의 매크로가 서로 예기치 않은 간섭을 할 수 있다. 사실 순서란게 의미가 없지만, 아예 아무 기준없이 예측불허로 실행되는 것보다는 낫다 싶어서 알파벳 순서로 실행하게 하였다.
- 예전에 새로운 매크로를 만들면서, 매크로 함수(Macro...로 시작하는)내에서 사용하기 위해서 다른 함수를 만든 것들이 있는데, 그런 함수들을 골라내기 힘들어서 분리하지 못했다. 만일 그런 경우에 해당되는 매크로 파일을 지워버릴 경우는 분리하지 못한 함수는 불필요하게 들어간 셈인데... 이건 큰 문제는 되지 않을 듯.
wiki.pl 수정
다음 환경변수 추가
use vars qw(
...
$MacrosDir $MyMacrosDir
);
다음 전역변수 추가
use vars qw(%RevisionTs $FS_lt $FS_gt $StartTime $Sec_Revision $Sec_Ts
... # <-- 이 자리에 있던 $MyFootnoteCounter $MyFootnotes 는 매크로가 분리되면서 그쪽으로 넘어갔다. 삭제
%MacroFile);
MacroSubst() 함수를 왕창 뜯어고친다.
sub MacroSubst {
my ($txt) = @_;
$txt =~ s/(\&__LT__;uploadedfiles\&__GT__;)/&MacroUploadedFiles($1)/gei;
$txt =~ s/(\&__LT__;comments\(([^,]+),([-+]?\d+)\)&__GT__;)/&MacroComments($1,$2,$3)/gei;
$txt =~ s/\&__LT__;(\/)?noinclude\&__GT__;//gei;
$txt =~ s/(\&__LT__;longcomments\(([^,]+),([-+]?\d+)\)&__GT__;)/&MacroComments($1,$2,$3,1)/gei;
$MemoID = 0;
$txt =~ s/(&__LT__;memo\(([^\n]+?)\)&__GT__;((.)*?)&__LT__;\/memo&__GT__;)/&MacroMemo($1, $2, $3)/geis;
$txt =~ s/(((^|\n)\* .*)*\n?)(&__LT__;trackbacksent&__GT__;)/&MacroTrackbackSent($4,$1)/gei;
$txt =~ s/(((^|\n)\* .*\n\*\* .*\n\*\* .*)*\n?)(&__LT__;trackbackreceived&__GT__;)/&MacroTrackbackReceived($4,$1)/gei;
my $macroname;
my ($MacrosDir, $MyMacrosDir) = ("./macros/", "./mymacros/");
foreach my $dir ($MacrosDir, $MyMacrosDir) {
foreach my $macrofile (glob("$dir/*.pl")) {
if ($macrofile =~ m|$dir/([^/]*).pl|) {
$macroname = $1;
$MacroFile{"$macroname"} = $macrofile;
}
}
}
foreach my $macro (sort keys %MacroFile) {
if ($txt =~ /(&__LT__;|<)$macro/i) {
require "$MacroFile{$macro}";
$txt = &{\&$macro}($txt);
}
}
return $txt;
}
이제, 위 MacroSubst 에 들어 있지 않은 매크로들의 실제 구현 부분은 지워 버린다. :-)
sub MacroColor { ... }
sub MacroColorBk { ... }
sub MacroFootnote { ... }
sub MacroMyInterest { ... }
sub MacroMostPopular { ... }
sub MacroEDic { ... }
sub MacroKDic { ... }
sub MacroJDic { ... }
sub MacroUserList { ... }
sub MacroWantedPages { ... }
sub MacroOrphanedPages { ... }
sub MacroAllPagesFrom { ... }
sub MacroAllPagesTo { ... }
sub MacroVote { ... }
sub MacroMySign { ... }
sub MacroCalendar { ... }
sub MacroWikiVersion { ... }
sub MacroHistory { ... }
sub MacroGoto { ... }
sub MacroTitleSearch { ... }
sub MacroFullSearch() }
sub MacroDate() { ... }
sub MacroTime() { ... }
sub MacroDateTime() { ... }
sub MacroAnchor() { ... }
sub MacroPageCount() { ... }
sub MacroRandom() { ... }
macros/매크로.pl 파일들 추가
wiki.pl 에서 지운 매크로들을 별도의 파일로 $MacrosDir로 지정된 디렉토리에 추가해 준다. /Download에서 최신 버전의 ext 버전을 받아 압축을 풀면 들어 있다.
추가 업데이트 내역
ext1.63a - 매크로 파일을 읽을 때 do 대신 require 사용하도록 수정. do 는 호출시마다 파일을 읽고 require 는 처음 호출될 때 한번만 읽는다고 하여서 바꿨음. 사실 여기서는 어차피 각 매크로 파일을 읽는 것은 단 한번만 이뤄지기 때문에 차이가 없고, 나중에 오히려 do 를 써야만 되도록 수정될 가능성도 있음.. (한 마디로, 주인장도 잘 모르면서 바꿨단 얘기 -_-;) 각 매크로 파일 마지막에 "1;"이 들어가야만 한다.
ext1.66a - 어떤 매크로를 불러올지 판단할 때, "&__LT__;매크로이름"만 검사하던 것을 "<매크로이름"도 같이 검사하게 하였음. (따라서 위키 매크로가 아닌 html태그도 매크로로 덮어 쓸 수 있음)
ext1.75 - 굳이 사용자가 바꿀 일이 없다고 판단되어서, 매크로 파일이 들어가는 디렉토리 (macros, mymacros) 를 config 파일에서 제거함.
ext1.78 - 매크로를 읽고 실행하는 부분을 단순화. UseModWiki매크로의 매크로 제작법이 좀 더 간단해짐.
사용자 의견
wiki.pl 의 용량을 꽤 줄일 수 있다고 생각했는데 막상 지워봐도 20KB 정도밖에 안 주는군요. -.-;;;
흐음, 위에 do 명령으로 매크로를 부르는 것을 require 로 부르도록 고칠까 하는데 두 명령의 정확한 차이점을 아시는 분?
위키위키분류