<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" 
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:h="http://www.w3.org/1999/xhtml"
	xmlns:s="http://www.remus.dti.ne.jp/~a-satomi/"
	xmlns:js="http://www.remus.dti.ne.jp/~a-satomi/jsfunc"
	xmlns:fl="http://www.remus.dti.ne.jp/~a-satomi/filelist"
	exclude-result-prefixes="h s js fl">

<!-- ================ ナビ関係パラメタ設定 ================  -->

<!-- 親ページ (rel="contents") -->

<xsl:param name="contentsPath">
	<xsl:call-template name="searchFile">
		<xsl:with-param name="rel">contents</xsl:with-param>
		<xsl:with-param name="data">path</xsl:with-param>
	</xsl:call-template>
</xsl:param>

<xsl:param name="contentsURI" select="js:omitDirIndex(js:chsuffix(js:a2r(string($curFilePath), string($contentsPath)), 'html'))"/>

<xsl:param name="contentsLabel">
	<xsl:call-template name="makeAnchorText">
		<xsl:with-param name="path" select="$contentsPath"/>
	</xsl:call-template>
</xsl:param>

<xsl:param name="contentsTitle">
	<xsl:call-template name="makeAnchorTitle">
		<xsl:with-param name="path" select="$contentsPath"/>
		<xsl:with-param name="addAncorTitleSuffix" select="false()"/>
	</xsl:call-template>
</xsl:param>

<!-- 前ページ (rel="prev") -->

<xsl:param name="prevPath">
	<xsl:call-template name="searchFile">
		<xsl:with-param name="rel">prev</xsl:with-param>
		<xsl:with-param name="data">path</xsl:with-param>
	</xsl:call-template>
</xsl:param>

<xsl:param name="prevURI" select="js:omitDirIndex(js:chsuffix(js:a2r(string($curFilePath), string($prevPath)), 'html'))"/>

<xsl:param name="prevLabel">
	<xsl:call-template name="makeAnchorText">
		<xsl:with-param name="path" select="$prevPath"/>
	</xsl:call-template>
</xsl:param>

<xsl:param name="prevTitle">
	<xsl:call-template name="makeAnchorTitle">
		<xsl:with-param name="path" select="$prevPath"/>
		<xsl:with-param name="addAncorTitleSuffix" select="false()"/>
	</xsl:call-template>
</xsl:param>

<!-- 次ページ (rel="next") -->

<xsl:param name="nextPath">
	<xsl:call-template name="searchFile">
		<xsl:with-param name="rel">next</xsl:with-param>
		<xsl:with-param name="data">path</xsl:with-param>
	</xsl:call-template>
</xsl:param>

<xsl:param name="nextURI" select="js:omitDirIndex(js:chsuffix(js:a2r(string($curFilePath), string($nextPath)), 'html'))"/>

<xsl:param name="nextLabel">
	<xsl:call-template name="makeAnchorText">
		<xsl:with-param name="path" select="$nextPath"/>
	</xsl:call-template>
</xsl:param>

<xsl:param name="nextTitle">
	<xsl:call-template name="makeAnchorTitle">
		<xsl:with-param name="path" select="$nextPath"/>
		<xsl:with-param name="addAncorTitleSuffix" select="false()"/>
	</xsl:call-template>
</xsl:param>

<!-- 索引 (rel="index") -->

<xsl:param name="indexPath">
	<xsl:call-template name="searchFile">
		<xsl:with-param name="rel">index</xsl:with-param>
		<xsl:with-param name="data">path</xsl:with-param>
	</xsl:call-template>
</xsl:param>

<xsl:param name="indexURI" select="js:omitDirIndex(js:chsuffix(js:a2r(string($curFilePath), string($indexPath)), 'html'))"/>

<xsl:param name="indexLabel">
	<xsl:call-template name="makeAnchorText">
		<xsl:with-param name="path" select="$indexPath"/>
	</xsl:call-template>
