0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

perl 試作品1号 一応参考程度。テキストをページにして見るアプリ。

Posted at

ページリーダの作りかけ。perl5.22
備忘録的に参考になればと。
初心者でも分かるくらいの、スペックだと思います。
プログラマーは言語で分かり合え、的な万国でも通用することを願います。

Alberto_story_pl.cgi
#! C:/Perl/bin/perl

####################################
# CGI script to display a two-panel layout in HTML
# it name is Alberto_story_pl.cgi
# adoress: http://127.0.0.1/my_apach/story/Alberto_story_pl.cgi
#     2025/06/02
#################################### ページではなくて行で行っている。
#use strict;
#use warnings;
#use CGI qw(:standard);
#use CGI::Carp qw(fatalsToBrowser); # エラーをブラウザに表示する
###use utf8; # UTF-8エンコーディングを使用  挙動がおかしくなるから使わない。
#use Encode qw(encode decode); # エンコードとデコードを使用
#use Encode::Locale; # ロケールに基づくエンコーディングを使用
#use Encode::Guess; # エンコーディングの推測を使用
#use Encode::Unicode; # Unicodeエンコーディングを使用
#use Encode::CN; # 中国語エンコーディングを使用
#use Encode::JP; # 日本語エンコーディングを使用
use Encode; # UTF-8エンコーディングを使用 ないと表示しなくなりブラウザの再起動が必要。
#+++++++++++++++++++++++++++++++++++++
# 決めておく変数
$cgi_uri ="./Alberto_story_pl.cgi"; # 初期値

%inhp;
$inhp{"my_i"} = 0; # 初期値
$inhp{"my_c"} = 1; # 初期値
$inhp{"my_p"} = 0; # 初期値
$inhp{"my_pagi"} = 0; # 初期値
$inhp{"no_click"} = "true"; # 初期値
$inhp{"rede_max"} = 0; # ページの最大数を初期化
$inhp{"my_base"} = "http://127.0.0.1/my_apach/story/"; # 初期値
$cf{"maxdata"} = 1024 * 1024; # 最大データサイズを1MBに設定
$rede_pegi_max_d = $inhp{"my_pagi"}; # ページの最大数を初期化 使ってない
#+++++++++++++++++++++++++++++++++++++
$my_base_w_lain = 12; # 指定のないページの行数    ここを2にして見開きにすれば。。。漫画も可能?
#+++++++++++++++++++++++++++++++++++++
%cf = (
    'maxdata' => 1024 * 1024, # 最大データサイズ
    'maxfile' => 1024 * 1024, # 最大ファイルサイズ
    'maxname' => 256,         # 最大ファイル名長
    'maxpath' => 256,         # 最大パス長
);
#+++++++++++++++++++++++++++++++++++++
$inhp{'up_p'} = "no_up_p"; # ページ送りのための変数



   &parse_form(); # フォームデータを解析して %inhp に格納                  ここ注意


#+++++++++++++++++++++++++++++++++++++
#if($inhp{'failed'}) {&error($inhp{'failed'}); exit;}  # エラーが発生した場合は終了
$fail_r_name = "./material/text/Management_room.txt";
$hyouji = ""; # 表示用の変数   manga
&rede_fail(); # ファイルがない場合の処理
#+++++++++++++++++++++++++++++++++++++
sub rede_fail {
    if($inhp{'failed'}) { 
        my $failed_in = $inhp{'failed'};  # エラーが発生した場合の変数
        if ($failed_in =~ m/^text\/.*\.te?xt$/) {
            $fail_r_name = "./material/$failed_in";  # エラーが発生した場合のファイル名を設定
        } else {
          #  $fail_r_name = "./material/text/Management_room.txt";  # デフォルトのファイル名を設定
        }
    }
    if (!-e $fail_r_name) { die("Cannot open file: $$ \n"); }
    #+++++++++++++++++++++++++++++++++++++
    # ファイルが存在しない場合
    @rede_data_arr =();# ("§§NO BOOK Error");
    open(INTE, "< $fail_r_name") or die("Cannot open file: $! \n");
    @rede_data_arr =<INTE>;
    close(INTE);
    #+++++++++++++++++++++++++++++++++++++
     if ($#rede_data_arr > 11) {
        $inhp{"my_c"} = 12; # 初期値 1~10は1pageに表示する行数
    }else {
        $inhp{"my_c"} = $#rede_data_arr + 1; # 初期値 1~10は1pageに表示する行数
    }
    #+++++++++++++++++++++++++++++++++++++    
        @Read_original_arr = @rede_data_arr; # 元の配列を保持    
}
#&error();
&in_is_setting(); # 設定行の処理を実行
#+++++++++++++++++++++++++++++++++++++
if ($rede_data_arr[0] =~ m/^#\$#\smanga;/) {
    $hyouji_1 = $1;  # 表示用の変数を取得
    $hyouji = 'manga';  # 表示用の変数を設定
   # &error("表示用の変数: $hyouji_1<br>\n");  # デバッグ用
} elsif ($rede_data_arr[0] =~ m/^###\stest;/) {
    $hyouji = 'test';  # 表示用の変数を設定
} elsif ($rede_data_arr[0] =~ m/^#\$#\s/) {
    $my_base_w_lain = 25; # 指定のないページの行数
} elsif ($rede_data_arr[0] =~ m/^§§./) {  # 行頭が"§§"または"#$##i?#"で始まるかどうかをチェック
    #  ノーマルスタート
} 
#+++++++++++++++++++++++++++++++++++++
if ($hyouji eq "manga") {
    $my_base_w_lain = 1; # 指定のないページの行数 1pageに1行
    shift @rede_data_arr;  # 最初の行を削除(@rede_data_arr); 
    @Read_original_arr = @rede_data_arr; # 元の配列を保持
   # &page_no(); # ページ番号の処理を実行
    # ページ番号の処理を実行
} elsif ($hyouji eq "test") {
    $my_base_w_lain = 25; # 指定のないページの行数
    &test_eria(); # テスト用の関数を実行
}
#+++++++++++++++++++++++++++++++++++++
sub in_is_setting {
    # &error("設定行の処理を開始<br>\n");
    my  $setting_line ="";# 最初の行を取得     
       # &error("$rede_data_arr[0]  。デフォルトのテキストファイルを使用します。<br>\n");
    if (!$inhp{'failed'} && $fail_r_name ne "./material/text/Management_room.txt") {
        &error("ファイル名が変更されました。$fail_r_name<br>\n");
        die("Management_room.txt not chnge.\n");
        exit;    
    } elsif ($rede_data_arr[0] =~ m/^#\$#/) {
        if ($rede_data_arr[0] =~ m/\ssetting="(.*?)";/) {
            if ($rede_data_arr[0] =~ m/\shyouji="(.*?)";/) {
                $hyouji = $1;  # 表示用の変数を取得
                &error("表示用の変数: $hyouji<br>\n");
            }
            $setting_line = $1;  # 最初の行を取得
            if ($setting_line ne "") {
                $fail_r_name = "./material/text/".$setting_line;  # テキストファイルのパスを設定
                    &rede_fail();
            }                
        }
    }    
}
#+++++++++++++++++++++++++++++++++++++
# @rede_data_arr

