#---------------------------------------------------------------------------------
#  KTMarkDown
#   Copyright (C) 2012 : Kengo Tsuruzono / crane@sitearo.com All Rights Reserved.
	$ver = 'version 1.0.0b1';
#---------------------------------------------------------------------------------

	### OUTPUT ONE LINE TEXT ###

	sub outputTextToFile {

		my( $textSrc ) = @_;

		### [ << ] -> &lt;
		while( $textSrc =~ /^(.*?)\<\<(.*?)$/ ) { 
			$textSrc = $1.'&lt;'.$2;
		}

		### [ >> ] -> &gt;
		while( $textSrc =~ /^(.*?)\>\>(.*?)$/ ) { 
			$textSrc = $1.'&gt;'.$2;
		}
		
		### ESCAPE : バックスラッシュの後の文字はそのまま出力
		my $textDst = '';

		while( $textSrc =~ /^(.*?)\\(.)(.*?)$/ ) { 
			$textSrc = $3;
			$textDst .= $1.$2;
		}
		$textDst .= $textSrc;
		
		print DST_FILE $textDst."\n";

	}


	sub outputStartTagToFile {

		my( $tagName, $tagAttr, $className ) = @_;
		my $addClass = '';
		my $addStyle = '';

		if ( $tagAttr =~ /^(.*?)\{(.*?)\}(.*?)$/ ) { # { CSS }
			$addStyle = $2;
			$tagAttr = $1.$3;
		}

		if ( $tagAttr =~ /^(.*?)\"(.+?)\"(.*?)$/ ) { # " CLASS "
			$addClass = $2;
			$tagAttr = $1.$3;
		}

		# CREATE LINECLASS
		if    ( $tagAttr =~ /^(\d*?)\,\:/ ) { # (((N,:
			if ( 0 == length( $1 ) ) { $className = $className.'2 outShadow';   } # (((,:  > 2o
			else                     { $className = $className.$1.' outShadow'; } # (((N,: > No
		} # (((,: > 2o
		elsif ( $tagAttr =~ /^(\d*?)\'\:/ ) {  # (((N':
			if ( 0 == length( $1 ) ) { $className = $className.'2 inShadow';   } # (((':  > 2i
			else                     { $className = $className.$1.' inShadow'; } # (((N': > 3i
		}
		elsif ( $tagAttr =~ /^(\d*?)\:/ ) {  # (((N:
			if ( 0 == length( $1 ) ) { $className = $className.'2'; } # (((:  > 2
			else                     { $className = $className.$1;  } # (((N: > N
		}
		elsif ( $tagAttr =~ /^\,/   ) { $className = $className.'1 outShadow'; } # (((, > 1o
		elsif ( $tagAttr =~ /^\'/   ) { $className = $className.'1 inShadow';  } # (((` > 1i
		else { $className = $className.'1'; } # (((
		
		if ( 0 < length( $addClass ) ) {
			$className = $className.' '.$addClass;
		}
		
		# CREATE TAG
		my $tag = "<$tagName class='$className'";
		if ( 0 < length( $addStyle ) ) { $tag .= " style='$addStyle'"; }
		print DST_FILE $tag.">\n";	
	
	}



	### MAIN ROUTINE ###

	$gSrcFile	= shift @ARGV;

	if ( $gSrcFile =~ /^(.*?)\.txt/i ) {
		$gDstFile = $1.'.html';
	}
	else {
		$gDstFile = $gSrcFile.'.html';
	}

	print STDERR   "===== KTMarkDown =====\n";
	print STDERR   "$ver \n";
	print STDERR   "SRC : $gSrcFile \n";
	print STDERR   "DST : $gDstFile \n";
	print STDERR   "----------------------\n";

	open SRC_FILE, $gSrcFile;
	open DST_FILE, ">$gDstFile";


	$openPg		= 0;		# <p>の後なら 1
	$listIndent	= 0;		# ul/olインデントの深さ
	@listTag	= ();		# ul/olのネスト状態を記憶
	$inPre		= 0;		# <pre>の中なら 1
	$inTbl		= 0;		# <table>の中なら 1
	$inNop		= 0;		# 無加工エリアの中なら 1

	while( <SRC_FILE> ) {

		$lineText  = $_;
		$lineText  =~ s/(\r|\n)//g;		# 改行削除
		
		if ( length( $lineText ) == 0 ) { # BRANK LINE
			print DST_FILE "\n";
			next; 
		}
		
		$lineClass = '';				# 行修飾クラス
		$lineStyle = '';				# 行修飾クリア
		$lineTag   = 'p';				# 行タグ



		##### NOP AREA #####

		### START NOP AREA : >>>>>
		if ( $lineText =~ /^\>\>\>\>\>/ ) {
			$inNop = 1;
			next;
		}

		### END NOP AREA : <<<<<
		if ( $lineText =~ /^\<\<\<\<\</ ) {
			$inNop = 0;
			next;
		}

		### NO TOUCH TEXT
		if ( $inNop == 1 ) {
			print DST_FILE $lineText."\n";
			next;
		}



		##### CLEAR LIST INDENT #####
		# 行頭に * or # がない場合は、インデントを0に戻す
		if ( $lineText =~ /^\s*([\*\+]+)(.*)$/ ) {
		} else {
			while ( 0 < $listIndent ) {
				print DST_FILE pop( @listTag );
				$listIndent--;
			}
		}



		##### CLOSE TABLE #####
		# 行頭に | がない場合は、テーブルを閉じる
		if ( $inTbl == 1 ) {
			if ( $lineText =~ /^\|/ ) { # 行頭の縦棒がないときは閉じる
			} else {
				print DST_FILE "</table>\n";
				$inTbl = 0;
			}
		}



		##### PREFIX #####

		### START PREFIX <pre> : 行頭 [[[
		if ( $lineText =~ /^\[\[\[(.*?)$/ ) {
			$attr = $1;
			&outputStartTagToFile( 'pre', $attr, 'type_' );
			$inPre = 1;
			next;
		}

		### プレフィックス終了 </pre> : 行頭 ]]]
		if ( $lineText =~ /^\]\]\]/ ) {
			print DST_FILE "</pre>\n";
			$inPre = 0;
			next;
		}



		##### 文字修飾 #####


		##### 基本修飾

		### 太字 : ''STRING''
		while( $lineText =~ /^(.*?)\'\'(.*?)\'\'(.*?)$/ ) { 
			$lineText = $1.'<b>'.$2.'</b>'.$3;
		}

		### 斜体字 : //STRING//
		while( $lineText =~ /^(.*?)\/\/(.*?)\/\/(.*?)$/ ) { 
			$lineText = $1.'<i>'.$2.'</i>'.$3;
		}

		### 等幅文字 : [[STRING]]
		while( $lineText =~ /^(.*?)\[\[(.*?)\]\](.*?)$/ ) { 
			$lineText = $1.'<span class="text_mono">'.$2.'</span>'.$3;
		}


		##### 下線

		while( $lineText =~ /^(.*?)__(.*?)__(.*?)$/ ) { 

			$head = $1;
			$body = $2;
			$foot = $3;
			
			if ( $body =~ /^\:(.*)$/ ) { # __:STRING__
				$textClass = 'txt_uline_2';
				$body = $1;
			} 
			elsif ( $body =~ /^(\d*?)\:(.*)$/ ) { # __N:STRING__
				$textClass = 'txt_uline_'.$1;
				$body = $2;
			}
			else { # __STRING__
				$textClass = 'txt_uline_1';
			}

			$lineText = $head.'<span class="'.$textClass.'">'.$body.'</span>'.$foot;

		}


		##### 丸囲い

		while( $lineText =~ /^(.*?)\(\((.*?)\)\)(.*?)$/ ) { 

			$head = $1;
			$body = $2;
			$foot = $3;
			
			if ( $body =~ /^\,\:(.*)$/ ) { 				# ((,:STRING)) > 2o
				$textClass = 'outShadow txt_rbox_2';
				$body = $1;
			} elsif ( $body =~ /^\,(.*)$/ ) {			# ((,STRING)) > 1o
				$textClass = 'outShadow txt_rbox_1';
				$body = $1;
			} elsif ( $body =~ /^\:(.*)$/ ) {			# ((:STRING)) > 2
				$textClass = 'txt_rbox_2';
				$body = $1;
			} elsif ( $body =~ /^(\d*?)\,\:(.*)$/ ) { 	# ((N,:STRING)) > No
				$textClass = 'outShadow txt_rbox_'.$1;
				$body = $2;
			} elsif ( $body =~ /^(\d*?)\:(.*)$/ ) {		# ((N:STRING)) > N
				$textClass = 'txt_rbox_'.$1;
				$body = $2;
			} else {									# ((STRING)) > 1
				$textClass = 'txt_rbox_1';
			}

			$lineText = $head.'<span class="'.$textClass.'">'.$body.'</span>'.$foot;

		}


		##### 角囲い

		while( $lineText =~ /^(.*?)\(\[(.*?)\]\)(.*?)$/ ) { 

			$head = $1;
			$body = $2;
			$foot = $3;
			
			if ( $body =~ /^\,\:(.*)$/ ) { 				# ([,:STRING]) > 2o
				$textClass = 'outShadow txt_box_2';
				$body = $1;
			} elsif ( $body =~ /^\,(.*)$/ ) {			# ([,STRING]) > 1o
				$textClass = 'outShadow txt_box_1';
				$body = $1;
			} elsif ( $body =~ /^\:(.*)$/ ) {			# ([:STRING]) > 2
				$textClass = 'txt_box_2';
				$body = $1;
			} elsif ( $body =~ /^(\d*?)\,\:(.*)$/ ) { 	# ([N,:STRING]) > No
				$textClass = 'outShadow txt_box_'.$1;
				$body = $2;
			} elsif ( $body =~ /^(\d*?)\:(.*)$/ ) {		# ([N:STRING]) > N
				$textClass = 'txt_box_'.$1;
				$body = $2;
			} else {									# ([STRING]) > 1
				$textClass = 'txt_box_1';
			}

			$lineText = $head.'<span class="'.$textClass.'">'.$body.'</span>'.$foot;

		}


		##### シャドウ

		### シャドウ n
		while( $lineText =~ /^(.*?)\`\`(.*?):(.*?)\`\`(.*?)$/ ) { 
			$tail = $2;
			if ( 0 == length( $tail ) ) { $tail = '2'; }
			$lineText = $1.'<span class="txt_shd_'.$tail.'">'.$3.'</span>'.$4;
		}

		### シャドウ1
		while( $lineText =~ /^(.*?)\`\`\:(.*?)\`\`(.*?)$/ ) { 
			$lineText = $1.'<span class="txt_shd_1">'.$2.'</span>'.$3;
		}

		### シャドウ2
		while( $lineText =~ /^(.*?)\`\`\;(.*?)\`\`(.*?)$/ ) { 
			$lineText = $1.'<span class="text_shadow3">'.$2.'</span>'.$3;
		}

		### シャドウ3
		while( $lineText =~ /^(.*?)\`\`(.*?)\`\`(.*?)$/ ) { 
			$lineText = $1.'<span class="text_shadow1">'.$2.'</span>'.$3;
		}



		##### CSS

		### クラス指定 : ""CLASS:STRING""
		while( $lineText =~ /^(.*?)\"\"(.+?)\|(.*?)\"\"(.*?)$/ ) { 
			$lineText = $1."<span class='$2'>".$3.'</span>'.$4;
		}

		### CSS指定 : {{CSS:STRING}}
		while( $lineText =~ /^(.*?)\{\{(.+?)\|(.*?)\}\}(.*?)$/ ) { 
			$lineText = $1."<span style='$2'>".$3.'</span>'.$4;
		}



		##### <pre>の中の場合は以下の処理はしない #####
		if ( $inPre == 1 ) { 
			&outputTextToFile( $lineText );
			next;
		}
		###



		##### IMAGE
		
		# [img.POS (ALT) "URL">→ <div style='float:POS;'><img alt="ALT" src="URL"></div>
		while( $lineText =~ /^(.*?)\[img\.(left|right).*?\((.*?)\).*?\"(.+?)\".*?\](.*?)$/ ) { 
			$lineText = $1.'<div style="float:'.$2.';"><img alt="'.$3.'" src="'.$4.'"></div>'.$5;
		}

		# [img.POS "URL">→ <div style='float:POS;'><img alt="" src="URL"></div>
		while( $lineText =~ /^(.*?)\[img\.(left|right).*?\"(.+?)\".*?\](.*?)$/ ) { 
			$lineText = $1.'<div style="float:'.$2.';"><img alt="" src="'.$3.'"></div>'.$4;
		}

		# [img (ALT) "URL"]→ <img alt="ALT" src="URL">
		while( $lineText =~ /^(.*?)\[img.*?\((.*?)\) \"(.+?)\".*?\](.*?)$/ ) { 
			$lineText = $1.'<img alt="'.$2.'" src="'.$3.'">'.$4;
		}

		# [img "URL"]→ [img alt="" src=URL]
		while( $lineText =~ /^(.*?)\[img.*?\"(.+?)\".*?\](.*?)$/ ) { 
			$lineText = $1.'<img alt="" src="'.$2.'">'.$3;
		}



		##### LINK
		# [a (説明) "URL"]→ <a href="URL">説明</a>
		while( $lineText =~ /^(.*?)\[a.*?\((.*?)\) \"(.+?)\".*?\](.*?)$/ ) { 
			$lineText = $1.'<a href="'.$3.'">'.$2.'</a>'.$4;
		}

		########## 行修飾

		##### 角囲い
		if ( $lineText =~ /^\(\(\[(.*?)$/ ) {
			$attr = $1;
			&outputStartTagToFile( 'div', $attr, 'blk_box_' );
			next;
		}

		##### 丸囲い
		if ( $lineText =~ /^\(\(\((.*?)$/ ) {
			$attr = $1;
			&outputStartTagToFile( 'div', $attr, 'blk_rbox_' );
			next;
		}

		### 行頭 ))) : 囲い終了
		if ( $lineText =~ /^[\)\]]\)\)/ ) {
			print DST_FILE "</div>\n";
			next;
		}



		### START BLOCKQUOTE
		if ( $lineText =~ /^\(\[\[(.*?)$/ ) {
			$attr = $1;
			&outputStartTagToFile( 'blockquote', $attr, 'type_' );
			next;
		}

		### END BLOCKQUOTE
		if ( $lineText =~ /^\]\]\)(.*?)$/ ) {
			print DST_FILE "</blockquote>\n";
			next;
		}


		### CLEAR FLOAT : 行頭 ///
		if ( $lineText =~ /^\/\/\// ) {
			print DST_FILE "<div style='clear:both;'></div>\n";
			next;
		}


		##### HORIZONTAL LINE

		### 行頭 --- → <hr> 実線
		if ( $lineText =~ /^---(.*)/ ) {
			$attr = $1;
			&outputStartTagToFile( 'hr', $attr, 'type_' );
			next;
		}

		### 行頭 --- → <hr> 実線
		if ( $lineText =~ /^---(.*)/ ) {

			$attr = $1;
			$attr =~ /(.)(.*)/;

			$type = $1;
			$attr = $2;

			if    ( $type eq ':' ) { $lineClass = 'dotted'; }
			elsif ( $type eq ';' ) { $lineClass = 'dashed'; }
			else                   { $lineClass = '';       }

			if ( $attr =~ /(\#...)/   ) { $lineStyle .= "border-color:$1;"; }	# #COLOR
			if ( $attr =~ /\{(.*?)\}/ ) { $lineStyle .= $1; }					# { CSS }
			if ( $attr =~ /\"(.*?)\"/ ) { $lineClass  = $1; }					# " CLASS "

			if    (( 0 <  length( $lineClass ) )&&( 0 <  length( $lineStyle ) )) {
				print DST_FILE "<hr class='$lineClass' style='$lineStyle'>\n";
			}
			elsif (( 0 <  length( $lineClass ) )&&( 0 == length( $lineStyle ) )) {
				print DST_FILE "<hr class='$lineClass'>\n";
			}
			elsif (( 0 == length( $lineClass ) )&&( 0 <  length( $lineStyle ) )) {
				print DST_FILE "<hr style='$lineStyle'>\n";
			}
			else {
				print DST_FILE "<hr>\n";
			}

			next;
		}


		##### 改ページ
		### 行頭 === → 改ページ
		if ( $lineText =~ /^===/ ) {
			print DST_FILE "<p style=\"page-break-before: always;\"></p>";
			next;
		}



		##### 行修飾 #####

		### ヘッダー : 行頭 ! <hn>
		if ( $lineText =~ /^(\#+)\,(.*)$/ ) { # WITH SHADOW
			$cnt = length( $1 );
			$lineTag    = "h$cnt";
			$lineClass .= ' outShadow';
			$lineText   = $2;
			
			print STDERR "$1 $2\n";
		}
		elsif ( $lineText =~ /^(\#+)(.*)$/ ) { # NO SHADOW
			$cnt = length( $1 );
			$lineTag = "h$cnt";
			$lineText = $2;

			print STDERR "$1 $2\n";
		}

		##### 揃え

		### 両端揃え : 行頭 ::::
		if ( $lineText =~ /^\:\:\:\:(.+)$/ ) {
			$lineStyle .= "text-align: justify;";
			$lineText = $1;
		}

		### 右揃え : 行頭 :::
		if ( $lineText =~ /^\:\:\:(.+)$/ ) {
			$lineStyle .= "text-align:right;";
			$lineText = $1;
		}

		### 中央揃え : 行頭 ::
		if ( $lineText =~ /^\:\:(.+)$/ ) {
			$lineStyle .= "text-align:center;";
			$lineText = $1;
		}

		### 左揃え : 行頭 :
		if ( $lineText =~ /^\:(.+)$/ ) {
			$lineStyle .= "text-align:left;";
			$lineText = $1;
		}


		##### リスト

		### [ 行頭 * or # ] → <UL><LI> or <OL><LI>
		if ( $lineText =~ /^\s*([\*\+]+)(.*)$/ ) {

			$marks = $1;				# *** か ###
			$text  = $2;				# 残りの文字列
			$cnt   = length( $1 );		# *** か ### の個数
			
			if ( $listIndent < $cnt ) { # 現在より深いインデント指定
			
				# 1文字目が何かをチェック
				if ( substr( $marks, 0, 1 ) eq '*' ) { $tag1 = '<ul>'; $tag2 = '</ul>'; }
				else                                 { $tag1 = '<ol>'; $tag2 = '</ol>'; }
			
				while ( $listIndent < $cnt ) {		# インデントの積み上げ
					print DST_FILE "$tag1\n";
					push( @listTag, $tag2 );		# インデントを戻すためのタグ集合
					$listIndent++;
				}
				
			}
			elsif ( $cnt < $listIndent ) { # 現在より浅いインデント指定
				while ( $cnt < $listIndent ) {
					print DST_FILE pop( @listTag )."\n";
					$listIndent--;
				}
			}

			print DST_FILE '<li>';
			&outputTextToFile( $text );
			print DST_FILE "</li>\n";
			next;

		}
		



		##### テーブル

		### [ 行頭 , ] → テーブル
		if ( $lineText =~ /^\|(.+)$/ ) { # 行頭のコンマでテーブル

			$lineText = $1;
			if ( $inTbl == 0 ) { print DST_FILE "<table border>\n"; }
			$inTbl = 1;
			print DST_FILE "<tr>";

			@items = split( '\|', $lineText );	# 縦棒でカラム区切り
			$cnt   = @items;
			if ( $cnt == 0 ) { push( @items, $lineText ); $cnt = @items; }
			
			for( $t = 0 ; $t < $cnt ; $t++ ) {
				if ( $items[ $t ] =~ /^\[cs=(\d+)\](.+)$/ ) { # COLSPAN指定
					print DST_FILE "<td COLSPAN=$1>$2";
				}
				else {
					print DST_FILE "<td>$items[ $t ]";
				}
			}
			next;
		}



		### <pre>の外
		if ( $inPre == 0 ) { 
			if (( 0 == length( $lineStyle ) )&&( 0 == length( $lineClass ) )) { 
				print DST_FILE "<$lineTag>";
				&outputTextToFile( $lineText );
				print DST_FILE "</$lineTag>\n"; 
			} 
			elsif (( 0 < length( $lineStyle ) )&&( 0 == length( $lineClass ) )) { 
				print DST_FILE "<$lineTag style=\"$lineStyle\">";
				&outputTextToFile( $lineText );
				print DST_FILE "</$lineTag>\n"; 
			}
			elsif (( 0 == length( $lineStyle ) )&&( 0 < length( $lineClass ) )) { 
				print DST_FILE "<$lineTag class=\"$lineClass\">";
				&outputTextToFile( $lineText );
				print DST_FILE "</$lineTag>\n"; 
			}
		}
		
		### <pre>の中
		else { 
			print DST_FILE "$lineText\n"; 
		}


	}

	close SRC_FILE;
	close DST_FILE;

	print STDERR   "======================\n";