</xsl:param>

<xsl:param name="indexTitle">
	<xsl:call-template name="makeAnchorTitle">
		<xsl:with-param name="path" select="$indexPath"/>
		<xsl:with-param name="addAncorTitleSuffix" select="false()"/>
	</xsl:call-template>
</xsl:param>

<!-- RSS (rel="meta", rel="alternate") -->

<xsl:param name="rssPath">
	<xsl:call-template name="searchFile">
		<xsl:with-param name="rel">rss</xsl:with-param>
		<xsl:with-param name="data">path</xsl:with-param>
	</xsl:call-template>
</xsl:param>

<xsl:param name="rssURI" select="js:a2r(string($curFilePath), string($rssPath))"/>

<xsl:param name="rssLabel">
	<xsl:call-template name="makeAnchorText">
		<xsl:with-param name="path" select="$rssPath"/>
	</xsl:call-template>
</xsl:param>

<!-- foaf (rel="meta FOAF.MAKER") -->

<xsl:param name="foafPath">
	<xsl:call-template name="searchFile">
		<xsl:with-param name="rel">foaf</xsl:with-param>
		<xsl:with-param name="data">path</xsl:with-param>
	</xsl:call-template>
</xsl:param>

<xsl:param name="foafURI" select="js:a2r(string($curFilePath), string($foafPath))"/>

<xsl:param name="foafLabel">
	<xsl:call-template name="makeAnchorText">
		<xsl:with-param name="path" select="$foafPath"/>
	</xsl:call-template>
</xsl:param>

<!-- ================ ファイル調査テンプレ ================  -->

<xsl:template name="searchFile">
	<xsl:param name="path" select="$curFilePath"/><!-- 調査ファイルの仮想的フルパス。無指定は $curFilePath  -->
	<xsl:param name="rel"/><!-- 調査ファイルとの関係性。 prev / next / contents / index /rss / foaf 。 無指定は調査ファイル自身。 -->
	<xsl:param name="data"/><!-- 取り出す情報。 path : 基準からのフルパス, title : ページタイトルまたは id の示す要素の内容値 -->
	<xsl:param name="relEnabled" select="not(contains($path, '/index.xml'))"/><!-- 関係性調査を有効にするか否か -->

	<!-- ファイルリストを走査した値を格納 -->
	<xsl:param name="result_from_fileList">
		<xsl:call-template name="searchFile_">
			<xsl:with-param name="path" select="$path"/>
			<xsl:with-param name="rel" select="$rel"/>
			<xsl:with-param name="data" select="$data"/>
			<xsl:with-param name="relEnabled" select="$relEnabled"/>
		</xsl:call-template>
	</xsl:param>

	<xsl:choose>
		<!-- ファイルリスト中を走査してなにがしかの結果が出る場合 -->
		<xsl:when test="string($result_from_fileList)">
			<xsl:value-of select="$result_from_fileList"/>
		</xsl:when>
		<!-- 何も出てこなかった場合 -->
		<xsl:otherwise>
			<xsl:choose>
				<!-- ファイルの関係性を調査してる場合。調査できないのだから、何も返さない -->
				<xsl:when test="string($rel)"/>
				<!-- 取り出したい情報がフルパスであれば、ただそのまま返すのみ -->
				<xsl:when test="$data = 'path'">
					<xsl:value-of select="$path"/>
				</xsl:when>
				<!-- 取り出したい情報がタイトルの場合 -->
				<xsl:when test="$data = 'title'">
					<xsl:call-template name="getPageTitle">
						<xsl:with-param name="path" select="$path"/>
					</xsl:call-template>
				</xsl:when>
				<xsl:otherwise/>
			</xsl:choose>
		</xsl:otherwise>
	</xsl:choose>
</xsl:template>

