<?php

/*
include2.inc.php
ページをインクルードする

#include2({ページ名},{行数指定},{オプション})

-----行数指定-----
省略	:全部表示
m-n	:m行目からn行目まで表示(n行目m行目を含む)
m-	:m行目から全部表示。
-n	:n行目まで表示(1-n と同じ)
n	:最初からn行目まで表示(-n, 1-n と同じ)

-----オプション-----
read	：includeしているページへのリンクを表示。（※省略時デフォルト）
edit	：includeしているページへの編集リンクを表示。
title	：includeしているページ名表示。（リンクはしない）
page	：階層化しているページの最後の部分を表示。
none	：includeしているページのタイトルもリンクも表示しない。

*/
// インクルードする最大ページ数
define('PLUGIN_INCLUDE2_MAX', 4);

function plugin_include2_init()
{
    global $plugin_include_included;
    global $plugin_include_count;
    if (! isset($plugin_include_included)) {
        $plugin_include_included = array();
    }
    if (! isset($plugin_include_count)) {
        $plugin_include_count = 1;
    }
}

function plugin_include2_convert()
{
    global $script, $vars, $get, $post;;
    global $menubar;
    global $_msg_include_restrict;
    global $_symbol_anchor;
    global $plugin_include_included;
    global $plugin_include_count;

    if (func_num_args() == 0) {
        return "include2(): Bad option<br />\n";
    }

    // $menubar will already be shown via menu plugin
    // if (! isset($plugin_include_included[$menubar])) $plugin_include_included[$menubar] = TRUE;
    // include.inc.php にあったのだが、menubar を include で表示できてもいいと思う。

    // include を呼び出したページはもちろん表示済み
    $root = isset($vars['page']) ? $vars['page'] : '';
    $plugin_include_included[$root] = true;
    // Get arguments
    list($page, $line, $opt) = func_get_args();
    // strip_bracket() is not necessary but compatible with 1.3.x (get_fullname() allows relative directory)
    $page = isset($page) ? get_fullname(strip_bracket($page), $root) : '';

    $s_page = htmlspecialchars($page);
    $r_page = rawurlencode($page);
    $k_page = array_pop(explode('/', $s_page));

    // エラー処理
    $link = '<a href="' . $script . '?' . $r_page . '">' . $s_page . '</a>'; // error メッセージ用のリンク
    if (isset($plugin_include_included[$page])) {
        return '#include2(): Included already: ' . $link . '<br />' . "\n";
    }
    if (! is_page($page)) {
        return '#include2(): No such page: ' . $s_page . '<br />' . "\n";
    }
    if ($plugin_include_count > PLUGIN_INCLUDE2_MAX) {
        return '#include2(): Limit exceeded: ' . $link . '<br />' . "\n";
    } else {
        ++$plugin_include_count;
    }

    // One page, only one time, at a time
    $plugin_include_included[$page] = true;

    // include で呼び出すページがこれらの値を使うかもしれないので。$page = include されるページ
    $get['page'] = $post['page'] = $vars['page'] = $page;
    if (check_readable($page, false, false)) {
        $src = get_source($page);
        $src = array_filter($src, "plugin_include2_match_comment");
        $regs = array();
        // 行指定の処理
        if ($line == "") {
        } elseif (ereg ("([0-9]+)-([0-9]+)", $line, $regs)) {
            // m-n :m行目からn行目まで表示。
            list(, $line_start, $line_end) = $regs;
            if ($line_start > 0 && $line_start <= $line_end) {
                $offset = $line_start -1;
                $length = $line_end - $line_start + 1;
                $src = array_slice ($src, $offset, $length);
            } else {
                $src = "include2(): Bad option\n";
            }
        } elseif (ereg ("([0-9]+)-", $line, $regs)) {
            // m- :m行目から全部表示。
            $offset = $regs[1] -1;
            $src = array_slice ($src, $offset);
        } elseif (ereg ("-([0-9]+)", $line, $regs)) {
            // -n :n行目まで表示。
            $offset = 0;
            $length = $regs[1];
            if ($length > 0) {
                $src = array_slice ($src, $offset, $length);
            } else {
                $src = "include2(): Bad option\n";
            }
        } elseif (ereg ("[0-9]+", $line)) {
            // n: 最初からn行目まで表示。( 1-n, -n  と同じ。)
            $offset = 0;
            $length = $line;
            if ($length > 0) {
                $src = array_slice ($src, 0, $length);
            } else {
                $src = "include2(): Bad option\n";
            }
        } else {
            $src = "include2(): Bad option\n";
        }

        $body = convert_html($src);
    } else {
        $body = str_replace('$1', $page, $_msg_include_restrict);
    }
    // 元に戻す。
    $get['page'] = $post['page'] = $vars['page'] = $root;

    // リンクの作成
    if ($opt === "edit") {
        $link = "<a href=\"$script?cmd=edit&amp;page=$r_page\">$s_page</a>";
    } elseif ($opt === "title") {
        $link = "$s_page";
    } elseif ($opt === "none") {
        $link = "";
    } elseif ($opt === "page") {
        $link = "$k_page";
    } else {
        $link = "<a href=\"$script?$r_page\">$s_page</a>"; // Read link
    }

    if ($link != '') {
        // ページアンカー作成
        $pageanchor = plugin_include2_pageanchor($page);
        if (is_file(PLUGIN_DIR . 'aname.inc.php')) {
            require_once(PLUGIN_DIR . 'aname.inc.php');
            $anchorlink =  plugin_aname_inline($pageanchor, 'super', $_symbol_anchor);
        }
        // 出力
        if ($page == $menubar) {
            $body = "<span align=\"center\"><h5 class=\"side_label\">$link $anchorlink</h5></span>\n<small>$body</small>";
        } else {
            $body = "<h1>$link $anchorlink</h1>\n$body\n";
        }
    }

    return $body;
}

// ページアンカー作成。
function plugin_include2_pageanchor($page)
{
    // ページ名後ろ100文字をキーに md5 ハッシュを作り、さらに 7 文字に削る。
    // アンカーの先頭は [A-Za-z] でなければならないので 'A' をつける。
    $start = (($len = strlen($page) - 100) > 0) ? $len : 0;
    $pageanchor = 'A' . substr(md5(substr($page, $start)), 0, 7);
    return $pageanchor;
}

function plugin_include2_match_comment($var)
{
    if (ereg("^//", $var)) {
        return false;
    } else {
        return true;
    }
}

?>