#+++++++++++++++++++++++++++++++++++++
sub hhhh {
print "Content-type:text/html\n\n";
print <<"EOF";
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>てすと</title>
    </head>
<body>
EOF
}
#+++++++++++++++++++++++++++++++++++++
# ?< 暗目に開始は変換から<?が中にあって    もここは変えるで>?ここまで     始ま?<り、\nで終わるようにする>?
#    holdig
#  &ltgt_convert(); # 変換処理を実行
#
#+++++++++++++++++++++++++++++++++++++
sub ltgt_convert {
   # print "<h1>てすと</h1>\n";  # タイトルを表示
   # print "<p>このページはテスト用です。</p>\n";  # 説明を表示
    my @rede_data_arr1 = @rede_data_arr; # 元の配列を保持
    # ?< 暗目に開始は変換から<?が中にあってもここは変えるで>?ここまで     始ま?<り、\nで終わるようにする>?
    my @arr_itizi = (); #
    my @arr_itizi2 = (); # 変数の初期化
    my $cr_ql = '?<';  # 行末の">?"を削除するための変数
    foreach my $value (@rede_data_arr1) {
        $value= $cr_ql.$value;  # 行頭に"?<"を追加
        if ($value !~ m/\>\?/) {  # 行頭に"?<"がない場合はスキップ
            $value =~ s/\?\<//;  # 行頭の"?<"を削除
            $value =~ s/\</&lt;/g;  # "<"を"&lt;"に変換
            $value =~ s/\>/&gt;/g;  # ">"を"&gt;"に変換
            next;
            # 最初の出現はなし。
        } else {
            @arr_itizi = split(/\>\?/, $value);
            for my $i (0 .. $#arr_itizi) {
                my $arr_itizi_0 = $arr_itizi[$i];  # 行を取得
                my $i0 = $i % 2;  # 偶数行と奇数行を判定
                if ($i0 == 0) {  # 偶数行の場合
                    @arr_itizi2 = split(/$cr_ql/, $arr_itizi_0);  # "<"で分割2個しか入らんい 空文字列か途中の?<の前
                    for my $j (0 .. $#arr_itizi2) {
                        my $arr_itizi2_2 = $arr_itizi2[$j];  # 行を取得
                        my $j0 = $j % 2;  # 偶数行と奇数行を判定
                        if ($j0 == 0) {  # 偶数行の場合  ここは"<"が入っている
                            $arr_itizi2_2 =~ s/\</&lt;/g;  # "<"を"&lt;"に変換
                            $arr_itizi2_2 =~ s/\>/&gt;/g;  # ">"を"&gt;"に変換 
                        # 
                        } else {  # 奇数行の場合 ?< の後は残すから 消えた?<の復元                            
                            $arr_itizi2[$j] = $cr_ql.$arr_itizi2_2;  # 行頭に"<"を追加
                        }
                    }
                    $arr_itizi[$i] = join("", @arr_itizi2);  # 分割した文字列を再結合            
                } else {  # 奇数行の場合[1]復元して  全部残す
                    $arr_itizi[$i] .= '>?';  # 行末に">?"を追加 
                }
            }
            $value = join("", @arr_itizi);  # 分割した文字列を再結合
        } 
        $value =~ s/^\$cr_ql//g;  # 行頭に?lt;//;  # 行頭の"?<"を削除
        $value =~ s/\>\?$//;  # 行末の">?"を削除        
    }
    #何もかもやると分からなくなる動いて確認してから
   # print "<pre>\n";  # <pre>タグで囲む
    my @rede_data_arr2 = (); # 元の配列を保持
    foreach my $value (@rede_data_arr1) {
        $value =~ s/^\</X/g;  # "<"を"&lt;"に変換
        $value =~ s/\>$/Y/g;  # ">"を"&gt;"に変換
        push(@rede_data_arr2, $value);  # 変換後の行を新しい配列に追加
   #     print "$value\n";  # 行を表示
    }
  @rede_data_arr = @rede_data_arr2; # 変換後の配列を元の配列に置き換え
  #  print "</pre>\n";  # </pre>タグで囲む
  #  print "<p>このページはテスト用です。</p>\n";  # 説明を表示
  #  @rede_data_arr= @rede_data_arr1; # 元の配列を保持
}#+++++++++++++++++++++++++++++++++++++
sub ttttt {
 
print <<"EOF";
</body>
</html>
EOF
exit;
}
#+++++++++++++++++++++++++++++++++++++