<xsl:template name="searchFile_">
	<xsl:param name="path"/>
	<xsl:param name="rel"/>
	<xsl:param name="data"/>
	<xsl:param name="relEnabled"/>

	<xsl:choose>

		<!-- 指定ファイルパスが絶対パスの時（＝最初の一回の呼び出し） -->
		<xsl:when test="starts-with($path, '/')">
			<xsl:for-each select="document($fileList)/fl:dir">
				<xsl:call-template name="searchFile_">
					<xsl:with-param name="path" select="substring-after($path, '/')"/>
					<xsl:with-param name="rel" select="$rel"/>
					<xsl:with-param name="data" select="$data"/>
					<xsl:with-param name="relEnabled" select="$relEnabled"/>
				</xsl:call-template>
			</xsl:for-each>
		</xsl:when>

		<!-- ファイルパスがまだディレクトリ名を含んでいたら（再帰呼び出し二度目以降） -->
		<xsl:when test="contains($path, '/')">
			<xsl:for-each select="fl:dir[@name = substring-before($path, '/')]">
				<xsl:call-template name="searchFile_">
					<xsl:with-param name="path" select="substring-after($path, '/')"/>
					<xsl:with-param name="rel" select="$rel"/>
					<xsl:with-param name="data" select="$data"/>
					<xsl:with-param name="relEnabled" select="$relEnabled"/>
				</xsl:call-template>
			</xsl:for-each>
		</xsl:when>

		<!-- 指定ファイルパスがファイル名だけになったら -->
		<xsl:otherwise>

			<!-- ファイルパス中 id フラグメント -->
			<xsl:variable name="id" select="substring-after($path, '#')"/>

			<!-- ファイルパス中のファイル名部分 (idフラグメント部を除いたもの) -->
			<xsl:variable name="path_">
				<xsl:choose>
					<xsl:when test="$id">
						<xsl:value-of select="substring-before($path, '#')"/>
					</xsl:when>
					<xsl:otherwise>
						<xsl:value-of select="$path"/>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:variable>

			<!-- file 要素の親・祖先要素の dir 要素に指定があるか探す -->
			<xsl:variable name="dirDefault">
				<xsl:if test="$rel">
					<xsl:call-template name="searchDirDefault">
						<xsl:with-param name="rel" select="$rel"/>
					</xsl:call-template>
				</xsl:if>
			</xsl:variable>

			<xsl:choose>

				<!-- file 要素に直接指定があったら -->
				<xsl:when test="fl:file[@name = $path_]/@*[name() = $rel]">
					<xsl:call-template name="searchFile_">
						<xsl:with-param name="path" select="fl:file[@name = $path_]/@*[name() = $rel]"/>
						<xsl:with-param name="rel"/>
						<xsl:with-param name="data" select="$data"/>
						<xsl:with-param name="relEnabled" select="$relEnabled"/>
					</xsl:call-template>
				</xsl:when>

				<!-- file 要素の親・祖先要素の dir 要素に指定があったら -->
				<xsl:when test="string($dirDefault)">
					<xsl:call-template name="searchFile_">
						<xsl:with-param name="path" select="string($dirDefault)"/>
						<xsl:with-param name="rel"/>
						<xsl:with-param name="data" select="$data"/>
						<xsl:with-param name="relEnabled" select="$relEnabled"/>
					</xsl:call-template>
				</xsl:when>

				<!-- file 要素の兄弟関係や dir 要素の包含関係から探す -->
				<xsl:otherwise>
					<xsl:choose>
						<xsl:when test="$rel = 'prev'">
							<xsl:if test="$relEnabled">
								<xsl:for-each select="fl:file[@name = $path_]/preceding-sibling::fl:file[1][@name != 'index.xml' and @name != 'index.html']">
									<xsl:call-template name="getData">
										<xsl:with-param name="data" select="$data"/>
										<xsl:with-param name="id" select="$id"/>
									</xsl:call-template>
								</xsl:for-each>
							</xsl:if>
						</xsl:when>
						<xsl:when test="$rel = 'next'">
							<xsl:if test="$relEnabled">
								<xsl:for-each select="fl:file[@name = $path_]/following-sibling::fl:file[1][@name != 'index.xml' and @name != 'index.html']">
									<xsl:call-template name="getData">
										<xsl:with-param name="data" select="$data"/>
										<xsl:with-param name="id" select="$id"/>
									</xsl:call-template>
								</xsl:for-each>
							</xsl:if>
						</xsl:when>
						<xsl:when test="$rel = 'contents'">
							<xsl:if test="$relEnabled">
								<xsl:for-each select="fl:file[@name = 'index.xml'] | fl:file[@name = 'index.html']">
									<xsl:call-template name="getData">
										<xsl:with-param name="data" select="$data"/>
										<xsl:with-param name="id" select="$id"/>
									</xsl:call-template>
								</xsl:for-each>
							</xsl:if>
						</xsl:when>
						<xsl:when test="$rel = 'index'"/>
						<xsl:when test="$rel = 'rss'"/>
						<xsl:when test="$rel = 'foaf'"/>
						<!-- $rel 無指定の場合は指定ファイル自体に対する処理 -->
						<xsl:otherwise>
							<xsl:for-each select="*[@name = $path_]">
								<xsl:call-template name="getData">
									<xsl:with-param name="data" select="$data"/>
									<xsl:with-param name="id" select="$id"/>
								</xsl:call-template>
							</xsl:for-each>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:otherwise>
	</xsl:choose>
