<?
/**********************************************
* 파일명: plugin.pre.TagComment.php
* 설  명: Comment Template Tag for SkyTemplate
* 버  젼: v1.2.0
* 작성자: 하늘아부지 (daddy@withsky.net)
***********************************************/
/*
    # 목적
        템플릿 파일을 브라우저, Dreamweaver, Namo 등의 프로그램으로 직접 보거나 편집할 경우
        템플릿 태그로 인해 모양이 깨지는 것을 가능한 막기 위해
        <!--{ 또는 }--> 을 적절히 조합하는 작업을 프로그램으로 일괄 처리한다.

    # 주의
        HTML 주석은 가능한 피하고 템플릿 주석을 사용한다.
        tplRewrite==true 일때만 동작한다.
*/

    function TagComment(&$compiler, $var, $all=0, $must="")
    {
        if (!$compiler->tplRewrite) return false;

        $src = &$compiler->Src[$var];

        // 일단 주석을 없애고
		$src = preg_replace(array("/<![-]{2,}".$compiler->dlmQuoted[0]."/", "/".$compiler->dlmQuoted[1]."[-]{2,}>/"), $compiler->dlm, $src); // HTML주석 제거

        // HTML 주석은 템플릿 주석으로 변환
//      $src = str_replace(array("<!--", "-->"), array($compiler->dlm[0]."*", "*".$compiler->dlm[1]), $src);

        // 템플릿 주석
        // 템플릿 변수로 변환
        $tmp = preg_split("/(".$compiler->dlmQuoted[0]."\*|\*".$compiler->dlmQuoted[1].")/", $src, -1, PREG_SPLIT_DELIM_CAPTURE);

		$step = array();
        for ($i=1, $c=count($tmp); $i<$c; $i+=2) {
            if ($tmp[$i] == $compiler->dlm[0]."*") {
                $step[] = $i;
            } else if ($tmp[$i] == "*".$compiler->dlm[1]) {
                if ($step) {
                    $start = array_pop($step);
                    $tmp[$start] = $compiler->dlm[0]."__COMMENT_START__".$compiler->dlm[1];
                    $tmp[$i] = $compiler->dlm[0]."__COMMENT_END__".$compiler->dlm[1];
                }
            }
        }
        $src = implode("", $tmp);

        $arr = array();
        $index = array();
		$quote = false;
		$quoteType = "";
		$bracket = 0;
		$z = 0;
		
        $tmp = preg_split("/(['\\\"]|".$compiler->dlmQuoted[0]."|".$compiler->dlmQuoted[1].")/", $src, -1, PREG_SPLIT_DELIM_CAPTURE);

		$arr[$z] = $tmp[0];
		for ($i=1, $c=count($tmp); $i<$c; $i+=2) {
			switch($token = $tmp[$i]) {
				case '"' :
				case "'" :
					if ($bracket > 0) {
						if (preg_match("/([\\\\]+)$/", $tmp[$i-1], $match)) {
							$escape = (strlen($match[1]) % 2) ? true : false;
						} else {
							$escape = false;
						}
						if ($escape) {
							$arr[$z] .= $token;
							$arr[$z] .= $tmp[$i+1];
						} else {
							if ($quote) {
								if ($quoteType == $token) {
									$quote = false;
									$quoteType = "";
									$arr[$z] .= $token;
									$arr[$z] .= $tmp[$i+1];
								} else {
									$arr[$z] .= $token;
									$arr[$z] .= $tmp[$i+1];
								}
							} else {
								$quote = true;
								$quoteType = $token;
								$arr[$z] .= $token;
								$arr[$z] .= $tmp[$i+1];
							}
						}
					} else {
						$arr[$z] .= $token;
						$arr[$z] .= $tmp[$i+1];
					}
					break;
				case $compiler->dlm[0] :
					if ($quote) {
						$arr[$z] .= $token;
						$arr[$z] .= $tmp[$i+1];
					} else {
						if ($bracket > 0) {
							$bracket++;
							$arr[$z] .= $token;
							$arr[$z] .= $tmp[$i+1];
						} else if ($bracket == 0) {
							$tmpKey = ($compiler->strict) ? $tmp[$i+1] : preg_replace("/(^[\t ]+|[\t ]+$)/", "", $tmp[$i+1]);
							// 명령어 (우선은 명령어인지 아닌지만 체크 ^^:)
							if (preg_match("/^([@%\?:\/\|&#\+\]\\$\\\\!\^]|(=;|=|;)|(LOOP|EACH|IF|ELSE|END|DIVIDE|DIV|REFER|REF|INCLUDE|INC|EXECUTE|EXE|DUMPFILE|DUMP|PHPCODE|PHP|EXPRESSION[;]?|EXP[;]?|ESCAPE|ESC|DEFINE|DEF|COLLECT|COL)([\s]|$))/", $tmpKey)) {
								$bracket++;
								$arr[++$z] = ltrim($tmp[$i+1]);
							} else
							// 변수
							if (preg_match("/^([a-zA-Z0-9_\x7f-\xff]+(\.[0-9]+)?::|[\.])?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\.[a-zA-Z0-9_\x7f-\xff]+)*(->[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\.[a-zA-Z0-9_\x7f-\xff]+)*)?$/", $tmpKey)) {
								if ($all) {
									$arr[$z] .= "<!--".$compiler->dlm[0].$tmp[$i+1].$compiler->dlm[1]."-->";
								} else {
									if (preg_match("/(__COMMENT_START__|__COMMENT_END__)/", $tmp[$i+1]) || ($must && preg_match("/".$must."/", $tmp[$i+1]))) {
										$arr[$z] .= "<!--".$compiler->dlm[0].$tmp[$i+1].$compiler->dlm[1]."-->";
									} else {
										$arr[$z] .= $compiler->dlm[0].$tmp[$i+1].$compiler->dlm[1];
									}
								}
								$arr[$z] .= $tmp[$i+3];
								$i+=2;
							} else
							// 해당사항 없음
							{
								$arr[$z] .= $token;
								$arr[$z] .= $tmp[$i+1];
							}
						} else {
							// error
						}
					}
					break;
				case $compiler->dlm[1] :
					if ($quote) {
						$arr[$z] .= $token;
						$arr[$z] .= $tmp[$i+1];
					} else {
						if ($bracket > 1) {
							$bracket--;
							$arr[$z] .= $token;
							$arr[$z] .= $tmp[$i+1];
						} else if ($bracket == 1) {
							$tmpKey = ltrim($arr[$z]);
							// 블럭형 명령어
							if (preg_match("/^([@%\?:\/\|]|(LOOP|EACH|IF|ELSE|END|DIVIDE|DIV)([\s]|$))/", $tmpKey, $match)) {
								$index[$z] = trim($match[1]);
							} else
							// 템플릿 블럭 모으기
							if (preg_match("/^([\^]|(COLLECT|COL)([\s]|$))/", $tmpKey, $match)) {
								if (strpos($tmpKey, ":")) {
									$index[$z] = trim($match[1]);
								} else {
									$arr[$z] = "<!--".$compiler->dlm[0].$arr[$z].$compiler->dlm[1]."-->";
								}
							} else
							// escape
							if (preg_match("/^(\\\\|(ESCAPE|ESC)([\s]|$))/", $tmpKey, $match)) {
								$arr[$z] = $compiler->dlm[0].$arr[$z].$compiler->dlm[1];
							} else
							// 기타 명령어
							if (preg_match("/^([&#\+\]\$=!]|(=;|=|;)|(REFER|REF|INCLUDE|INC|EXECUTE|EXE|DUMPFILE|DUMP|PHPCODE|PHP|EXPRESSION|EXP|ESCAPE|ESC|DEFINE|DEF)([\s]|$))/", $tmpKey, $match)) {
								$arr[$z] = "<!--".$compiler->dlm[0].$arr[$z].$compiler->dlm[1]."-->";
							}
							$bracket--;
							$arr[++$z] = $tmp[$i+1];
						} else if ($bracket == 0) {
							$arr[$z] .= $token;
							$arr[$z] .= $tmp[$i+1];
						} else {
							// error
						}
					}
					break;
			}
		}
		unset($tmp);

		// Src 흔적만 남김
        $src = true;

        // 블럭형 명령어 처리
        // 모두 주석처리하는 경우($all==true)는 불필요
        if (!$all && $index) {
            $else = array();
            $step = 0;

            foreach ($index as $idx=>$proc) {
				// 루프, if
                if (preg_match("/^([@%\?\|\^]|LOOP|EACH|IF|DIVIDE|DIV|COLLECT|COL)$/", $proc)) {
					$arr[$idx] = "<!--".$compiler->dlm[0].$arr[$idx].$compiler->dlm[1]."-->";
                    $step++;
				} else
                // ELSE : 루프, else, else if
                if (preg_match("/^(:|ELSE)$/", $proc)) {
                    if (!isset($else[$step])) {
                        $else[$step] = $idx;
                        $arr[$idx] = "<!--".$compiler->dlm[0].$arr[$idx].$compiler->dlm[1];
                    } else {
						$arr[$idx] = $compiler->dlm[0].$arr[$idx].$compiler->dlm[1];
					}
				} else
                // END : 주석, 루프, if
                if (preg_match("/^(\/|END)$/", $proc)) {
                    if (isset($else[$step])) {
                        $arr[$idx] = $compiler->dlm[0].$arr[$idx].$compiler->dlm[1]."-->";
						for ($i=$else[$step]+1; $i<$idx; $i+=2) {
                            $arr[$i] = preg_replace("/(<\!--|-->)/", "", $arr[$i]);
                        }
                        unset($else[$step]);
                    } else {
						$arr[$idx] = "<!--".$compiler->dlm[0].$arr[$idx].$compiler->dlm[1]."-->";
					}
                    $step--;
				}
            }
		}
		$src = implode("", $arr);

        // 템플릿 주석 마무리
        $tmp = preg_split("/(<!--".$compiler->dlmQuoted[0]."__COMMENT_START__".$compiler->dlmQuoted[1]."-->|<!--".$compiler->dlmQuoted[0]."__COMMENT_END__".$compiler->dlmQuoted[1]."-->)/", $src, -1, PREG_SPLIT_DELIM_CAPTURE);
		$step = array();
        for ($i=1, $c=count($tmp); $i<$c; $i++) {
            if ($tmp[$i] == "<!--".$compiler->dlm[0]."__COMMENT_START__".$compiler->dlm[1]."-->") {
                $step[] = $i;
            } else if ($tmp[$i] == "<!--".$compiler->dlm[0]."__COMMENT_END__".$compiler->dlm[1]."-->") {
                if ($step) {
                    $start = array_pop($step);
                    if (!$step) {
                        $tmp[$start] = "<!--".$compiler->dlm[0]."*";
                        $tmp[$i] = "*".$compiler->dlm[1]."-->";
                        for ($j=$start+1; $j<$i; $j++) {
                            $tmp[$j] = preg_replace("/(<\!--|-->)/", "", $tmp[$j]);
                        }
                    }
                }
            }
        }
        $src = implode("", $tmp);
        $src = str_replace(array($compiler->dlm[0]."__COMMENT_START__".$compiler->dlm[1], $compiler->dlm[0]."__COMMENT_END__".$compiler->dlm[0]), array($compiler->dlm[0]."*", "*".$compiler->dlm[1]), $src);
    }

?>