sub test_eria {
$p_haba_moji = 25*2; # 半角での文字数全角25文字ごとに分割; # 1行の文字数を指定
#-----------------------------------------------------------
$kaishi = @rede_data_arr; # 最初の行を取得
@new_data_arr = (); # 新しい配列を初期化
#+++++++++++++++++++++++++++++++++++++
# print "最初の行: $kaishi<br>\n";  # デバッグ用
# print @Read_original_arr."<br>\n";  # デバッグ用

#-----------------------------------------------------------
sub test_sub {
    $i = -1;
    foreach my $value (@Read_original_arr) {
        $i++;  # 行番号をインクリメント
        $value =~ s/^\s+|\s+$//g;  # 行頭と行末の空白を削除
    #  $value =~ s/\r//g;  # 改行コードを削除
        $value =~ s/\n/<br>/g;  # 改行コードをHTMLの改行タグに変換 先頭は\n または文字spでも問題あったらおかしい    
        if ($value eq "") {
            next;  # 空行はスキップ
        }
    #   print "$i: $value<br>\n";  # デバッグ用
    #  my $text = "これはサンプルのテキストで、25文字ごとに分割されます。長い文章でも対応可能です。";
    # 25文字ごとに分割
    #  my $f_i = 0; # 分割された文字列のインデックス
        if ($value =~ m/^§/) {
            push(@new_data_arr, $value);  # "§"で始まる行はそのまま配列に追加     
            next;  # 次の行へ
        }else {
            my $value = " $value";  # 行頭に全角スペースを追加
        }
   
        print "inStato:$i: $value<br>\n";  # デバッグ用 $i を使ってる
        print "$value second<br>\n";   
    }
}

####################################################################
# UTF-8バイト列を分割する関数
$p_haba_moji = 25;  # 分割する文字数を指定 p_haba_moji = 1;だと1文字ごとに分割される結果は同じになる。
$err_split = "";  # 分割エラーのフラグを初期化
$fast_retun_utf = 0;  # クリックされた回数をカウントする変数全角を2 半角を1としてカウントされる
$test_str = "A\x01BあC";  # テスト用の文字列
@tokens = &split_utf8_bytes($test_str);  # テスト用の文字列を分割
print "分割tokensされた文字列の数: $#tokens<br>\n";  # 分割された文字列の数を表示
print "分割された文字列: ", join(" | ", map { unpack("H*", $_) } @tokens), "<br>\n";  # 分割された文字列を表示
# 分割された文字列を新しい配列に格納
@new_data_arr = (@tokens);  # 分割された文字列を新しい配列に格納
print "分割された文字列の数: $#new_data_arr<br>\n";  # 分割された文字列の数を表示
print "分割された文字列: ", join(" | ", map { unpack("H*", $_) } @new_data_arr), "<br>\n";  # 分割された文字列を表示
#+++++++++++++++++++++++++++++++++++++
# use Encode; # UTF-8エンコーディングを使用 
#+++++++++++++++++++++++++++++++++++++
# UTF-8バイト列を分割する関数
sub split_utf8_bytes {
    if ($p_haba_moji <= 1) {  # 分割する文字数が1未満の場合はエラー
        $p_haba_moji = 1;  # 分割する文字数を1に設定
    }
    my $value = shift;  # 引数から文字列を取得
    my $str_master = $value;  # 分割する文字列を取得
    my $my_i = 0;  # クリックされた回数をカウントする変数全角を2 半角を1としてカウントされる
    my $mi_i = 0;  # クリックされた回数をカウントする変数全角を2 半角を1としてカウントされる
    my $mi_ii = 0;  # クリックされた回数をカウントする変数全角を2 半角を1としてカウントされる
    my $my_fast_Rage = 0;  # クリックされた回数をカウントする変数全角を2 半角を1としてカウントされる
    my $my_p_loop_c = 0;  # クリックされた回数をカウントする変数全角を2 半角を1としてカウントされる
    my $str = Encode::encode('UTF-8', $str_master);  # バイト列に変換
    my @return_arr = ();  # 分割された文字列を格納する配列
    my $i_i = 0;
    my $total = length($str);  # ← ここが「バイトの総数」
    my @count_1arr = ();  # クリックされた回数を格納する配列
    while ($i_i < $total) {
        #$#i# print "i_i: $i_i<br>\n";  # デバッグ用
        # クリックされた回数をカウント, total: $total, my_i: $my_i<br>\n";  # デバッグ用
        if ($my_i % $p_haba_moji == 0) {  # 25文字ごとに分割
          #  print $i_i, "文字目$my_i で分割<br>\n";  # デバッグ用

            push(@count_1arr, $i_i);  # クリックされた回数を配列に追加           
        }
        my $first_byte = ord(substr($str, $i_i, 1));
        # print "first_byte: $first_byte<br>\n";  # デバッグ用           
        if ($first_byte eq "") {
            last;  # 文字列の終わりに到達したらループを終了
        }
        if ($first_byte <= 0x7F) {
            #$### print "ASCII: ";
            my $ascii = substr($str, $i_i, 1); #判定後位置は変わっていない
            #   print unpack("H*", $ascii), "\n";
			$i_i++;   # つぎのasciiために位置を+1しておく
            $my_i++;  # クリックされた回数をカウント
            $mi_i++;  # 半角専用カウント
			push @return_arr, $ascii; 		
            next;
        } else {
            if ($i_i != 0) {
                $i_i--;  # 再取り込みのために1戻す           
            } else {
                $my_fast_Rage = 1; #先頭が全角で始まっていない。
            }
            #$#i#  print "非ASCII: ";
            my $len = 0;#1;substr($str, $i_i, $len +1);  # 文字の長さを初期化 asciiは1文字なのでlenは0+1となる
            if    (($first_byte & 0xE0) == 0xC0) { $len = 2; } #0+2 = 2+1 = 3
            elsif (($first_byte & 0xF0) == 0xE0) { $len = 3; }
            elsif (($first_byte & 0xF8) == 0xF0) { $len = 4; }                
            my $char = substr($str, $i_i, $len +1); #iiを含めているからlen+1 0個はないから
              #  print "len: $len, char: $char<br>\n";  # デバッグ用
            $i_i++;  # lenの土台 0 12 の0の位置を上げる
            $my_i += 2;  # 全角を2 半角を1としてカウント
            $mi_ii++;  # 全角専用カウント
              #  print unpack("H*", $char), "\n";
            push @return_arr, $char;
            $i_i += $len;  # クリックされた回数をカウント 0+1 len = 2 は3 めの座標            
            $i_i++;        # ascci用に次の座標を指しておく    全角半角の総数が出る    
        }
        if ($i_i >= $total) {
            $err_split = "err_split";  # 分割エラーのフラグを設定
            last;  # 文字列の終わりに到達したらループを終了
        }
    }
    if ($my_fast_Rage != 1) {  # 先頭が全角で始まっていないかどうか全角 = 1 半角で始まっても出さない。
        $my_fast_Rage = 0;  # 先頭が全角で始まっていないかどうか全角 = 1 半角で始まっても出さない。
    }
    push @count_1arr, $i_i-1;  # 最後のクリックされた回数を配列に追加 終わりは次の開始で+1されている
    ###################################
    #   = $my_p_loop_c; # 何ライン到達したか全角2 半角1として$p_haba_mojiをクリヤーした数でカウントされる
    #  = $my_i; # 全角+半角回数をカウント
    #  = $mi_i; # 半角専用カウント
    #  = $mi_ii; # 全角専用カウント
    #  = $my_fast_Rage; # 先頭が全角で始まっていないかどうか全角 = 1 半角半角 = 0;
    ###################################
    if ($fast_retun_utf == 0) {  # クリックされた回数をカウントする変数全角を2 半角を1としてカウントされる
        return @return_arr;  # 分割された文字列の配列を返す
    } 
    #$### セカンドミッション
    #  print のないところではまだ動かせない。########################################
    print "分割結果: my_i: $my_i, mi_i: $mi_i, mi_ii: $mi_ii, my_fast_Rage: $my_fast_Rage<br>\n";  # デバッグ用
    print "分割エラーのフラグ: $err_split<br>\n";  # デバッグ用
    # 分割された文字列の数を表示
    print "分割された文字列の数: $#return_arr<br>\n";  # デバッグ用
    print "分割された位置: @count_1arr<br>\n";  # デバッグ用
    my $i_2 = 0;  # 行番号をリセット
    my @return_Formatted_arr = ();  # フォーマットされた文字列を格納する配列
    foreach my $j (@count_1arr) {
        if ($j == 0) {
            next;  # クリックされた回数が0の場合はスキップ
        } elsif ($j < $i_2) {
            my $k = $j-$i_2;
            print "i_2: $i_2, j: $j, j-i: $k<br>\n";  # デバッグ用
            my $new_str = substr($str, $i_2, $k);
            $i_2 = $j;
            push @return_Formatted_arr, $new_str;  # フォーマットされた文字列を配列に追加
            print "分割された文字列: $new_str<br>\n";  # デバッグ用
            next;
        }
    }
    return @return_Formatted_arr;  # フォーマットされた文字列の配列を返す
}
#+++++++++++++++++++++++++++++++++++++

# &test_sub(); # 分割テストを実行
#-----------------------------------------------------------
print "分割された文字列の数: $#new_data_arr<br>\n";  # 分割された文字列の数を表示
print @new_data_arr;  # 分割された文字列を表示
print "<br>終わり<br>\n";  # デバッグ用
#+++++++++++++++++++++++++++++++++++++
&my_test_sub(); # 分割テストを実行
#+++++++++++++++++++++++++++++++++++++
sub my_test_sub {
print "# テスト<br>\n";  # デバッグ用
#$err_split = "壊れるかどうか<br>\n"; # 分割エラーのフラグを初期化 見んかったことにしよう。
my @tokens = &split_utf8_bytes("A\x01BあC");
print "よけいなのがでる<br>\n";#
@new_data_arr = (@tokens);  # 分割された文字列を新しい配列に格納
# print $#err_split, "これは-1が帰っている<br>\n";  # デバッグ用 分割エラーのフラグを表示
#print "$#tokens 結果。<br>\n";  # 分割された文字列の数を表示
#print "結果: ", join(" | ", map { unpack("H*", $_) } @tokens), "<br>\n";
#print "$#new_data_arr: ", scalar(@new_data_arr), "<br>\n";  # 分割された文字列の数を表示
print "成功: ", join(" | ", map { unpack("H*", $_) } @new_data_arr), "<br>\n";  # 分割された文字列を表示
# 分割された文字列を配列に追加
print "@new_data_arr<br>\n";  # デバッグ用 元の文字コードが化けてしまってるこれが化けて一致できず
}
#+++++++++++++++++++++++++++++++++++++
#-----------------------------------------------------------
print "end of the script<br>\n";  # デバッグ用
#+++++++++++++++++++++++++++++++++++++
print <<"EOF";
</body>
</html>
EOF
exit;
# __END__

$owari = @new_data_arr; # 最後の行を取得
@rede_data_arr = @new_data_arr; # 新しい配列に置き換え
}
#-----------------------------------------------------------
&page_no(); # ページ番号の処理を実行
sub page_no {
    my $ii = 0; # ページ番号のカウンタ
    my @ii_inner = ();
    my $dd_cunt = 0; # 行番号のカウンタ
    my $bak_i = 0;
    my $iip_set_c = $my_base_w_lain; #変えながら行幅が入っていく行数 次が発生する前なら変えられる
    my $iip_k0 = 0;
    my $iip_k = $my_base_w_lain;
    my $iip_in_s = $my_base_w_lain;#幅が終わる前なら縮小出来る
    my $inner_chege = 0;
    my $mtemp = "";
    my $mtemp_arr = ();
    my $up_genten = 0;
    @m_c_arr = (); # 0~10の配列を作成
    my $ii_bak = 0;
    my $kai = 1;
    my $i_stato_h = 0;
    my $laine_tyu_f = 0;
    for (my $i = 0; $i < @rede_data_arr; $i++) {
        if ($iip_set_c <= $i){
            $iip_in_s = $my_base_w_lain;
            $up_genten = $i;
            $iip_set_c = $up_genten + $iip_in_s;        
            $ii_bak = $ii;
            $ii++; # ページ  
            if ($ii_bak != $ii) {$kai = 0;} else {$kai = 1;}     
            $iip_k0 = 0;  # 同じページの幅変更をロック解除     
        }
        if ($rede_data_arr[$i] =~ m/^§P([0-9]{1,2})\s?/i) {
            if ($rede_data_arr[$i] =~ /\s/i){
                @mtemp_arr = split(/\s/, $rede_data_arr[$i]);  # " "で分割
            } else {
                @mtemp_arr = ($rede_data_arr[$i]);  # 分割せずにそのまま
            }
            @ii_inner = split(/[Pp]/,$mtemp_arr[0]);  # "P"で分割 dd
            if($iip_k0 == 0){
                $iip_in_s = $ii_inner[1];  # 行番号を変更1ローテション後から数値が有効になる
                $iip_k = $iip_in_s;  # 行番号を変更
                $iip_k0 = 1;
            }        
           # $inner_chege = 1;
            shift @mtemp_arr;  # 最初の要素を削除
            $rede_data_arr[$i] = join(" ", @mtemp_arr);  # 残りの要素を再結合
        }
        if ($kai == 0 && $ii_bak != $ii) {  # ページ番号が変わったとき   
            if ($kai == 0) {
                push(@m_c_arr, $i_stato_h."P".$iip_k."P".$ii_bak);  # "§P?dd"+"P"+行番号 で始まる行を配列に追加            
                $i_stato_h = $i;  # ページ番号の開始位置を記録
                $iip_k = $my_base_w_lain;
                $iip_in_s = $my_base_w_lain;
                $inner_chege = 0; 
                $kai = 1;            
            }       
        } elsif($inner_chege == 1) {        
            $rede_data_arr[$i] ="<h3>Err line spase.</h3>".join(" ", @mtemp_arr);  # 残りの要素を再結合
            $bak_i = $i;
            $inner_chege = 0;
        }        
        if ($iip_in_s != 0){   # ローテーションの中であればページ幅を変更できるが回数が越していても小さくする
            $iip_set_c = $up_genten + $iip_in_s;
            $iip_k = $iip_in_s;
            $iip_in_s = 0;
        } 
        if ($rede_data_arr[$i] =~ /^§§/) {
            $rede_data_arr[$i] =~ s/^§§//;  # 行頭の"§§"を削除
            $rede_data_arr[$i] = "<h1>$rede_data_arr[$i]</h1>";  # "§§"を<h1>タグに置き換えタイトル化
        } elsif ($rede_data_arr[$i] =~ /^§∮/) {
            $rede_data_arr[$i] =~ s/==/" alt="image_max700" width="300px">/ig; 
            $rede_data_arr[$i] =~ s/=([1-7][0-9][0-9]|700)=/" alt="image_max700" width="$1px">/ig; 
            $rede_data_arr[$i] =~ s/§∮/<img src="material\/imge\//g;  # 行頭の"§∮"を削除
            $rede_data_arr[$i] .="<br>\n";  # 画像の後に改行を追加
        } elsif ($rede_data_arr[$i] =~ /^§/) {
            $rede_data_arr[$i] =~ s/^§//;  # 行頭の"§"を削除
            $rede_data_arr[$i] = "<h2>$rede_data_arr[$i]</h2>";  # "§"を<h2>タグに置き換えサブタイトル化
        } elsif ($rede_data_arr[$i] =~ /^ /) {
           # $rede_data_arr[$i] =~ s/^ //;  # 行頭の" "を削除([0-9]{1,2})\s?/i) { 行頭は を入れておく。
            $laine_tyu_f = 1;  # 行頭に全角スペースがある場合はフラグを立てる
            $rede_data_arr[$i] = "<p>$rede_data_arr[$i]";  # その他の行は<p>タグで囲む
        } elsif ($laine_tyu_f == 1) {  # 行末に全角スペースがある場合
            if ($rede_data_arr[$i] =~ / $/){
                $rede_data_arr[$i] =~ s/ $//;  # 行末の" "を削除
                $laine_tyu_f = 0;  # 行末に全角スペースがある場合はフラグを下ろす
                $rede_data_arr[$i] .= "</p>";  # 行末に</p>タグを追加
            } else {
                $rede_data_arr[$i] ="$rede_data_arr[$i]<br>";
            }
        } else {
             # else は何もしない。
        }
    } 
    if ($laine_tyu_f == 1) {  # 行末に全角スペースがある場合
        $rede_data_arr[$#rede_data_arr] .= "</p>";  # 最後の行に</p>タグを追加
    }
    $rede_pegi_max = $#rede_data_arr;  # ページの最大数を取得
}#-----------------------------------------------------------print "@m_c_arr<br>\n";  # デバッグ用
# fuder();
# $rede_data_str = join("<br>\n", @rede_data_arr);
##------------------------------------
# ページ送りの処理配列取り込み
&pegi_no2(); # ページ送りの処理を実行
sub pegi_no2 {
    $stat_i = 0; # 初期値
    @m_c_lain = (); # ページ送りのための配列を初期化「収録配列」
    # "§_?dd"で始まる行を抽出して配列に格納(@m_c_arr, §P(0~99)"P"(行番号))
    if ($#m_c_arr < 0) {
        @m_c_arr = ("0P0P0");  # ページ配列がないときは初期値を設定
    }
    my $iix = 0;
    my $m_c_t22 = 0;  # ページ番号の初期値
    if ($#m_c_arr > 0) {
        for my $i (0 .. $#m_c_arr) {
            my @m_c_t1 = split(/P/, $m_c_arr[$i]);  # "P"で分割 "P12P34"のような形式を分割
            # "§_?dd"の形式を保持 P,標準行数,行番号 
            my @m_c_t2 = @m_c_t1;  # 最後の要素の場合は次の要素がないのでそのまま      
            if ($i + 1 <= $#m_c_arr) {        
                @m_c_t2 = split(/P/, $m_c_arr[$i+1]);  # "P"で分割
                $m_c_t22 = $m_c_t2[2];  # ページ番号を取得
            } else {
                $m_c_t22 = $m_c_t1[1]+$m_c_t1[2];  # 1の終わりを2の始まりと仮定しておく
            }
            # "P"で分割した配列の要素を取得
            if($stat_i + $m_c_t1[1] > $#rede_data_arr){  #  ここでやってある
                my $new_base_w_lain = $#rede_data_arr - $stat_i;  # my_base_w_lainの値を調整
                push(@m_c_lain,"$stat_i:".$new_base_w_lain.":".$iix); # 小さい値のときは
                last; # "P"で分割     
            }else {
                push(@m_c_lain,"$stat_i:".$m_c_t1[1].":".$iix); # 小さい値のときは
                $iix++;  # 行番号をインクリメント
                $stat_i += $m_c_t1[1];  # 最大値を取得
                if ($#m_c_arr != $i){
                    next; # 次の要素へ
                }
            } 
            if ($i == $#m_c_arr){
                $m_c_t22 = $#rede_data_arr;
            }       
            while($stat_i < $m_c_t22 && $stat_i <= $#rede_data_arr){ #1と2の間は
                push(@m_c_lain,"$stat_i:".$my_base_w_lain.":".$iix); # 小さい値のときは
                $iix++;  # 行番号をインクリメント           
                my $my_base_w_lain0 = $#rede_data_arr - $stat_i;  # my_base_w_lainの値を調整
                if ($my_base_w_lain0 <= $my_base_w_lain){
                    if ($my_base_w_lain0 <= 0) {
                        last; # 0以下になったら終了
                    }
                }
                if ($stat_i + $my_base_w_lain >= $#rede_data_arr) {
                    $stat_i = $#rede_data_arr;  # 最大値を超えないように調整               
                    push(@m_c_lain,"$stat_i:".$my_base_w_lain0.":".$iix); # 小さい値のときは
                    last; # "P"で分割     
                } 
                $stat_i += $my_base_w_lain;  # 最大値を取得 
            }               
        }
    } else {
        # ページ配列がないとき 0:my_base_w_lain
        $stat_i = 0; # 初期値
        if($stat_i <= $my_base_w_lain){
            push(@m_c_lain,"$stat_i:".$#rede_data_arr.":".$iix.":"); # "P"で分割
            $iix++;  # 行番号をインクリメント  # "P"で分割
        } else {
            while($stat_i <= $#rede_data_arr){
                push(@m_c_lain,"$stat_i:".$my_base_w_lain.":".$iix.":"); # 小さい値のときは
                $iix++;  #    # "P"で分割
                $stat_i += $my_base_w_lain;  # 最大値を取得 
                if ($stat_i + $my_base_w_lain > $#rede_data_arr) {
                    $stat_i = $#rede_data_arr;  # 最大値を超えないように調整
                    my $new_base_w_lain = $#rede_data_arr - $stat_i;  # my_base_w_lainの値を調整
                    push(@m_c_lain,"$stat_i:".$new_base_w_lain.":".$iix.":"); # 小さい値のときは
                    last; # "P"で分割     
                }
            }
        }    
    }
    $inhp{"my_pagi"} = $#m_c_lain-1;  # ページの最大数を取得

}    # ページ送りのための配列を表示
    if ($inhp{"up_p"} eq "up_p") {
        $inhp{"my_p"} = $inhp{"my_p"} + 1;  # ページの最大数を取得
        if ($inhp{"my_p"} > $inhp{"my_pagi"} ) {
            $inhp{"my_p"} = $inhp{"my_pagi"}   # ページの最大数を超えた場合は0に戻す
        }
    }    # print "ページ送りのための配列: @m_c_lain<br>\n";  # デバッグ用
#-----------------------------------------------------------
#  フォームデコード
#-----------------------------------------------------------
sub parse_form {
	my ($buf,%in);
	if ($ENV{REQUEST_METHOD} eq "POST") {
		error('受理できません') if ($ENV{CONTENT_LENGTH} > $cf{maxdata});
		read(STDIN, $buf, $ENV{CONTENT_LENGTH});
	} else {
		$buf = $ENV{QUERY_STRING};
	}
	foreach ( split(/&/, $buf) ) {
		my ($key,$val) = split(/=/);
        $kye =~s/\0//g; # キーの無効化
        $val =~s/\0//g; # 値の無効化
        next unless defined $key && defined $val; # キーと値が定義されている場合のみ処理する。
		$val =~ tr/+/ /;
		$val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg;
		# 無効化
		$val =~ s/&/&amp;/g;
		$val =~ s/</&lt;/g;
		$val =~ s/>/&gt;/g;
		$val =~ s/"/&quot;/g;
		$val =~ s/'/&#39;/g;
		$val =~ s/\r\n/<br>/g;
		$val =~ s/\n/<br>/g;
		$val =~ s/\r/<br>/g;
		$in{$key} .= "\0" if (defined($in{$key}));
		$in{$key} .= $val;
        $inhp{$key} = $in{$key}; #グローバル化
	}
	return;
}
#-----------------------------------------------------------
sub error($message) {
    my $message = $_[0];  # エラーメッセージを受け取る
    # エラーメッセージを表示する関数
    # CGIスクリプトの出力を設定
print "Content-type:text/html\n\n";
print qq|
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>2画面構成</title>
    </head><body>
    <h1>エラー</h1>
    <h2>$message</h2>
    <p>エラーが発生しました。詳細: $message</p>
    </body>
</html>
|;
  #  die("Error: $message\n");
    # スクリプトを終了
    exit;
}
#-----------------------------------------------------------
$Script1 = <<'EOF';
   <script>
   // alert("JavaScriptが読み込まれました!1");
        var no_click = true; // クリックされていない状態を示すフラグ
        var failed = ""; // faile名画入る。
        var my_i = 0;  //Number(value);  // クリックされた回数をカウントする変数
        var my_c = 1;  // Number(value1);  // クリックされた回数を10倍にする変数value1;  // クリックされた回数を10倍にする変数
        var my_p = 0;  // Number(value3);  // ページの最大数を取得
        var rede_pegi_max = 1;  // Number(value2);  // ページの最大数を取得
        var my_base = "http://127.0.0.1/my_apach/story/"; // 初期値
   //     alert("my_i: " + my_i + ", my_c: " + my_c + ", rede_pegi_max: " + rede_pegi_max);
        // ページ読み込み時に実行される関数#### ページが読み込まれ読み込まれ時にしたの/html 前が成される
      // /  document.addEventListener("DOMContentLoaded", () => { //記録として実行はしない
      //  alert("DOMContentLoadedイベントが発火しました!");
      // /  fastRedirect(); // ページ読み込み時にfastRedirect関数を呼び出す
      // /  });
        //
        // ページ遷移の関数
        // ページ遷移のURLを生成 最初は暫定値が入っていてクリックされたら更新される
       // base my_base
        // ページ遷移の関数
     //   alert("ここは終わりの部分です。");
    </script>
EOF
#-----------------------------------------------------------
$Script2 = <<'EOF';
<script>    
    function checkClick() {
        // クリックされたらフラグをfalseにする
        if (no_click == true) { // クリックされていない状態
            no_click = false;
            document.getElementById("butt1").value = "OFF Active"; // ボタンの値を変更           
            document.getElementById("butt1").style.background = "blue";


        //    alert("クリックされません");
        } else {
            no_click = true; // クリックされたらフラグをtrueに戻す
            document.getElementById("butt1").value = "ON Active"; // ボタンの値を変更
            document.getElementById("butt1").style.background = "green";
                    } 
       // alert("クリックフラグが切り替わりました! no_click: " + no_click);          
    }
    // クリックイベントを監視    
    document.addEventListener('click', function(event) {
      //  alert("JavaScriptが読み込まれました!4");
        let x = 0; // クリック位置のX座標
        let y = 0; // クリック位置のY座標            
     //   alert("クリックイベントが発火しました!onclick: " + no_click);
        // 左クリックかどうかを確認
        if (event.button === 0) { // 0は左クリックを意味します
            x = event.clientX; // ビューポート内のX座標 if ないだからでないことがある
            y = event.clientY; // ビューポート内のY座標
      //      alert("クリック位置: X=" + x + ", Y=" + y);
            if (y < 55) {
                if (x < 400){return;} // クリック位置が画面上部にある場合は何もしない
                no_click = false; // クリック位置が画面上部にある場合はフラグをfalseに設定
                document.getElementById("butt1").value = "OFF Active"; // ボタンの値を変更
                document.getElementById("butt1").style.background = "blue"; // ボタンの背景色を変更
                checkClick(); // クリック位置が画面上部にある場合はcheckClick関数を呼び出す
                return; // クリック位置が画面上部の場合は何もしない
            }else{
                if (no_click == false) {
        //            alert("クリックイベントが無効化されています。");
                    return; // クリックイベントが無効化されている場合は何もしない
                } 
                midolu_renge(x, y); // midolu_renge関数を呼び出す
       //         alert("クリックイベントが処理されました!");//
            }           
        } else {
            return; // 左クリック以外は何もしない
        }           
    });    
</script>
<script>
    // midolu_renge関数を定義
    function midolu_renge(m_x, m_y) {
    //    alert("midolu_renge関数が呼び出されました! クリック位置: X=" + m_x + ", Y=" + m_y+"no_click: " + no_click);
        // クリック位置の座標を取得
        if( no_click==false ){   
            alert("midolu_renge関数が終了しました!"+ " クリック位置: X=" + m_x + ", Y=" + m_y);
            return; // クリックflagがないときは何もしない
        } else {
      //      alert("クリックflagがtrueになっています。クリック位置: X=" + m_x + ", Y=" + m_y);
            // クリック位置の座標を取得
      //      alert("window.innerWidth: " + window.innerWidth);
      //      alert("window.innerHeight: " + window.innerHeight);
            //ここまではok
            if (m_x < (window.innerWidth / 4)) {
      //          alert("左側の画面がクリックされました。");
                if (my_p > 0) {
                    my_p -= 1;  // ページ数を減らす
                    if (my_p < 1) {
                        my_p = 0; // ページ送りの最小値を0に設定
                    }
                }else {
                    my_p = 0; // ページ送りの最小値を0に設定
                    return; // ページ送りの最小値を0に設定
                }
                navigateToPage(); // ページ遷移
            } else if( m_x < (window.innerWidth / 2)) {
        //        alert("中央の画面がクリックされました。");
                if (my_p < Math.floor(rede_pegi_max)) {
                    my_p += 1;  // ページ数を増やす += my_c;  // クリックされた回数をカウント
                    if (my_p > Math.floor(rede_pegi_max)) { // ページ送りの最大値を超えないように調整
                        my_p = Math.floor(rede_pegi_max); // ここでは100を最大値としています
                    }
                } else {
                    my_p = Math.floor(rede_pegi_max); // ページ送りの最大値を超えないように調整
                }
                navigateToPage(); // ページ遷移
            } else {
          //      alert("右側の画面がクリックされました。");
                            // 左クリック以外の処理
                if (no_click == true) {
                    no_click = false; // クリックされていない状態にする
                    document.getElementById("butt1").value = "OFF Active"; // ボタンの値を変更
                    document.getElementById("butt1").style.background = "blue"; // ボタンの背景色を変更
                }
            }
            // クリックイベントをキャンセル    
        }
    return; // クリックイベントをキャンセル
    }
    </script>
<script>
    function navigateToPage() {
    //    alert("これはmy_i: " + my_i + ", my_c: " + my_c + ", rede_pegi_max: " + rede_pegi_max);
        var my_uri = "http://127.0.0.1/my_apach/story/Alberto_story_pl.cgi?failed="+ failed +"&my_i=" + my_i + "&my_c=" + my_c + "&my_p=" + my_p;  // ページ遷移のURLを生成
    //    alert("ページ遷移のURL: " + my_uri);
        window.location.href = my_uri;  // ページ遷移
        return ; // スクリプトを終了
    }
</script>
EOF
#-----------------------------------------------------------
$Script3 = <<'EOF';
<script>    
    function checkClick() {
        // クリックされたらフラグをfalseにする
        if (no_click == true) { // クリックされていない状態
            no_click = false;
            document.getElementById("butt1").value = "OFF Active"; // ボタンの値を変更           
            document.getElementById("butt1").style.background = "blue";


        //    alert("クリックされません");
        } else {
            no_click = true; // クリックされたらフラグをtrueに戻す
            document.getElementById("butt1").value = "ON Active"; // ボタンの値を変更
            document.getElementById("butt1").style.background = "green";
                    } 
       // alert("クリックフラグが切り替わりました! no_click: " + no_click);          
    }
    // クリックイベントを監視    
    document.addEventListener('click', function(event) {
      //  alert("JavaScriptが読み込まれました!4");
        let x = 0; // クリック位置のX座標
        let y = 0; // クリック位置のY座標            
     //   alert("クリックイベントが発火しました!onclick: " + no_click);
        // 左クリックかどうかを確認
        if (event.button === 0) { // 0は左クリックを意味します
            x = event.clientX; // ビューポート内のX座標 if ないだからでないことがある
            y = event.clientY; // ビューポート内のY座標
      //      alert("クリック位置: X=" + x + ", Y=" + y);
            if (y < 55) {
                if (x < 400){return;} // クリック位置が画面上部にある場合は何もしない
                no_click = false; // クリック位置が画面上部にある場合はフラグをfalseに設定
                document.getElementById("butt1").value = "OFF Active"; // ボタンの値を変更
                document.getElementById("butt1").style.background = "blue"; // ボタンの背景色を変更
                checkClick(); // クリック位置が画面上部にある場合はcheckClick関数を呼び出す
                return; // クリック位置が画面上部の場合は何もしない
            }else{
                if (no_click == false) {
        //            alert("クリックイベントが無効化されています。");
                    return; // クリックイベントが無効化されている場合は何もしない
                } 
                midolu_renge(x, y); // midolu_renge関数を呼び出す
       //         alert("クリックイベントが処理されました!");//
            }           
        } else {
            return; // 左クリック以外は何もしない
        }           
    });    
</script>
<script>
    // midolu_renge関数を定義
    function midolu_renge(m_x, m_y) {
    //    alert("midolu_renge関数が呼び出されました! クリック位置: X=" + m_x + ", Y=" + m_y+"no_click: " + no_click);
        // クリック位置の座標を取得
        if( no_click==false ){   
            alert("midolu_renge関数が終了しました!"+ " クリック位置: X=" + m_x + ", Y=" + m_y);
            return; // クリックflagがないときは何もしない
        } else {
      //      alert("クリックflagがtrueになっています。クリック位置: X=" + m_x + ", Y=" + m_y);
            // クリック位置の座標を取得
      //      alert("window.innerWidth: " + window.innerWidth);
      //      alert("window.innerHeight: " + window.innerHeight);
            //ここまではok
            if (m_x < (window.innerWidth / 4)) {
      //          alert("左側の画面がクリックされました。");
                if (my_p > 0) {
                    my_p -= 2;  // ページ数を減らす
                    if (my_p < 1) {
                        my_p = 0; // ページ送りの最小値を0に設定
                    }
                }else {
                    my_p = 0; // ページ送りの最小値を0に設定
                    return; // ページ送りの最小値を0に設定
                }
                document.getElementById("my_p_f").value = my_p; // ページ数を更新
                navigateToPage(); // ページ遷移
            } else if( m_x > (window.innerWidth / 3) && m_x < (window.innerWidth / 3) * 2) {
        //        alert("中央の画面がクリックされました。");
                        if (no_click == true) {
                    no_click = false; // クリックされていない状態にする
                    document.getElementById("butt1").value = "OFF Active"; // ボタンの値を変更
                    document.getElementById("butt1").style.background = "blue"; // ボタンの背景色を変更
                }
            } else {
          //      alert("右側の画面がクリックされました。");
                            // 左クリック以外の処理
            // クリックイベントをキャンセル 
                             if (my_p < Math.floor(rede_pegi_max)) {
                    my_p += 2;  // ページ数を増やす += my_c;  // クリックされた回数をカウント
                    if (my_p > Math.floor(rede_pegi_max)) { // ページ送りの最大値を超えないように調整
                        my_p = Math.floor(rede_pegi_max); // ここでは100を最大値としています
                    }
                } else {
                    my_p = Math.floor(rede_pegi_max); // ページ送りの最大値を超えないように調整
                }
                navigateToPage(); // ページ遷移 
            }     
        }
    return; // クリックイベントをキャンセル
    }
    </script>
<script>
    function navigateToPage() {
    //    alert("これはmy_i: " + my_i + ", my_c: " + my_c + ", rede_pegi_max: " + rede_pegi_max);
        var my_uri = "http://127.0.0.1/my_apach/story/Alberto_story_pl.cgi?failed="+ failed +"&my_i=" + my_i + "&my_c=" + my_c + "&my_p=" + my_p;  // ページ遷移のURLを生成
    //    alert("ページ遷移のURL: " + my_uri);
        window.location.href = my_uri;  // ページ遷移
        return ; // スクリプトを終了
    }
</script>
EOF
#-----------------------------------------------------------
if ($hyouji eq "manga") {
    # マンガのHTMLヘッダー部分を出力)
    &manga_html(); # HTMLのヘッダー部分を出力
    exit;
} 
#-----------------------------------------------------------
# ここからは普通のHTMLのヘッダー部分を出力  
#普通のhtml

#-----------------------------------------------------------# HTMLのヘッダー部分を出力
print "Content-type:text/html\n\n";
print qq|<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>2画面構成</title>
    <style>
        .container {
            display: flex;
            height: 100vh;
        }
        .left, .right {
            flex: 1;
            padding: 20px;
        }
        .left {
            background-color: #f0f0f0;
        }
        .right {
            background-color: #d0d0d0;
        }
        #butt1 {
            width: 100px;
            height: 30px;
            background-color: green;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        #my_p1 {
            width: 50px;
            height: 24px;
            background-color:green;
            color: yellow;
            border: 1px solid #ccc;
            border-radius: 5px;
        }
    </style>
    $Script1
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
</head>
|; # HTMLのヘッダー部分を出力
print qq(
<body><!-- ページの内容 -->
<input type="hidden" name="my_i" id="inputField" size="3" value="$inhp{"my_i"}">
<input type="hidden" name="my_c" id="inputField1" size="3"  value="$inhp{"my_c"}">
<input type="hidden" name="my_p" id="inputField2" size="3"  value="$inhp{"my_p"}">
<input type="hidden" name="my_pagi" id="inputField3" size="3"  value="$inhp{"my_pagi"}">
<input type="hidden" name="my_pagi" id="inputField4" size="3"  value="$inhp{'failed'}">
<input type="hidden" name="my_base" id="inputField_base" value="$inhp{"my_base"}">
<span id="data_display"></span>
<script>
    // ページが読み込まれたときに実行される関数
    window.onload = function() {
        // inputフィールドの値を取得
        var inputValue = document.getElementById('inputField').value;
        var inputValue1 = document.getElementById('inputField1').value;
        var inputValue2 = document.getElementById('inputField2').value;
        var inputValue3 = document.getElementById('inputField3').value;
        var inputValue4 = document.getElementById('inputField4').value;
        var inputValue_base = document.getElementById('inputField_base').value;
        my_i = (inputValue) ? parseInt(inputValue) : 0; // 数値に変換
        my_c = (inputValue1) ? parseInt(inputValue1) : 1; // 数値に変換
        my_p = (inputValue2) ? parseInt(inputValue2) : 0; // 数値に変換
        rede_pegi_max = (inputValue3) ? parseInt(inputValue3) : 1; // 数値に変換
        failed = (inputValue4) ? inputValue4 : ""; // 文字列に変換
        my_base = inputValue_base; // 初期値
        // クリックされた回数を表示       
        // 取得した値を表示
    };
</script>
<div class="header">
<table><tr><td>
    <form action="Alberto_story_pl.cgi" method="get">
  <!--  <input type="text" name="my_i1" size="3" id="my_i1" value="my_i">-->
    <input type="text" id="my_p_f" size="3" name="my_p" size="3" id="my_p1" value="$inhp{"my_p"}">
  <!--  <input type="text" name="my_c1" size="3" id="my_i1" value="my_c">-->
    <input type="hidden" name="up_p" size="3" id="my_pagi1" value="up_p">
    <input type="submit" value="ページ送り">
</form></td><td>
<input type="button" id="butt1" value="ON Active" onclick="checkClick()">
</td><td> 
);
#-----------------------------------------------------------
# ページ送りのための配列を生成
print qq(<a href="$cgi_uri">STO</a> );
my $ii_staso0 = 0;  # ページ送りの開始位置
my $ii_midolu0 = 0;  # ページ送りの中央位置
my $ii_end0 = 0;  # ページ送りの終了位置
my $ii_machi = $inhp{"my_p"};  # 現在のページ番号
# エラー条件 $inhp{{"my_p"} < 0 || $inhp{"my_p"} > $#m_c_lain}
# エラー条件 $#m_c_lain < 0
if (($inhp{"my_p"} == 0 || $#m_c_lain) && ($inhp{"my_p"} < 10 || $#m_c_lain < 10)) { 
     # ページ番号が最大値の場合 9=0~9までは可変長
    $ii_staso0 = 0;  # ページ番号が最大値の場合は9を引いた値に設定
    $ii_midolu0 = $inhp{"my_p"};  # ページ番号が最大値の場合は1に設定
    $ii_end0 = $#m_c_lain-1;  # ページ番号が最大値の場合は最大値に設定
}
# ここからは 10個以上のpがあって5以上指定されたとき
# 総数の-5までの表示10可能な変動範囲で5M中心がにいる
if ($inhp{"my_p"} <= $#m_c_lain - 5 && $#m_c_lain >= 10) {
    if ($inhp{"my_p"} < 5) {  # ページ番号が5未満の場合
        $ii_staso0 = 0;  # ページ番号が5未満の場合は0に設定
        if ($inhp{"my_p"} >= 5) {
        $ii_midolu0 = 5;  # ページ番号が5未満の場合は1に設定
        } else {
            $ii_midolu0 = $inhp{"my_p"};  # ページ番号が5未満の場合は1に設定        
        }
        $ii_end0 = 10-1;  # ページ番号が5未満の場合は5を加算0から入るから
    } else {  # ページ番号が5以上の場合
        $ii_staso0 = $inhp{"my_p"} - 4;  # ページ番号が5以上の場合は4を引いた値に設定
        $ii_midolu0 = 5;  # ページ番号が5以上の場合は1に設定
        $ii_end0 = $inhp{"my_p"} + 5;  # ページ番号が5以上の場合は5を加算
    } 
} elsif ($inhp{"my_p"} > 5 && $inhp{"my_p"} >= $#m_c_lain - 6 && $#m_c_lain >= 10) { 
    # 表示を上位に移動できるようにして総数が10以上のとき$inhp{"my_p"} <= $#m_c_lain - 6以上となるとき
     # ページ番号が5以上10以下の場合
    $ii_staso0 = $#m_c_lain - 10;  # ページ番号が5以上10以下の場合は5を引いた値に設定  
    $ii_midolu0 =(5-($#m_c_lain - $inhp{"my_p"})) + ($#m_c_lain - 5);  # ページ番号が5以上10以下の場合は1に設定 上に移動していく
    $ii_end0 = $#m_c_lain-1;  # ページ番号が5以上10以下の場合は4を加算
}
# ページ送りのための配列を表示
# print qq($ii_staso0 ペ$ii_midolu0 ージ送りのための配列:$ii_end0 @m_c_lain<br>\n);  # デバッグ用
for my $i ($ii_staso0 .. $ii_end0) {
    my @m_c_t = split(/:/, $m_c_lain[$i]);  # ":"で分割 
    my $cgi_urib = $cgi_uri.'?failed='.$inhp{'failed'}.'&my_p='.$m_c_t[2].'&my_c='.$m_c_t[1].'&my_i='.$m_c_t[0];  # ページリンクのURLを生成   
    if ($ii_machi == $i) {  # 現在のページを強調表示     
        print qq(<b><a href="$cgi_urib">P$i:$m_c_t[1]:$m_c_t[0]</a></b>);  # 現在のページを強調表示
    } else {
        print qq(<a href="$cgi_urib">P$i:$m_c_t[1]:$m_c_t[0]</a>);  # ページリンクを表示
    }
    print " ";  # スペースを追加
}
print qq(</td></tr></table>
</div>
    <div class="container">
        <div class="left">		
);
# ページ送りの処理
print qq(
<script> 
var my_i = $inhp{"my_i"};  // クリックされた回数をカウントする変数
var my_c = $inhp{"my_c"};  // クリックされた回数を10倍にする変数
var my_p = $inhp{"my_p"};  // ページの最大数を取得
var rede_pegi_max = $inhp{"my_pagi"};  // ページの最大数を取得
var failed = "$inhp{'failed'}"; // faile名画入る。
var my_base = "http://127.0.0.1/my_apach/story/"; // 初期値
var no_click = true; // クリックされていない状態を示すフラグ
var my_uri = "http://127.0.0.1/my_apach/story/Alberto_story_pl.cgi?my_i=" + my_i + "&my_c=" + my_c + "&my_p=" + my_p;  // ページ遷移のURLを生成
</script>
);
# ページ送りの処理
print qq(<div class="rede_data">);
my @read_my_p = split(/:/, $m_c_lain[$inhp{"my_p"}]);  # ページ送りのための配列を分割
chomp(@read_my_p);  # 改行コードを削除
my $myhensa = $read_my_p[1];  # ページ送りのための配列から行数を取得
my @it_image = ();  # 画像の配列を初期化
my $my_ip = $inhp{"my_i"};  # ページ送りのための配列から行番号を取得
    for (my $i = 0; $i < $read_my_p[1]; $i++) {        
    #    print "データ $i<br>";
        my $data = $rede_data_arr[$i+$read_my_p[0]];  # ページ送りのための配列からデータを取得
        if ($data =~ m/<img\s/i) {push(@it_image, $data);}  # 画像が含まれている場合は配列に追加
        print "$rede_data_arr[$i+$read_my_p[0]]\n";  # ページ送りのための配列からデータを表示
    }
            print qq|<p>   現在のページ番号: $inhp{'my_p'}</p>|;  # ページ番号が一致しない場合のエラーメッセージ
print qq(</div>);
print qq(           
        </div>
        <div class="right"><!-- 右側のコンテンツ -->
@it_image<br><br>
);
print qq(
<textarea name="example" rows="15" cols="92">);
my @read_my_p = split(/:/, $m_c_lain[$inhp{"my_p"}]);  # ページ送りのための配列を分割
chomp(@read_my_p);  # 改行コードを削除
my $myhensa = $read_my_p[1];  # ページ送りのための配列から行数を取得 = @rede_data_arr
my $my_ip = $inhp{"my_i"};  # ページ送りのための配列から行番号を取得
# ページ送りのための配列からデータを表示
    for (my $i = 0; $i < $read_my_p[1]; $i++) {        
        if (1 == 1){
            print "$rede_data_arr[$i+$read_my_p[0]]\n";
        } else {
            print "$rede_data_arr[$i+$read_my_p[0]]\n";
        };
    }       
print qq(</textarea><br>\n);
print qq(
        <p>ページ送りのための配列: @m_c_lain</p>
        <p>ページ番号: $inhp{"my_p"}</p>
        <p>ページの最大数: $inhp{"my_pagi"}</p>
        <p>クリックされていない状態: no_click = $inhp{"no_click"}</p>
        </div>
    </div>
    </body>
    $Script2
</html>
);
exit;
# ページ送りのための配列を表示

############################################################################
# HTMLのヘッダー部分を出力
# マンガのHTMLヘッダー部分を出力
sub manga_html {
print "Content-type:text/html\n\n";
print qq|
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>2画面構成</title>
    <style>
        body {
            margin: 0;
            font-family: Arial, sans-serif;
        }
        p {
            text-align:left;
            margin: 0;
            padding: 10px;
        } 
        h1 {text-align:left;}
        h2 {text-align:left;}
        .container {
            width: 100%;;
            height: 100vh;
        }       
        .left, .right {        
            padding: 20px;
        }
        .left {
            background-color: #f0f0f0;
            width:50%;
            high:100%; 
            vertical-align: top;
            text-align:right;
        }
        .innar_left {
        }
        .right {
            background-color: #d0d0d0;
            width:50%;
            high:100%; 
            vertical-align: top;
            text-align:left;
        }
        .innar_right {
        }
        #butt1 {
            width: 100px;
            height: 30px;
            background-color: green;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        #my_p1 {
            width: 50px;
            height: 24px;
            background-color:green;
            color: yellow;
            border: 1px solid #ccc;
            border-radius: 5px;
        }
    </style>
$Script1
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
</head>
|; # HTMLのヘッダー部分を出力
print qq(
<body><!-- ページの内容 -->
<div class="header">
<input type="hidden" name="my_i" id="inputField" size="3" value="$inhp{"my_i"}">
<input type="hidden" name="my_c" id="inputField1" size="3"  value="$inhp{"my_c"}">
<input type="hidden" name="my_p" id="inputField2" size="3"  value="$inhp{"my_p"}">
<input type="hidden" name="my_pagi" id="inputField3" size="3"  value="$inhp{"my_pagi"}">
<input type="hidden" name="failed" id="inputField4" size="3"  value="$inhp{'failed'}">
<input type="hidden" name="my_base" id="inputField_base" value="$inhp{"my_base"}">
<span id="data_display"></span>
<script>
    // ページが読み込まれたときに実行される関数
    window.onload = function() {
        // inputフィールドの値を取得
        var inputValue = document.getElementById('inputField').value;
        var inputValue1 = document.getElementById('inputField1').value;
        var inputValue2 = document.getElementById('inputField2').value;
        var inputValue3 = document.getElementById('inputField3').value;
        var inputValue4 = document.getElementById('inputField4').value;
        var inputValue_base = document.getElementById('inputField_base').value;
        my_i = (inputValue) ? parseInt(inputValue) : 0; // 数値に変換
        my_c = (inputValue1) ? parseInt(inputValue1) : 1; // 数値に変換
        my_p = (inputValue2) ? parseInt(inputValue2) : 0; // 数値に変換
        rede_pegi_max = (inputValue3) ? parseInt(inputValue3) : 1; // 数値に変換
        failed = (inputValue4) ? inputValue4 : ""; // 文字列に変換
        my_base = inputValue_base; // 初期値
        // クリックされた回数を表示       
        // 取得した値を表示
    };
</script>
<table><tr><td>
    <form action="Alberto_story_pl.cgi" method="get">
  <!--  <input type="text" name="my_i1" size="3" id="my_i1" value="my_i">-->
    <input type="text" id="my_p_f" size="3" name="my_p" size="3" id="my_p1" value="$inhp{"my_p"}">
  <!--  <input type="text" name="my_c1" size="3" id="my_i1" value="my_c">-->
    <input type="hidden" name="up_p" size="3" id="my_pagi1" value="up_p">
    <input type="hidden" name="failed" size="3" id="my_pagi1" value="$inhp{'failed'}">
    <input type="submit" value="ページ送り">
</form></td><td>
<input type="button" id="butt1" value="ON Active" onclick="checkClick()">
</td><td> );
print qq(<a href="$cgi_uri">STO</a> );#-----------------------------------------------------------
# ページ送りのための配列を生成
my $ii_staso02 = 0;  # ページ送りの開始位置
my $ii_midolu02 = 0;  # ページ送りの中央位置
my $ii_end02 = 0;  # ページ送りの終了位置
my $ii_machi2 = $inhp{"my_p"};  # 現在のページ番号
# エラー条件 $inhp{{"my_p"} < 0 || $inhp{"my_p"} > $#m_c_lain}
# エラー条件 $#m_c_lain < 0
if (($inhp{"my_p"} == 0 || $#m_c_lain) && ($inhp{"my_p"} < 10 || $#m_c_lain < 10)) { 
     # ページ番号が最大値の場合 9=0~9までは可変長
    $ii_staso02 = 0;  # ページ番号が最大値の場合は9を引いた値に設定
    $ii_midolu02 = $inhp{"my_p"};  # ページ番号が最大値の場合は1に設定
    $ii_end02 = $#m_c_lain-1;  # ページ番号が最大値の場合は最大値に設定
}
# ここからは 10個以上のpがあって5以上指定されたとき
# 総数の-5までの表示10可能な変動範囲で5M中心がにいる
if ($inhp{"my_p"} <= $#m_c_lain - 5 && $#m_c_lain >= 10) {
    if ($inhp{"my_p"} < 5) {  # ページ番号が5未満の場合
        $ii_staso02 = 0;  # ページ番号が5未満の場合は0に設定
        if ($inhp{"my_p"} >= 5) {
        $ii_midolu02 = 5;  # ページ番号が5未満の場合は1に設定
        } else {
            $ii_midolu02 = $inhp{"my_p"};  # ページ番号が5未満の場合は1に設定        
        }
        $ii_end02 = 10-1;  # ページ番号が5未満の場合は5を加算0から入るから
    } else {  # ページ番号が5以上の場合
        $ii_staso02 = $inhp{"my_p"} - 4;  # ページ番号が5以上の場合は4を引いた値に設定
        $ii_midolu02 = 5;  # ページ番号が5以上の場合は1に設定
        $ii_end02 = $inhp{"my_p"} + 5;  # ページ番号が5以上の場合は5を加算
    } 
} elsif ($inhp{"my_p"} > 5 && $inhp{"my_p"} >= $#m_c_lain - 6 && $#m_c_lain >= 10) { 
    # 表示を上位に移動できるようにして総数が10以上のとき$inhp{"my_p"} <= $#m_c_lain - 6以上となるとき
     # ページ番号が5以上10以下の場合
    $ii_staso02 = $#m_c_lain - 10;  # ページ番号が5以上10以下の場合は5を引いた値に設定  
    $ii_midolu02 =(5-($#m_c_lain - $inhp{"my_p"})) + ($#m_c_lain - 5);  # ページ番号が5以上10以下の場合は1に設定 上に移動していく
    $ii_end02 = $#m_c_lain-1;  # ページ番号が5以上10以下の場合は4を加算
}
  # ページ送りのための配列を計算
# print qq($ii_staso02 ペ$ii_midolu02 ージ送りのための配列:$ii_end02 @m_c_lain<br>\n);  # デバッグ用
for my $i ($ii_staso02 .. $ii_end02) {
    my @m_c_t2 = split(/:/, $m_c_lain[$i]);  # ":"で分割 
    my $cgi_urib2 = $cgi_uri.'?failed='.$inhp{'failed'}.'&my_p='.$m_c_t2[2].'&my_c='.$m_c_t2[1].'&my_i='.$m_c_t2[0];  # ページリンクのURLを生成   
    if ($ii_machi2 == $i) {  # 現在のページを強調表示     
        print qq(<b><a href="$cgi_urib2">P$i:$m_c_t2[1]:$m_c_t2[0]</a></b>);  # 現在のページを強調表示
    } else {
        print qq(<a href="$cgi_urib2">P$i:$m_c_t2[1]:$m_c_t2[0]</a>);  # ページリンクを表示
    }
    print " ";  # スペースを追加
}
print qq(</td></tr></table>
<script> 
var my_i = $inhp{"my_i"};  // クリックされた回数をカウントする変数
var my_c = $inhp{"my_c"};  // クリックされた回数を10倍にする変数
var my_p = $inhp{"my_p"};  // ページの最大数を取得
var rede_pegi_max = $inhp{"my_pagi"};  // ページの最大数を取得
var failed = "$inhp{'failed'}"; // faile名画入る。
var my_base = "http://127.0.0.1/my_apach/story/"; // 初期値
var no_click = true; // クリックされていない状態を示すフラグ
var my_uri = "http://127.0.0.1/my_apach/story/Alberto_story_pl.cgi?failed="+ failed +"&my_i=" + my_i + "&my_c=" + my_c + "&my_p=" + my_p;  // ページ遷移のURLを生成
</script>
</div>
<table class="container"> 
  <tr>
    <td class="left"><!-- 左側のコンテンツ -->
        <div class="innar_left">      
);
# ページ送りの処理
my @read_my_p1 = split(/:/, $m_c_lain[$inhp{"my_p"} +1]);  # ページ送りのための配列を分割
chomp(@read_my_p1);  # 改行コードを削除
#my $myhensa = $read_my_p[1];  # ページ送りのための配列から行数を取得
#my @it_image1 = ();  # 画像の配列を初期化
#my $my_ip = $inhp{"my_i"};  # ページ送りのための配列から行番号を取得
my $my_p2 = $inhp{"my_p"}+1;  # ページ送りのための配列から行番号を取得
    for (my $i = 0; $i < $read_my_p1[1]; $i++) {        
    #    print "データ $i<br>";
       # my $data = $rede_data_arr[$i+$read_my_p[0]];  # ページ送りのための配列からデータを取得
       # if ($data =~ m/<img\s/i) {push(@it_image, $data);}  # 画像が含まれている場合は配列に追加
        print "$rede_data_arr[$i+$read_my_p1[0]]\n";  # ページ送りのための配列からデータを表示
    }
print qq|<p>   現在のページ番号: $my_p2</p>|;  # ページ番号が一致しない場合のエラーメッセージ

print qq(</div></td>
    <td class="right"><!-- 右側のコンテンツ -->
        <div class="innar_right">
);
my @read_my_p0 = split(/:/, $m_c_lain[$inhp{"my_p"}]);  # ページ送りのための配列を分割
chomp(@read_my_p0);  # 改行コードを削除
my $my_p0 = $inhp{"my_p"};  # ページ送りのための配列から行番号を取得
    for (my $i = 0; $i < $read_my_p0[1]; $i++) {        
        print "$rede_data_arr[$i+$read_my_p0[0]]\n";  # ページ送りのための配列からデータを表示
    }
print qq|<p>   現在のページ番号: $my_p0</p>|;  # ページ番号が一致しない場合のエラーメッセージ
print qq(</div>
    </td>
  </tr>
</table>
    </body>
    $Script3
</html>
);

exit;
}    
exit;
__END__

<table style="width:100%; table-layout: fixed;">
  <tr>
    <td style="width:50%; text-align:right;">
      <img src="page1_left.jpg" alt="Left Page">
    </td>
    <td style="width:50%; text-align:left;">
      <img src="page1_right.jpg" alt="Right Page">
    </td>
  </tr>
</table>

use Encode;

my @chunks = split(//, $value);
my $mojisu_lc = 0;
my $tmp_my_moji_l = "";
my @new_data_arr;

for my $chunk (@chunks) {  
    my $length = length(encode("UTF-8", $chunk)); # バイト数取得

    if ($length == 1) {
        $mojisu_lc++;  # 半角は1カウント
    } else {
        $mojisu_lc += 2;  # 全角は2カウント
    }

    if ($mojisu_lc >= $p_haba_moji) {  
        $mojisu_lc = 0;
        $tmp_my_moji_l .= "$chunk<br>\n";  
        push(@new_data_arr, $tmp_my_moji_l);
        $tmp_my_moji_l = "";  # リセット
    } else {
        $tmp_my_moji_l .= $chunk;  
    }
}

push(@new_data_arr, $tmp_my_moji_l);
#-----------------------------------------------------------
   ascii          no ascii
0  0 a(1) 1         0あ(2)3|3|4
1  1 b(1) 2         4い(2)3|6|7
#-----------------------------------------------------------
2  2 あ(2)3|4|5     7 a(1) 8
3  5 い(2)3|7|8     8 b(1) 9
#-----------------------------------------------------------
4  8 c(1) 9        9 う(2)3|11|12
5  9               12
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?