</xsl:template>

<!-- =========== ファイルリスト走査テンプレのサブテンプレ群 ===========  -->

<!-- dir 要素への包括指定を探す -->
<!-- 注：カレントノードがファイルリスト中の dir 要素/file 要素に来ている事が前提 -->
<xsl:template name="searchDirDefault">
	<xsl:param name="rel"/>
	<xsl:choose>
		<xsl:when test="@*[name() = $rel] = ''">
			<xsl:text>_NULL_</xsl:text>
		</xsl:when>
		<xsl:when test="@*[name() = $rel]">
			<!-- 指定値が $curFilePath と同じ場合は無視 -->
			<xsl:if test="@*[name() = $rel] != $curFilePath">
				<xsl:value-of select="@*[name() = $rel]"/>
			</xsl:if>
		</xsl:when>
		<xsl:otherwise>
			<xsl:for-each select="parent::node()">
				<xsl:call-template name="searchDirDefault">
					<xsl:with-param name="rel" select="$rel"/>
				</xsl:call-template>
			</xsl:for-each>
		</xsl:otherwise>
	</xsl:choose>
</xsl:template>

<!-- 情報取り出し -->
<!-- 注：カレントノードがファイルリスト中の dir 要素/file 要素に来ている事が前提 -->
<xsl:template name="getData">
	<xsl:param name="data"/><!-- 取り出す情報。( path | title ) -->
	<xsl:param name="id"/><!-- id 識別子を使うならその値 -->

	<xsl:choose>
		<!-- パスを取り出すモード -->
		<xsl:when test="$data = 'path'">
			<xsl:text>/</xsl:text>
			<xsl:call-template name="getPath">
				<xsl:with-param name="filename" select="@name"/>
			</xsl:call-template>
			<xsl:if test="local-name() = 'dir'">/</xsl:if>
			<xsl:if test="$id">#<xsl:value-of select="$id"/></xsl:if>
		</xsl:when>

		<!-- ページタイトルを取り出すモード -->
		<xsl:when test="$data = 'title'">
			<xsl:variable name="path">
				<xsl:call-template name="getData">
					<xsl:with-param name="data">path</xsl:with-param>
				</xsl:call-template>
			</xsl:variable>
			<xsl:variable name="pageTitle">
				<xsl:choose>
					<!-- id の指定があったら -->
					<xsl:when test="$id">
						<xsl:call-template name="getPageTitle">
							<xsl:with-param name="path" select="concat($path, '#', $id)"/>
						</xsl:call-template>
					</xsl:when>
					<!-- ファイルリストの該当 file 要素に内容テキストがあったら -->
					<xsl:when test="string(self::node())">
						<xsl:value-of select="self::node()"/>
					</xsl:when>
					<!-- id 指定も file 要素の内容テキストもなかったら -->
					<xsl:otherwise>
						<xsl:call-template name="getPageTitle">
							<xsl:with-param name="path" select="$path"/>
						</xsl:call-template>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:variable>

			<xsl:choose>
				<!-- 返す値がカラの場合のエラー処理 -->
				<xsl:when test="not(string($pageTitle))">
					<xsl:message terminate="yes">
						<xsl:text>[Title not found] </xsl:text>
						<xsl:choose>
							<xsl:when test="$id">
								<xsl:value-of select="concat($path, '#', $id)"/>
							</xsl:when>
							<xsl:otherwise>
								<xsl:value-of select="$path"/>
							</xsl:otherwise>
						</xsl:choose>
					</xsl:message>
				</xsl:when>
				<!-- 返す値がちゃんとあるなら返す -->
				<xsl:otherwise>
					<xsl:value-of select="$pageTitle"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:when>
		<xsl:otherwise/>
	</xsl:choose>
