索引を目次に入れる方法とは?

このQ&Aのポイント
  • Perl初心者の方が目次に索引を入れる方法について困っているようです。
  • 質問文章のデータには、目次と索引の情報がありますが、目次と索引を組み合わせて最終的なデータを作成する方法を知りたいとのことです。
  • 質問者は、2ページから始まる目次と索引のデータを組み合わせ、最終的に目次と索引が交互に並んだデータを作成したいと考えています。
回答を見る
  • ベストアンサー

索引を目次の該当ページへ入れたいです

+ 目次(1) 1 5 #←1~5ページにある目次 ++ 目次(2) 5 7  ++ 目次(3) 8 10 +++目次(4) 11 15 というデータに、 2 索引(1) #←2ページにある索引 5 索引(2) 7 索引(3) 9 索引(4) 11 索引(5) のデータを入れていき、最終的に + 目次(1) ++ 索引(1) ++ 索引(2) ++ 目次(2) +++索引(3) ++ 目次(3) +++ 索引(3) +++目次(4) ++++索引(5) というデータにするにはどうすればよいでしょうか? Perl初心者で、困っております。どうかよろしくお願いします。

  • Perl
  • 回答数3
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • qtea
  • ベストアンサー率77% (38/49)
回答No.1

リファレンスを使うと、多少、楽(?)です。 ベタベタに記述すると、以下のような感じ。 索引のページ数から、目次をひっぱってくるところが、効率悪そう… あと、各項目の区切り文字は、スペースにしてます。 -------------------------------- #use Data::Dumper; my @list; open MOKUJI, "目次.txt" or die($!); while(<MOKUJI>){ chomp; my($depth,$title,$from,$to) = split /\s+/; push @list, { depth => $depth, title => $title, from => $from, to => $to, words => [] }; } close MOKUJI; #print Dumper(@list); open SAKUIN,"" or die($!); while(<SAKUIN>){ chomp; my($page,$word) = split /\s+/; foreach(@list){ if($page >= $_->{from} and $page <= $_->{to}){ push @{$_->{words}},{ page => $page, word => $word }; last; } } } close SAKUIN; #print Dumper(@list); foreach(@list){ my $depth = $_->{depth}; print $depth; print $_->{title}; print "\n"; foreach(@{$_->{words}}){ print $depth; print $_->{word}; print "\n"; } } -------------------------------- Data::Dumperは、複雑(?)なデータ構造(特にツリー構造など)の中身を確認するのに便利です。 あとは、CPANあたりで、Tree構造を作るモジュールを探してみるのも手でしょう。 とはいえ、それはそれで面倒なのですが(使い方を覚えるのが一苦労)。 ・リファレンス http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlref.html ・Data::Dumper http://fleur.hio.jp/perldoc/mix/lib/Data/Dumper.ja.html ・CPAN http://search.cpan.org/search?query=tree&mode=all

ki0204
質問者

補足

ありがとうございます。大変参考になりました! 補足なんですが、目次の"+"が1つなら索引の"+"は2つ、というように目次よりも索引の"+"をひとつ増やしたい場合と、 索引,ページ数と表したい場合はどのようにすればよいか教えていただけたら幸いです。お願いします。

その他の回答 (2)

  • qtea
  • ベストアンサー率77% (38/49)
回答No.3

とりあえず、No2の説明を書いてみます。 #コンテントオブジェクトにして返す sub to_content{ my ($depth, $title, $from, $to) = @_; return { depth => $depth, title => $title, from_page => $from, to_page => $to, last_page => $to, words => [], child_contents => [], parent_content => undef }; } 目次のデータを作って返すサブルーチンです。 引数は、深さ(+の個数)、目次のタイトル、開始ページ、終了ページです。 それぞれの項目を説明すると… depth  深さを保持します。+の個数です。個数で持つのは、その方が比較が楽になるからです。 title  目次のタイトルを保持します。 from_page  目次の開始ページを保持します。 to_page  目次の終了ページを保持します。 last_page  目次の下に目次がぶらさがっているので、ぶら下がっている、一番最後の目次の終了ページ数を保持します。これは、索引をぶら下げる時に、余計な探索を少しでも減らせるようと考えてつけました。もしかしたら無駄な努力だったかもしれません。 words  索引の単語とページ数を保持します。リストのリファレンスで持ちます。 child_contents  ぶら下がる目次を保持します。リストのリファレンスで持ちます。 parent_content  親の目次を保持します。どの目次にぶら下がるのかを探索する時に、上からではなく、下から探索したいと考えたので(その方が場合によっては楽)つけています。 つづきは、また、ひまなときに…

