외부 프로그램을 실행시켜 텍스트를 처리하게 하는 확장 기능. 이 확장 기능은 /매크로모듈화처럼 사용자가 각각의 PlugIn 파일을 추가, 삭제, 수정하여 쉽게 덮어 쓸 수 있다.
{{{#!gnuplot [옵션들...] <-- 한 줄에 오직 이 라인만 있을 것. 플러그인이름은 알파벳,숫자,_ 로만 이뤄짐. 옵션은 공백으로 구분 텍스트 <-- 플러그인이 처리할 텍스트 }}} <-- 역시 한 줄에 이 라인만 있을 것
sub plugin_gnuplot { my ($content, @opt) = @_; # $content 에는 "텍스트"가, @opt 에는 옵션들의 배열이 전달된다. # 외부 프로그램을 사용해서 html 출력을 만들어 반환한다. return "html코드"; } 1; # 마지막에 이 줄이 있어야 한다.
### 패치를 위해 추가된 환경설정 변수 use vars qw( ... $PluginDir $MyPluginDir # 추가 ... ); ###
sub CommonMarkup { my ($text, $useImage, $doLines) = @_; local $_ = $text; if ($doLines < 2) { # 2 = do line-oriented only ############### ### added by gypark ### {{{ }}} 처리 s/(^|\n)\{\{\{[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*\n/&StoreRaw("\n<PRE class=\"code\">") . &StoreCodeRaw($2) . &StoreRaw("\n<\/PRE>") . "\n"/igem; ### 이 줄 추가 s/(^|\n)\{\{\{#!((\w+)( .+)?)[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*\n/$1.&StorePlugin($2,$5)."\n"/igem; ### {{{lang|n|t }}} 처리 s/(^|\n)\{\{\{([a-zA-Z0-9+]+)(\|(n|\d*|n\d+|\d+n))?[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*\n/&StoreRaw("<PRE class=\"syntax\">") . &StoreSyntaxHighlight($2, $4, $5) . &StoreRaw("<\/PRE>") . "\n"/igem; ### ###############
다음 함수 통채로 추가
### 외부 plugin 지원 sub StorePlugin { my ($command, $content) = @_; my $name; my @opt; my $plugin_file = "";; $command = &UnquoteHtmlForPageContent($command); @opt = split (/\s/, $command); $name = shift @opt; my ($PluginDir, $MyPluginDir) = ("./plugin/", "./myplugin/"); if (-f "$MyPluginDir/$name.pl") { $plugin_file = "$MyPluginDir/$name.pl"; } elsif (-f "$PluginDir/$name.pl") { $plugin_file = "$PluginDir/$name.pl"; } if ($plugin_file eq "") { # 플러그인이 없음 return &StoreRaw("\n<PRE class='code'>"). &StoreRaw("\n<font color='red'>No such plugin found: $name</font>\n"). &StoreCodeRaw($content). &StoreRaw("\n<\/PRE>") . "\n"; } my $loadplugin = eval "require '$plugin_file'"; if (not $loadplugin) { # 플러그인 로드에 실패 return &StoreRaw("\n<PRE class='code'>"). &StoreRaw("\n<font color='red'>Failed to load plugin: $name</font>\n"). &StoreCodeRaw($content). &StoreRaw("\n<\/PRE>") . "\n"; } my $func = "plugin_$name"; my $content_unquoted = &UnquoteHtmlForPageContent($content); my $txt = &{\&$func}($content_unquoted, @opt); if (not defined $txt) { # 플러그인이 undef 반환 return &StoreRaw("\n<PRE class='code'>"). &StoreRaw("\n<font color='red'>Error occurred while processing: $name</font>\n"). &StoreCodeRaw($content). &StoreRaw("\n<\/PRE>") . "\n"; } return &StoreRaw($txt); }
sub GetPageLinks { ... $text =~ s/<code>(.|\n)*?\<\/code>/ /ig; ### {{{ }}} 내의 내용은 태그로 간주하지 않음 $text =~ s/(^|\n)(\{\{\{[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*)\n/$1 \n/igm; $text =~ s/(^|\n)(\{\{\{([a-zA-Z0-9+]+)(\|(n|\d*|n\d+|\d+n))?[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*)\n/$1 \n/igm; # 아래 줄 추가 $text =~ s/(^|\n)(\{\{\{#!((\w+)( .+)?)[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*)\n/$1 \n/igm; ### if ($interlink) { ... }
관리자가 페이지 내의 링크를 일괄 변경할 때도 plugin 영역의 내용은 변경하지 않게 한다.
sub SubstituteTextLinks { ... $text =~ s/(<code>((.|\n)*?)<\/code>)/&StoreRaw($1)/ige; $text =~ s/(<nowiki>((.|\n)*?)<\/nowiki>)/&StoreRaw($1)/ige; ############### ### added by gypark ### {{{ }}} 내의 내용은 태그로 간주하지 않음 # 이 아래 처음 두 줄은 조금 수정되었고 세번째 줄 추가됨 $text =~ s/(^|\n)(\{\{\{[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*)\n/$1.&StoreRaw($2)."\n"/igem; $text =~ s/(^|\n)(\{\{\{([a-zA-Z0-9+]+)(\|(n|\d*|n\d+|\d+n))?[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*)\n/$1.&StoreRaw($2)."\n"/igem; $text =~ s/(^|\n)(\{\{\{#!((\w+)( .+)?)[ \t\r\f]*\n((.|\n)*?)\n\}\}\}[ \t\r\f]*)\n/$1.&StoreRaw($2)."\n"/igem; ### ############### ... }
ext1.73b - 플러그인이 에러가 나서 원래 텍스트를 보여 줄 때 부등호 등이 치환되어 버리는 문제를 수정
ext1.74a - 미리보기에서 플러그인이 동작하지 않는 문제 수정 (저장된 텍스트를 읽을 때는 줄바꿈이 \n이지만 textarea에 있는 텍스트를 미리보기에 넘겨줄 때는 줄바꿈이 \r\n임)
ext1.75 - 굳이 사용자가 바꿀 일이 없다고 판단되어서, 플러그인 파일이 들어가는 디렉토리 설정을 config 파일에서 제거함.
ext1.95a - {{{#!...}}} 안의 내용 중에 위키네임이나 이중대괄호쌍이 있더라도 그것을 링크로 취급하지 않게 함. (즉, 역링크 검색이나 전체 링크 출력시 표시되지 않게 함)
ext1.110 - ext1.95a와 같은 맥락으로, 관리자 기능 중 링크 일괄 변경을 할 때도 플러그인 안의 내용은 건드리지 않게 함
다양한 플러그인이 나오기를 기대합니다~ :-)