-
2006/09/17 12:26 오후 #1997
워드프레스의 code 태그 기능이 소스를 표현하기에 부적당한것 같아서 dp.SyntaxHighlighter를 적용했습니다. dp.SyntaxHighlighter는 제 블로그에 쓴 글처럼 소스 등을 보기 좋게 해주는 것인데, 포스팅 내용에 <textarea name="code" … >와 </textarea> 사이의 내용을 자스를 통해 변환시켜줍니다.
그런데 그냥 textarea를 하니 function-formatting.php에 있는 autop()함수에 의해 글을 뿌려주면서 자동으로 p 와 br 태그를 덧붙여버리더군요. 그래서 아래와 같이 플러그인을 제작해봤습니다.
if (!function_exists('clean_textarea')) {
function clean_textarea($text) {
$text = str_replace('<br />', '', $text);
$text = str_replace('<p>', "n", $text);
$text = str_replace('</p>', '', $text);
return $text;
}
}if (!function_exists('convert_textarea')) {
function convert_textarea($pee) {
$pee = preg_replace('!(<textarea name="code.*?>)(.*?)</textarea>!ise', " stripslashes('$1') . stripslashes(clean_textarea('$2')) . '</textarea>' ", $pee);
return $pee;
}
}add_action('init', 'clean_textarea');
add_action('init', 'convert_textarea');
add_filter('the_content', 'convert_textarea');근데 문제는 clean_textarea() 함수에서 p와 br태그를 제거하도록 했는데, 문제는 소스중에 p나 br이 포함되어 있더라도 그냥 제거해버리는 것 같습니다. 제 생각엔 autop()함수에 의해 추가된 p나 br 태그만 제거하도록 하면 될 것 같은데, 어떤 방법이 없을까요?
아래는 제가 참고한 function-formatting.php에 있는 autop()함수와 그와 관련해서 clean_pre()함수의 내용입니다. 참고로 같이 올려봤습니다.
function clean_pre($text) {
$text = str_replace('<br />', '', $text);
$text = str_replace('<p>', "n", $text);
$text = str_replace('</p>', '', $text);
return $text;
}function wpautop($pee, $br = 1) {
$pee = $pee // . "n"; // just to make things a little easier, pad the end
$pee = preg_replace('|<br />s*<br />|', "nn", $pee);
// Space things out a little
$pee = preg_replace('!(<(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)!', "n$1", $pee);
$pee = preg_replace('!(</(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])>)!', "$1nn", $pee);
$pee = str_replace(array("rn", "r"), "n", $pee); // cross-platform newlines
$pee = preg_replace("/nn+/", "nn", $pee); // take care of duplicates
$pee = preg_replace('/n?(.+?)(?:ns*n|z)/s', "<p>$1</p>n", $pee); // make paragraphs, including one at the end
$pee = preg_replace('|<p>s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
$pee = preg_replace('!<p>s*(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|hr|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)s*</p>!', "$1", $pee); // don't pee all over a tag
$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
$pee = preg_replace('!<p>s*(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|hr|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)!', "$1", $pee);
$pee = preg_replace('!(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)s*</p>!', "$1", $pee);
if ($br) $pee = preg_replace('|(?<!<br />)s*n|', "<br />n", $pee); // optionally make line breaks
$pee = preg_replace('!(</?(?:table|thead|tfoot|caption|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)s*<br />!', "$1", $pee);
$pee = preg_replace('!<br />(s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)!', '$1', $pee);
$pee = preg_replace('!(<pre.*?>)(.*?)</pre>!ise', " stripslashes('$1') . stripslashes(clean_pre('$2')) . '</pre>' ", $pee);
return $pee;
}ps : 코드 부분 때문에 폭이 너무 넓어져서 읽기가 어렵게 돼버렸습니다. 보기좋게 해야되는데, 중간에 엔터로 구분을 하니 코드 해독이 난이해질 수 있을 것 같아 그냥 뒀습니다. 죄송합니다.
2006/09/17 12:26 오후 #2001워드프레스의 code 태그 기능이 소스를 표현하기에 부적당한것 같아서 dp.SyntaxHighlighter를 적용했습니다. dp.SyntaxHighlighter는 제 블로그에 쓴 글처럼 소스 등을 보기 좋게 해주는 것인데, 포스팅 내용에 <textarea name="code" … >와 </textarea> 사이의 내용을 자스를 통해 변환시켜줍니다.
그런데 그냥 textarea를 하니 function-formatting.php에 있는 autop()함수에 의해 글을 뿌려주면서 자동으로 p 와 br 태그를 덧붙여버리더군요. 그래서 아래와 같이 플러그인을 제작해봤습니다.
if (!function_exists('clean_textarea')) {
function clean_textarea($text) {
$text = str_replace('<br />', '', $text);
$text = str_replace('<p>', "n", $text);
$text = str_replace('</p>', '', $text);
return $text;
}
}if (!function_exists('convert_textarea')) {
function convert_textarea($pee) {
$pee = preg_replace('!(<textarea name="code.*?>)(.*?)</textarea>!ise', " stripslashes('$1') . stripslashes(clean_textarea('$2')) . '</textarea>' ", $pee);
return $pee;
}
}add_action('init', 'clean_textarea');
add_action('init', 'convert_textarea');
add_filter('the_content', 'convert_textarea');근데 문제는 clean_textarea() 함수에서 p와 br태그를 제거하도록 했는데, 문제는 소스중에 p나 br이 포함되어 있더라도 그냥 제거해버리는 것 같습니다. 제 생각엔 autop()함수에 의해 추가된 p나 br 태그만 제거하도록 하면 될 것 같은데, 어떤 방법이 없을까요?
아래는 제가 참고한 function-formatting.php에 있는 autop()함수와 그와 관련해서 clean_pre()함수의 내용입니다. 참고로 같이 올려봤습니다.
function clean_pre($text) {
$text = str_replace('<br />', '', $text);
$text = str_replace('<p>', "n", $text);
$text = str_replace('</p>', '', $text);
return $text;
}function wpautop($pee, $br = 1) {
$pee = $pee // . "n"; // just to make things a little easier, pad the end
$pee = preg_replace('|<br />s*<br />|', "nn", $pee);
// Space things out a little
$pee = preg_replace('!(<(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)!', "n$1", $pee);
$pee = preg_replace('!(</(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])>)!', "$1nn", $pee);
$pee = str_replace(array("rn", "r"), "n", $pee); // cross-platform newlines
$pee = preg_replace("/nn+/", "nn", $pee); // take care of duplicates
$pee = preg_replace('/n?(.+?)(?:ns*n|z)/s', "<p>$1</p>n", $pee); // make paragraphs, including one at the end
$pee = preg_replace('|<p>s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
$pee = preg_replace('!<p>s*(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|hr|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)s*</p>!', "$1", $pee); // don't pee all over a tag
$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
$pee = preg_replace('!<p>s*(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|hr|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)!', "$1", $pee);
$pee = preg_replace('!(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)s*</p>!', "$1", $pee);
if ($br) $pee = preg_replace('|(?<!<br />)s*n|', "<br />n", $pee); // optionally make line breaks
$pee = preg_replace('!(</?(?:table|thead|tfoot|caption|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)s*<br />!', "$1", $pee);
$pee = preg_replace('!<br />(s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)!', '$1', $pee);
$pee = preg_replace('!(<pre.*?>)(.*?)</pre>!ise', " stripslashes('$1') . stripslashes(clean_pre('$2')) . '</pre>' ", $pee);
return $pee;
}ps : 코드 부분 때문에 폭이 너무 넓어져서 읽기가 어렵게 돼버렸습니다. 보기좋게 해야되는데, 중간에 엔터로 구분을 하니 코드 해독이 난이해질 수 있을 것 같아 그냥 뒀습니다. 죄송합니다.
2006/09/20 2:42 오전 #1998autop 문제는 해결하기가 참 난감한 문제더군요. 지금까지 제 나름대로의 해결법은 필터(apply_filter)기능을 사용하는 플러그인들의 우선순의를 조절하는것과, 치환하는 함수에 줄건너뛰기(n)를 넣는 방법이었습니다.
하지만 이 경우는 본문이 완전히 로딩된 후에 자바스크립트를 이용해 내용을 치환하기 때문에 다른 해결법을 취해야 할 듯 하네요. (자바스크립트가 꺼진 브라우저에서는 어떻게 표현 되나요??)
잠깐 생각이 드는 방법은 autop 필터가 적용되기 전에 본문 중 textarea부분을 살짝 빼 놓았다가, autop가 적용된 이후에 다시 치환하는것인데… 좀 복잡해 질것같은 예감이 엄습하는군요.
Array 속성을 가진 변수를 하나 만들어서 function 1() 에서 불러와서 autop가 적용되기 전에 값들을 저장 해 놓은 다음, autop가 적용된 이후에 그 변수를 불러와서 function 2()에서 다시 치환하는거죠.
$myTextArea_Codes = array();
$textarea_replace_count = 0;function get_codes_before_autop($text){
$text = preg_replace('preg', 'replace_codes_before_autop('1')', $text);
return $text;
}function replace_codes_before_autop($code){
global $myTextArea_Codes, $textarea_replace_count, $post;
$myTextArea_Codes[] = $code;
$new_code = "<p>[textareacode:".$post->ID."-".$textarea_replace_count."]</p>";
$textarea_replace_count++;
return $new_code;
}function restore_after_autop($text){
global $myTextArea_Codes, $post;
preg_match_all('preg', $text, $match);
$match = $match[0];
foreach(.....){
내용들....
}
}add_filter('the_content', 'get_codes_before_autop', 0);
add_filter('the_content', 'restore_after_autop', 20);
얼추 이런식의 생각인데… 근거가 아예 없지는 않지만, 테스트 해 본게 아니라서 적용 가능할지는 확실치 않은데다… 좀 억지스러움이 물씬 풍기기 때문에 추천할 만한 방법은 아니네요… ^^;
preg_replace방식이기때문에… 따옴표나 역슬래쉬()에 대한 대책들도 포함되어야 할겁니다.
autop와 관련해서 다른 경험을 가진 분께서 또 다른 방법을 제시해주시면 좋겠네요.
참… 어떤 플러그인에서는 autop필터를 제거했다가 다시 추가하는 방법을 쓰기도 하더군요.(찾아보니 extreme video 플러그인 이었네요)
if(function_exists('wpautop')){
remove_filter('the_content','wpautop');
add_filter('the_content','wpautop',8);
}
2006/09/20 2:42 오전 #2002autop 문제는 해결하기가 참 난감한 문제더군요. 지금까지 제 나름대로의 해결법은 필터(apply_filter)기능을 사용하는 플러그인들의 우선순의를 조절하는것과, 치환하는 함수에 줄건너뛰기(n)를 넣는 방법이었습니다.
하지만 이 경우는 본문이 완전히 로딩된 후에 자바스크립트를 이용해 내용을 치환하기 때문에 다른 해결법을 취해야 할 듯 하네요. (자바스크립트가 꺼진 브라우저에서는 어떻게 표현 되나요??)
잠깐 생각이 드는 방법은 autop 필터가 적용되기 전에 본문 중 textarea부분을 살짝 빼 놓았다가, autop가 적용된 이후에 다시 치환하는것인데… 좀 복잡해 질것같은 예감이 엄습하는군요.
Array 속성을 가진 변수를 하나 만들어서 function 1() 에서 불러와서 autop가 적용되기 전에 값들을 저장 해 놓은 다음, autop가 적용된 이후에 그 변수를 불러와서 function 2()에서 다시 치환하는거죠.
$myTextArea_Codes = array();
$textarea_replace_count = 0;function get_codes_before_autop($text){
$text = preg_replace('preg', 'replace_codes_before_autop('1')', $text);
return $text;
}function replace_codes_before_autop($code){
global $myTextArea_Codes, $textarea_replace_count, $post;
$myTextArea_Codes[] = $code;
$new_code = "<p>[textareacode:".$post->ID."-".$textarea_replace_count."]</p>";
$textarea_replace_count++;
return $new_code;
}function restore_after_autop($text){
global $myTextArea_Codes, $post;
preg_match_all('preg', $text, $match);
$match = $match[0];
foreach(.....){
내용들....
}
}add_filter('the_content', 'get_codes_before_autop', 0);
add_filter('the_content', 'restore_after_autop', 20);
얼추 이런식의 생각인데… 근거가 아예 없지는 않지만, 테스트 해 본게 아니라서 적용 가능할지는 확실치 않은데다… 좀 억지스러움이 물씬 풍기기 때문에 추천할 만한 방법은 아니네요… ^^;
preg_replace방식이기때문에… 따옴표나 역슬래쉬()에 대한 대책들도 포함되어야 할겁니다.
autop와 관련해서 다른 경험을 가진 분께서 또 다른 방법을 제시해주시면 좋겠네요.
참… 어떤 플러그인에서는 autop필터를 제거했다가 다시 추가하는 방법을 쓰기도 하더군요.(찾아보니 extreme video 플러그인 이었네요)
if(function_exists('wpautop')){
remove_filter('the_content','wpautop');
add_filter('the_content','wpautop',8);
}
2006/09/22 12:12 오전 #2000음… 오늘 다시 이 글을 보면서 생각난게 있어서 적어봅니다.
위의 내용보다는 좀 더 간단하게 처리 할 수도 있는 방법입니다.
function Pass_AutoP_Codes($text) {
preg_match_all('/(<textarea(.*?)name="code(.*?)>(.*?)</textarea>)/ise', $text, $match);
$match = $match[0];
$codes = array();
if(!empty($match)) {//textarea 코드부분이 있으면 잠시 바꿔놓습니다.
for($i=0; $i<count($match); $i++) {
//autop에서 <p>태그를 추가하지 않도록 <p>를 넣어놓습니다.
$text = str_replace($match[$i], '<p>[textarea:'.$i.']</p>', $text);
$codes[] = $match[$i];
}
}
//autop를 적용합니다.
$text = wpautop($text);
if(!empty($codes)) {//autop 처리 후 다시 원래의 코드를 넣습니다.
for($i=0; $i<count($codes); $i++) {
$text = str_replace('<p>[textarea:'.$i.']</p>', $codes[$i], $text);
}
}
return $text;
}remove_filter('the_content', 'wpautop');
remove_filter('the_excerpt', 'wpautop');
remove_filter('comment_text', 'wpautop');add_filter('the_content', 'Pass_AutoP_Codes');
add_filter('the_excerpt', 'Pass_AutoP_Codes');
add_filter('comment_text', 'Pass_AutoP_Codes');Pass_AutoP_Codes라는 이름은 임의로 넣은것입니다.
제가 preg 관련 함수와 정규식에대한 지식이 없어서 찾을 preg 부분에 확신이 없군요. 잘 아시는 분께서 보완해 주시면 좋겠습니다.2006/09/22 12:12 오전 #2004음… 오늘 다시 이 글을 보면서 생각난게 있어서 적어봅니다.
위의 내용보다는 좀 더 간단하게 처리 할 수도 있는 방법입니다.
function Pass_AutoP_Codes($text) {
preg_match_all('/(<textarea(.*?)name="code(.*?)>(.*?)</textarea>)/ise', $text, $match);
$match = $match[0];
$codes = array();
if(!empty($match)) {//textarea 코드부분이 있으면 잠시 바꿔놓습니다.
for($i=0; $i<count($match); $i++) {
//autop에서 <p>태그를 추가하지 않도록 <p>를 넣어놓습니다.
$text = str_replace($match[$i], '<p>[textarea:'.$i.']</p>', $text);
$codes[] = $match[$i];
}
}
//autop를 적용합니다.
$text = wpautop($text);
if(!empty($codes)) {//autop 처리 후 다시 원래의 코드를 넣습니다.
for($i=0; $i<count($codes); $i++) {
$text = str_replace('<p>[textarea:'.$i.']</p>', $codes[$i], $text);
}
}
return $text;
}remove_filter('the_content', 'wpautop');
remove_filter('the_excerpt', 'wpautop');
remove_filter('comment_text', 'wpautop');add_filter('the_content', 'Pass_AutoP_Codes');
add_filter('the_excerpt', 'Pass_AutoP_Codes');
add_filter('comment_text', 'Pass_AutoP_Codes');Pass_AutoP_Codes라는 이름은 임의로 넣은것입니다.
제가 preg 관련 함수와 정규식에대한 지식이 없어서 찾을 preg 부분에 확신이 없군요. 잘 아시는 분께서 보완해 주시면 좋겠습니다. -
AuthorPosts
- 답변은 로그인 후 가능합니다.