ki0204
質問者

お礼

ありがとうございました

  • qtea
  • ベストアンサー率77% (38/49)
回答No.2

>補足なんですが、目次の"+"が1つなら索引の"+"は2つ、というように目次よりも索引の"+"をひとつ増やしたい場合と、 >索引,ページ数と表したい場合はどのようにすればよいか教えていただけたら幸いです。お願いします。 下のほうの、 ------- foreach(@{$_->{words}}){ print $depth; print $_->{word}; print "\n"; } ------- この部分を↓に変更すればよいかと思います。 ------- foreach(@{$_->{words}}){ print "+"; #追加 print $depth; print $_->{word}; print ","; #追加 print $_->{page}; #追加 print "\n"; } ------- ただ、目次の「+」を見ていると、目次はツリー構造にしたいのかな?と、ふと思いました。 目次(2)は目次(1)にぶらさがっており、目次(4)は目次(3)にぶらさがっている、という感じなのかな?と… なので、それに対応してみたものを作ってみました。 結構、長いです。かなり、ごちゃごちゃしてます。 サンプルなので、ファイルを読みこむところなどは、自分で用意してください。 ------------------------- use Data::Dumper; use strict; #コンテントオブジェクトにして返す sub to_content{ my ($depth, $title, $from, $to) = @_; return { depth => $depth, title => $title, from_page => $from, to_page => $to, last_page => $to, words => [], child_contents => [], parent_content => undef }; } #索引オブジェクトにして返す sub to_index{ my ($page, $word) = @_; return { page => $page, word => $word, parent_content => undef }; } #目次リストを作成する sub make_contents_list{ my ($content, $before_contet) = @_; if($content->{depth} == $before_contet->{depth}){ $before_contet->{parent_content}->{last_page} = $content->{to_page}; $content->{parent_content} = $before_contet->{parent_content}; push @{$before_contet->{parent_content}->{child_contents}}, $content; }elsif($content->{depth} > $before_contet->{depth}){ $before_contet->{last_page} = $content->{to_page}; $content->{parent_content} = $before_contet; push @{$before_contet->{child_contents}}, $content; }else{ make_contents_list($content, $before_contet->{parent_content}); } } #ページ数から目次を検索して返す(見つからなければ、undefを返す) sub find_content_from_page{ my ($content, $page) = @_; if($page >= $content->{from_page} and $page <= $content->{to_page}){ return $content; }else{ foreach(@{$content->{child_contents}}){ if($page >= $_->{from_page} and $page <= $_->{to_page}){ return $_; }elsif($page >= $_->{from_page} and $page <= $_->{last_page}){ return find_content_from_page($_,$page); } } } return undef; } #単語から索引オブジェクトを検索して返す(見つからなければ、undefを返す) #左辺値が配列なら、全ての同じ単語を検索して、全て返す #左辺値がスカラーなら、最初に見つかった単語を返す sub find_word{ my ($content, $word_text) = @_; my @words; foreach(@{$content->{words}}){ if($_->{word} eq $word_text){ if(wantarray){ push @words, $_; }else{ return $_; } } } foreach(@{$content->{child_contents}}){ if(wantarray){ my @ret_word = find_word($_, $word_text); if(defined @ret_word){ push @words, @ret_word; } }else{ my $ret_word = find_word($_, $word_text); if(defined $ret_word){ return $ret_word; } } } return wantarray ? @words : undef; } #目次と索引の一覧の表示 sub print_content{ my $content=shift; my $mark = "+" x $content->{depth}; $mark .= " " if(length($mark) > 0); print $mark, $content->{title}, "\n"; foreach(@{$content->{words}}){ print "+", $mark, " ", $_->{word}, ",", $_->{page}, "\n"; } foreach(@{$content->{child_contents}}){ print_content($_); } } #目次に索引オブジェクトを入れる sub insert_index{ my ($content, $word) = @_; my $content = find_content_from_page($content, $word->{page}); if(defined $content){ $word->{parent_content}=$content; push @{$content->{words}}, $word; } } #指定の索引オブジェクトから一番上までの道筋をリストで返す sub get_word_road{ my ($word) = @_; my @road = get_content_road($word->{parent_content}); push @road, $word->{parent_content}; return @road; } #指定の目次オブジェクトから一番上までの道筋をリストで返す sub get_content_road{ my ($content) = @_; my @road; my $i = 0; while(defined $content->{parent_content}){ unshift @road, $content->{parent_content}; $content=$content->{parent_content}; } return @road; } #目次一覧 my $book = to_content(0,'テスト文書',0,0); #前回の目次オブジェクトを記憶しておく変数 my $before_contet = $book; #目次データを読みこみ、目次オブジェクトのツリーを作成する while(<DATA>){ #目次データと索引データを空行で分けているので、空行が来たら、ストップ last if /^$/; chomp; my ($mark, $title, $from, $to) = split /\s+/, $_; my $content =to_content( length($mark), $title, $from, $to ); #目次一覧を現在の目次と前回の目次から作成する make_contents_list($content, $before_contet); #前回の目次オブジェクトとして保持する $before_contet = $content; } #索引データを読みこみ、目次オブジェクトにつっこむ while(<DATA>){ chomp; my($page, $word_text) = split /\s+/; my $word = to_index($page, $word_text); insert_index($book, $word); } #とりあえず、確認 #print Dumper($book); print_content($book); print "----\n"; #単語を探す my $word = find_word($book, "索引(5)"); if(defined $word){ my @road = get_word_road($word); my @titles = map{$_->{title}} @road; print join(" > ", @titles, $word->{word}); print ", ", $word->{page}, "\n"; }else{ print "見つかりませんでした。"; } my @word = find_word($book, "索引(3)"); if(defined @word){ foreach(@word){ my @road = get_word_road($_); my @titles = map{$_->{title}} @road; print join(" > ", @titles, $_->{word}); print ", ", $_->{page}, "\n"; } }else{ print "見つかりませんでした。"; } #下記はテストデータ __END__ + 目次(1) 1 5 ++ 目次(2) 5 7 ++ 目次(3) 8 10 +++ 目次(4) 11 15 ++ 目次(5) 16 20 + 目次(6) 21 25 2 索引(1) 5 索引(2) 7 索引(3) 12 索引(3) 9 索引(4) 11 索引(5) -------------------------

ki0204
質問者

お礼

ありがとうございました

関連するQ&A

  • Wordで、目次(索引)を2ページレイアウトにする方法について

    通常、Wordから目次の追加をした場合、1ページになりますが 目次(索引)を2ページ(1ページに2行)にすることってできますか? 確か前にそういう文章見たことあったので。 分かる方ご回答を宜しくお願いします。

  • Word 「索引と目次」について

    初めて質問致します。上手に説明が出来ないのですが、 教えて頂きたいのは、II.施策の後、「4.」ではなく 「1.」と表示させたいのですが表示できずに困っています。 スタイルでの設定に問題があるのでしょうか、教えて下さい。 「スタイルと書式」を使ってフォントなどを統一させ メニューより「挿入」、「参照」、「索引と目次」で 下記のような目次を作成しました。 ★Upするとページ番号がイビツになってしまいますが  Word上では同じ縦位置にキレイにならんでます。 ----------------------------------------------------         目次 I.○○○○の概要           1  1. ○○○○の○○○       1  2. ○○○○の○○        1  3. ○○○○○○○の○○     1 II.施策                2  4. ○○○○の○○        2  (1)  ○○○○の○○       2  5. ○○○○への○○○○○○   5  (1)  ○○○○○○の○○ 5  6. ○○○○○○○○○○ 6  (1)  ○○○○ 6  7. ○○○○ 6  (1)  ○○○○ 6  (2)  ○○○○ 7  (3)  ○○○○ 8  (4)  ○○○○ 9  (5) ○○○○ 9 ----------------------------------------------------

  • ワードの目次のページをなしにする方法

    <<ページ設定について、教えてください>> ワードで、見出しをつけ、「索引と目次」で行うと、目次までページがでます。 目次には、ページを入れたくないです。 目次には、ページを出さず、「本文」からページ(1)をつけたいです。つまり、3ページ後から、ページ1をつけたいです。 大変、困っています。 どのようにすればよいのでしょうか。教えてください。よろしくお願い致します。

  • 【Word】目次、索引のページ番号に任意の文字を追加する

    各セクションごとで、ページ番号の前に文字を追加しています。 ※内容は実際のものではありません 【セクション1のページ番号】 東京-1、東京-2、東京-3・・・ 【セクション2のページ番号】 名古屋-1、名古屋-2、名古屋-3・・・ 【セクション3のページ番号】 大阪-1、大阪-2、大阪-3・・・ 「東京-」「名古屋-」「大阪-」は手入力、数字は{page}フィールドです。 各セクションの先頭で「前と同じ」をオフにし、開始番号を1にしています。 目次と索引を作成すると、ページの数字のみで作成されます。 目次と索引も「東京-1」形式で作成したいのですが、 方法はありますでしょうか? よろしくお願い致します。

  • Word2003目次のページ番号の設定方法

    Word2003を使っていて、100ページにもなるものを書いて、その目次を作ったんです。 目次は「挿入」→「参照」→「索引/目次」で作りました。ただし、本文のページ番号は「-1-」というフォーマットにしてしまうと、目次が以下のようになってしまいます。 第1章 背景・・・・・・・・・・-1-  1-1 ○○・・・・・・・・・・-2- この目次の参照先ページ番号を「-1-」じゃなくて「1」にしたいんです。しかし、本文のページ番号は「-1-」にしたいです。 どうすれば、設定できるでしょうか?

  • Microsoft Word2003 索引と目次のオプションについて

    こんばんは。 現在マイクソロフトワード2003を使っています。 目次を作りたくて、挿入メニューの参照>索引と目次の、 目次タブで目次を作りました。 目次タブにオプションボタンがあるのですが、 このボタンを押して表示される目次オプションダイアログボックスが よくわかりません。 見出しマップを目次レベル1にしても、 何も目次が出てきません。 この目次オプションダイアログボックスのスタイルの一覧の ところについて詳しく具体的な使い方を教えて欲しいです。 よろしくお願いします。

  • ページ番号と目次を挿入したいのですが

    今日は。 卒論を書いているのですが、ページ番号と目次の挿入が上手くいきませんのでアドバイスください。環境はMicrosoft Word2003です。 現在、タイトル、目次(3ページ)、本文となっています。 学校からの指定で、目次のページ番号はローマ数字(ⅰ、ⅱ、ⅲ)で、本文には数字(1、2、3・・・)とするようにしています。そのため、タイトルと目次と本文を別々のファイルにしています。 挿入→参照→索引と目次で自動で目次のページ設定をしたいのですが、このように別のファイルにしていると出来ません。同じファイルだとしても、0ページからしか設定できないので、本文のはじめは4ページという表示になってしまいます。機能は使えず、いちいち自分でページを入力していくしかないのでしょうか? あと、同じファイルでローマ数字のページと数字のページを混在することは不可能なのでしょうか? ちなみに、友人は目次が1ページなので、目次・本文という形にしても目次を0ページから設定出来るので、本文は1ページからという形にきちんと出来たそうです。 よろしくお願いします。

  • WORDの目次

    WORD2003で目次を作成(挿入→参照→索引と目次)しています。 目次を作成すると、目次とページ番号が一覧となって表示しますが、 ページ番号のスタイル(?)を変えられますか? 【例】 ●ページ番号/全ページ ●第1章-ページ番号 ヘッダが上記のようになっていて、目次とヘッダがリンクするような かたちを考えているのですが?

  • ワードで索引を作るとページが狂いませんか

    ワード2007です。2ページの一番下まで文書が書いてあるとします。索引をいくつかつけ、最後の語句にも、索引をつけたとします。すると、最後の語句は、3ページに来ています。 ところが印刷してみると、もともとの本文は2ページで収まっており、3ページ目だけに索引が印刷されています。困ったことに、最後の語句は、印刷上は2ページにいるのに、索引では3ページにあると表示されてしまいます。 このように、索引のフィールドが加わることで、ページが狂うのをどう防げばいいのでしょうか。

  • Wordで目次へ戻る方法

    Word2000にて、挿入の索引と目次にて目次の作成を行いました。 目次から該当ページへはジャンプできるのですが、逆にクリックで目次に戻る方法はないでしょうか? よろしくお願いします。