</xsl:template>

<!-- 基準からの絶対パスの取得 -->
<!-- 注：カレントノードがファイルリスト中の dir 要素/file 要素に来ている事が前提 -->
<xsl:template name="getPath">
	<xsl:param name="filename"/><!-- 現在処理中のファイルの名前 -->
	<xsl:choose>
		<xsl:when test="../@name and ../@name != '/'">
			<xsl:for-each select="parent::fl:dir">
				<xsl:call-template name="getPath">
					<xsl:with-param name="filename">
						<xsl:value-of select="concat(@name, '/', $filename)"/>
					</xsl:with-param>
				</xsl:call-template>
			</xsl:for-each>
		</xsl:when>
		<xsl:otherwise>
			<xsl:value-of select="$filename"/>
		</xsl:otherwise>
	</xsl:choose>
</xsl:template>

<!-- =========== 汎用サブテンプレ ===========  -->

<!-- 指定パスの文書のページタイトル、あるいは id 識別子の示す要素の内容値を取得 -->
<xsl:template name="getPageTitle">
	<xsl:param name="path"/><!-- 対象ファイルの仮想的フルパス (id 識別子を含む) -->
	<xsl:param name="page" select="document(concat($baseDir, $path))"/>
	<xsl:param name="id" select="substring-after($path, '#')"/>

	<xsl:if test="not($page)">
		<xsl:message terminate="yes">[File not found] <xsl:value-of select="$path"/></xsl:message>
	</xsl:if>

	<xsl:choose>
		<!-- id 識別子あり -->
		<xsl:when test="$id">
			<xsl:for-each select="$page/descendant::*[@id = $id]"><!-- 記述簡素化目的のカレントノード移動 -->
				<xsl:choose>
					<!-- id の示す要素が div.section だった場合 -->
					<xsl:when test="name(self::node()) = 'div' and contains(@class, 'section')">
						<xsl:value-of select="h:h1 | h:h2 | h:h3 | h:h4 | h:h5 | h:h6"/>
					</xsl:when>
					<!-- id の示す要素が  h[1-6] だった場合 -->
					<xsl:when test="starts-with(name(self::node()), 'h') and substring(name(self::node()), 2, 1) &gt; 0">
						<xsl:value-of select="."/>
					</xsl:when>
					<xsl:otherwise>
						<xsl:value-of select="concat('#', $id)"/>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:for-each>
		</xsl:when>
		<!-- id 識別子なし -->
		<xsl:otherwise>
			<xsl:value-of select="document(concat($baseDir, $path))/descendant::h:h1"/>
		</xsl:otherwise>
	</xsl:choose>
</xsl:template>

</xsl:stylesheet>
