hikidoc-0.0.6/0000775000175000017500000000000011603207143012762 5ustar uwabamiuwabamihikidoc-0.0.6/test/0000775000175000017500000000000011603207143013741 5ustar uwabamiuwabamihikidoc-0.0.6/test/test_hikidoc.rb0000644000175000017500000005042011603207143016736 0ustar uwabamiuwabamirequire "test/unit" rootdir = "#{File::dirname(__FILE__)}/.." require "#{rootdir}/lib/hikidoc" class HikiDocTestCase < Test::Unit::TestCase def test_plugin assert_convert("
{{hoge}}
\n", "{{hoge}}") assert_convert("

a{{hoge}}b

\n", "a{{hoge}}b") assert_convert("

\\{{hoge}}

\n", "\\{{hoge}}") assert_convert("

a{{hoge

\n", "a{{hoge") assert_convert("

hoge}}b

\n", "hoge}}b") assert_convert("

{{hoge}}\na

\n", "{{hoge}}\na") assert_convert("
{{hoge}}
\n

a

\n", "{{hoge}}\n\na") end def test_plugin_with_quotes assert_convert("
{{hoge(\"}}\")}}
\n", '{{hoge("}}")}}') assert_convert("
{{hoge(\'}}\')}}
\n", "{{hoge('}}')}}") assert_convert("
{{hoge(\'\n}}\n\')}}
\n", "{{hoge('\n}}\n')}}") end def test_plugin_with_meta_char assert_convert("
{{hoge(\"a\\\"b\")}}
\n", '{{hoge("a\\"b")}}') assert_convert("
{{hoge(\"<a>\")}}
\n", '{{hoge("")}}') assert_convert("

a{{hoge(\"<a>\")}}

\n", 'a{{hoge("
")}}') end def test_plugin_with_default_syntax # test HikiDoc#valid_plugin_syntax? # default syntax checking pairs of quote like "..." or '...' assert_convert(%q!

{{'}}

! + "\n", %q!{{'}}!) assert_convert(%q!
{{''}}
! + "\n", %q!{{''}}!) assert_convert(%q!

{{'"}}

! + "\n", %q!{{'"}}!) assert_convert(%q!
{{'\''}}
! + "\n", %q!{{'\''}}!) assert_convert(%q!
{{'abc\\\\'}}
! + "\n", %q!{{'abc\\\\'}}!) assert_convert(%q!
{{\"""}}
! + "\n", %q!{{\"""}}!) assert_convert(%q!
{{"ab\c"}}
! + "\n", %q!{{"ab\c"}}!) end def test_plugin_with_custom_syntax assert_convert("

{{<<\"End\"\nfoo's bar\nEnd\n}}

\n", "{{<<\"End\"\nfoo's bar\nEnd\n}}") options = {:plugin_syntax => method(:custom_valid_plugin_syntax?)} assert_convert(%Q|
{{<<"End"\nfoo's bar\nEnd\n}}
\n|, %Q!{{<<"End"\nfoo's bar\nEnd\n}}!, options) assert_convert(%Q|
{{<<"End"\nfoo\nEnd}}
\n|, %Q!{{<<"End"\nfoo\nEnd}}!, options) end def test_multi_line_plugin assert_convert(<<-END_OF_EXPECTED, <<-END_OF_INPUT)
{{<<TEST2 test2 TEST2}}
END_OF_EXPECTED {{<{{<<TEST <<< here is not pre but plugin. >>> TEST}} END_OF_EXPECTED {{<>> TEST}} END_OF_INPUT end def test_blockquote assert_convert("

hoge

\n
\n", %Q|""hoge\n|) assert_convert("

hoge\nfuga

\n
\n", %Q|""hoge\n""fuga\n|) assert_convert("

hoge

\n

fuga

\n
\n
\n", %Q|""hoge\n"" ""fuga\n|) assert_convert("

hoge

\n
\n", %Q|"" ! hoge\n|) assert_convert("

foo\nbar

\n

foo

\n
\n", %Q|""foo\n""bar\n""\n""foo|) assert_convert("

foo\nbar

\n

foo

\n
\n", %Q|""foo\n""bar\n""!foo|) assert_convert("

foo\nbar

\n
baz
\n
\n", %Q|""foo\n"" bar\n"" baz|) assert_convert("

foo\nbar

\n
baz
\n
\n", %Q|""foo\n""\tbar\n""\t\tbaz|) end def test_header assert_convert("

hoge

\n", "!hoge") assert_convert("

hoge

\n", "!! hoge") assert_convert("

hoge

\n", "!!!hoge") assert_convert("

hoge

\n", "!!!! hoge") assert_convert("
hoge
\n", "!!!!!hoge") assert_convert("
hoge
\n", "!!!!!! hoge") assert_convert("
! hoge
\n", "!!!!!!! hoge") assert_convert("

foo

\n

bar

\n", "!foo\n!!bar") end def test_list assert_convert("
    \n
  • foo
  • \n
\n", "* foo") assert_convert("
    \n
  • foo
  • \n
  • bar
  • \n
\n", "* foo\n* bar") assert_convert("
    \n
  • foo
      \n
    • bar
    • \n
  • \n
\n", "* foo\n** bar") assert_convert("
    \n
  • foo
      \n
    • foo
    • \n
  • \n
  • bar
  • \n
\n", "* foo\n** foo\n* bar") assert_convert("
    \n
  • foo
      \n
    1. foo
    2. \n
  • \n
  • bar
  • \n
\n", "* foo\n## foo\n* bar") assert_convert("
    \n
  • foo
  • \n
    \n
  1. bar
  2. \n
\n", "* foo\n# bar") end def test_list_skip assert_convert("
    \n
  • foo
      \n
      • \n
      • foo
      • \n
    • \n
  • \n
  • bar
  • \n
\n", "* foo\n*** foo\n* bar") assert_convert("
    \n
  1. foo
      \n
      1. \n
      2. bar
      3. \n
      4. baz
      5. \n
    1. \n
  2. \n
\n", "# foo\n### bar\n###baz") end def test_hrules assert_convert("
\n", "----") assert_convert("

----a

\n", "----a") end def test_pre assert_convert("
foo
\n", " foo") assert_convert("
\\:
\n", ' \:') assert_convert("
foo
\n", "\tfoo") assert_convert("
foo\nbar
\n", " foo\n bar") assert_convert("
foo\nbar
\n", " foo\n bar\n") assert_convert("
<foo>
\n", " ") assert_convert("
{{_:a/a}}
\n", " {{_:a/a}}") assert_convert("
[[_:a/a]]
\n", " [[_:a/a]]") end def test_multi_pre assert_convert("
foo
\n", "<<<\nfoo\n>>>") assert_convert("
foo\n bar
\n", "<<<\nfoo\n bar\n>>>") assert_convert("
foo
\n
bar
\n", "<<<\nfoo\n>>>\n<<<\nbar\n>>>") assert_convert("
<foo>
\n", "<<<\n\n>>>") end def test_multi_pre_with_plugin assert_convert("
{{{}}}
\n" + "
{{'test'}}
\n", "<<<\n{{{}}}\n>>>\n{{'test'}}") end def test_comment assert_convert("", "// foo") assert_convert("", "// foo\n") end def test_paragraph assert_convert("

foo

\n", "foo") assert_convert("

foo

\n

bar

\n", "foo\n\nbar") assert_convert("

foo

\n

bar

\n", "foo\r\n\r\nbar") assert_convert("

foo

\n

b a r

\n", "foo \n\nb a r ") end def test_escape assert_convert(%Q|

\\"\\"foo

\n|, %q|\"\"foo|) end def test_link assert_convert(%Q|

http://hikiwiki.org/

\n|, "http://hikiwiki.org/") assert_convert(%Q|

http://hikiwiki.org/

\n|, "[[http://hikiwiki.org/]]") assert_convert(%Q|

Hiki

\n|, "[[Hiki|http://hikiwiki.org/]]") assert_convert(%Q|

Hiki

\n|, "[[Hiki|http:/hikiwiki.html]]") assert_convert(%Q|

Hiki

\n|, "[[Hiki|http:hikiwiki.html]]") assert_convert(%Q|

img.png

\n|, "http://hikiwiki.org/img.png") assert_convert(%Q|

img.png

\n|, "http://hikiwiki.org:80/img.png") assert_convert(%Q|

| + %Q|http://hikiwiki.org/ja/?c=edit;p=Test

\n|, "http://hikiwiki.org/ja/?c=edit;p=Test") assert_convert(%Q|

| + %Q|http://hikiwiki.org/ja/?c=edit&p=Test

\n|, "http://hikiwiki.org/ja/?c=edit&p=Test") assert_convert(%Q|

img.png

\n|, "http:/img.png") assert_convert(%Q|

img.png

\n|, "http:img.png") assert_convert(%Q|

Tuna

\n|, "[[Tuna|%CB%EE]]") assert_convert(%Q|

""

\n|, '[[""]]') assert_convert(%Q|

%22

\n|, "[[%22]]") assert_convert(%Q|

&

\n|, "[[&]]") assert_convert(%Q|

aabbcc

\n|, "[[aa]]bb[[cc]]") assert_convert(%Q!

a|a

\n!, "[[a|a|aa]]") end def test_inter_wiki_name assert_convert("

scheme:keyword

\n", "[[scheme:keyword]]") assert_convert("

label

\n", "[[label|scheme:keyword]]") end def test_wiki_name assert_convert("

WikiName

\n", "WikiName") assert_convert("

HogeRule1

\n", "HogeRule1") assert_convert("

WikiName1WikiName2

\n", "WikiName1WikiName2") assert_convert("

WikiName1 " + "WikiName2

\n", "WikiName1 WikiName2") assert_convert("

NOTWIKINAME

\n", "NOTWIKINAME") assert_convert("

NOT_WIKI_NAME

\n", "NOT_WIKI_NAME") assert_convert("

WikiNAME

\n", "WikiNAME") assert_convert("

fooWikiNAME

\n", "fooWikiNAME") assert_convert("

RSSPage

\n", "RSSPage") assert_convert("

RSSPageName

\n", "RSSPageName") end def test_not_wiki_name assert_convert("

WikiName

\n", "^WikiName") assert_convert("

^WikiName

\n", "^WikiName", :use_not_wiki_name => false) assert_convert("

^WikiName

\n", "^WikiName", :use_wiki_name => false) assert_convert("

^WikiName

\n", "^WikiName", :use_wiki_name => false, :use_not_wiki_name => false) assert_convert("

foo WikiName bar

\n", "foo ^WikiName bar") end def test_use_wiki_name_option assert_convert("

WikiName

\n", "WikiName") assert_convert("

WikiName

\n", "WikiName", :use_wiki_name => false) end def test_image_link assert_convert(%Q|

img.png

\n|, "[[http://hikiwiki.org/img.png]]") assert_convert(%Q|

http://hikiwiki.org/img.png

\n|, "[[http://hikiwiki.org/img.png]]", :allow_bracket_inline_image => false) assert_convert(%Q|

img

\n|, "[[img|http://hikiwiki.org/img.png]]") assert_convert(%Q|

img

\n|, "[[img|http://hikiwiki.org/img.png]]", :allow_bracket_inline_image => false) end def test_definition assert_convert("
\n
a
\n
b
\n
\n", ":a:b") assert_convert("
\n
a
\n
b\n
\n
c
\n
\n", ":a:b\n::c") assert_convert("
\n
a\\
\n
b:c
\n
\n", ':a\:b:c') assert_convert("
\n
a
\n
b\\:c
\n
\n", ':a:b\:c') assert_convert("
\n
a
\n
b:c
\n
\n", ":a:b:c") end def test_definition_title_only assert_convert("
\n
a
\n
\n", ":a:") end def test_definition_description_only assert_convert("
\n
b
\n
\n", "::b") end def test_definition_with_link assert_convert("
\n
Hiki
\n" + "
Website
\n
\n", ":[[Hiki|http://hikiwiki.org/]]:Website") assert_convert("
\n
a
\n" + "
Hiki
\n" + "
\n", ":a:[[Hiki|http://hikiwiki.org/]]") end def test_definition_with_modifier assert_convert("
\n
foo
\n" + "
bar
\n
\n", ":'''foo''':bar") assert_convert("
\n
foo
\n" + "
bar
\n
\n", ":foo:'''bar'''") assert_convert("
\n
foo
\n" + "
bar
\n
\n", ":foo:``bar``") end def test_definition_with_modifier_link assert_convert("
\n
" + "Hiki" + "
\n
Website
\n
\n", ":'''[[Hiki|http://hikiwiki.org/]]''':Website") assert_convert("
\n
Website
\n
" + "Hiki" + "
\n
\n", ":Website:'''[[Hiki|http://hikiwiki.org/]]'''") assert_convert("
\n
Website
\n
" + "Hiki" + "
\n
\n", ":Website:``[[Hiki|http://hikiwiki.org/]]``") end def test_table assert_convert(%Q|\n\n
ab
\n|, "||a||b") assert_convert(%Q|\n\n
ab
\n|, "||a||b||") assert_convert(%Q|\n\n
ab
\n|, "||a||b||") assert_convert(%Q|\n\n
ab
\n|, "||a||b|| ") assert_convert(%Q|\n\n
ab
\n|, "||!a||b||") assert_convert(%Q|\n\n\n\n
12\n
34\n
5
\n|, "||>1||^2\n||^3||4\n||>5") assert_convert(%Q|\n\n\n\n
abc
def
\n|, "||a||b||c||\n||||||||\n||d||e||f||") end def test_table_with_modifier assert_convert("\n\n
''''''bar
\n", "||'''||'''||bar") assert_convert("\n\n
'''\\'''bar
\n", "||'''\\||'''||bar") end def test_modifier assert_convert("

foo

\n", "'''foo'''") assert_convert("

foo

\n", "''foo''") assert_convert("

foo

\n", "==foo==") assert_convert("

foo==barbaz==

\n", "''foo==bar''baz==") assert_convert("

foo and bar

\n", "'''foo''' and '''bar'''") assert_convert("

foo and bar

\n", "''foo'' and ''bar''") assert_convert("

foo

\n", "``foo``") assert_convert("

foo==barbaz==

\n", "``foo==bar``baz==") end def test_nested_modifier assert_convert("

foo

\n", "''==foo==''") assert_convert("

foo

\n", "==''foo''==") end def test_modifier_and_link assert_convert("

Hiki

\n", "[['''Hiki'''|http://hikiwiki.org/]]") assert_convert("

Hiki

\n", "'''[[Hiki|http://hikiwiki.org/]]'''") assert_convert("

Hiki

\n", "``[[Hiki|http://hikiwiki.org/]]``") end def test_pre_and_plugin assert_convert(%Q|
{{hoge}}
\n|, " {{hoge}}") assert_convert(%Q|
{{hoge}}
\n|, "<<<\n{{hoge}}\n>>>") assert_convert("
{{foo\n 1}}
\n", "{{foo\n 1}}") end def test_plugin_in_modifier assert_convert("

{{foo}}

\n", "'''{{foo}}'''") assert_convert("

{{foo}}

\n", "``{{foo}}``") end def test_syntax_ruby if Object.const_defined?(:Syntax) assert_convert("
class A\n  def foo(bar)\n  end\nend
\n", "<<< ruby\nclass A\n def foo(bar)\n end\nend\n>>>") assert_convert("
class A\n  def foo(bar)\n  end\nend
\n", "<<< Ruby\nclass A\n def foo(bar)\n end\nend\n>>>") assert_convert("
'a<">b'
\n", "<<< ruby\n'a<\">b'\n>>>") # redefine method for below tests class << Syntax::Convertors::HTML def for_syntax(syntax) raise end end end # use google-code-prettify assert_convert("
class A\n  def foo(bar)\n  end\nend
\n", "<<< ruby\nclass A\n def foo(bar)\n end\nend\n>>>") assert_convert("
class A\n  def foo(bar)\n  end\nend
\n", "<<< Ruby\nclass A\n def foo(bar)\n end\nend\n>>>") assert_convert("
'a<\">b'
\n", "<<< ruby\n'a<\">b'\n>>>") end def test_plugin_in_pre_with_header assert_convert("

Title

\n
{{_/a:a}}
\n", "! Title\n {{_/a:a}}") assert_convert("

Title

\n
{{_/a:a}}\n{{_/a:a}}
\n", "! Title\n {{_/a:a}}\n {{_/a:a}}") end private def assert_convert(expected, markup, options={}, message=nil) assert_equal(expected, HikiDoc.to_xhtml(markup, options), message) end def custom_valid_plugin_syntax?(code) eval("BEGIN {return true}\n#{code}", nil, "(plugin)", 0) rescue SyntaxError false end end hikidoc-0.0.6/test/run-test.rb0000755000175000017500000000050111603207143016044 0ustar uwabamiuwabami#!/usr/bin/env ruby require "test/unit" if Test::Unit.respond_to?(:setup_argv) Test::Unit::setup_argv{[File.dirname($0)]} else if Test::Unit::AutoRunner.respond_to?(:standalone?) exit Test::Unit::AutoRunner.run($0, File.dirname($0)) else exit Test::Unit::AutoRunner.run(false, File.dirname($0)) end end hikidoc-0.0.6/COPYING0000644000175000017500000000277611603207143014027 0ustar uwabamiuwabamiCopyright (c) 2005, Kazuhiko All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the HikiDoc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. hikidoc-0.0.6/bin/0000775000175000017500000000000011603207143013532 5ustar uwabamiuwabamihikidoc-0.0.6/bin/hikidoc0000755000175000017500000000224411603207143015072 0ustar uwabamiuwabami#!/usr/bin/env ruby require 'hikidoc' require 'optparse' require 'erb' HTML_TEMPLATE = < <%= title %> <%= body %> EOS options = {} format_options = {} ARGV.options do |opts| opts.banner = "Usage: #$0 [OPTIONS] FILE" opts.on('-f', '--fragment', 'Output HTML fragments only') do options[:fragment] = true end opts.on('-t', '--template=TEMPLATE', 'Specify a HTML template file') do |template| options[:template] = template end opts.on('--no-wikiname', 'Disable WikiName link') do format_options[:use_wiki_name] = false end opts.parse! end case ARGV.size when 0 title, text = '-', $stdin.read when 1 title, text = ARGV[0], File.read(ARGV[0]) else usage end body = HikiDoc.to_html(text, format_options) def result(erb, title, body, text) erb.result(binding) end if options[:fragment] puts(body) else template = options[:template] if template source = File.read(template) else source = HTML_TEMPLATE end erb = ERB.new(source) erb.filename = template puts(result(erb, title, body, text)) end hikidoc-0.0.6/README0000644000175000017500000000566611603207143013655 0ustar uwabamiuwabami! HikiDoc !! Introduction 'HikiDoc' is a text-to-HTML conversion tool for web writers. HikiDoc allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid HTML (or XHTML). !! Requirements HikiDoc requires Ruby 1.8.2 or later. !! Download Get from the subversion repository http://hikidoc.rubyforge.org/svn/ . (eg.) svn co http://hikidoc.rubyforge.org/svn/trunk/ hikidoc !! Installation Run the 'setup.rb' script like so: $ ruby setup.rb config $ ruby setup.rb setup # ruby setup.rb install !! Syntax See [[TextFormattingRules]]. !! Mailing list To subscribe the HikiDoc ML, please send the following mail. English posts are also welcome. To: hikidoc@ml.fdiary.net Cc: kazuhiko@fdiary.net Subject: subscribe <- any subject Hello. <- any body HikiDoc ML's archive is available at http://www.fdiary.net/ml/hikidoc/ . !! Related softwares The following softwares use the HikiDoc library or the HikiDoc format. :[[tDiary|http://www.tdiary.org/]]:a Weblog/Web-diary software :[[Hiki|http://hikiwiki.org/]]:a powerful and fast wiki clone :[[lily|http://lily.sourceforge.jp/]]:a simple CMS :[[Text::HikiDoc|http://search.cpan.org/perldoc?Text::HikiDoc]]:HikiDoc by Perl :[[PikiDoc|http://github.com/moro/piki_doc/]]:a library that you can add plugin functions on HikiDoc !! License HikiDoc's license is the 'Modified BSD License'. Copyright (c) 2005, Kazuhiko All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the HikiDoc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. hikidoc-0.0.6/NEWS.ja0000644000175000017500000000163611603207143014056 0ustar uwabamiuwabami! NEWS.ja !! 0.0.5から0.0.6の変更点: 2010-08-28 * パッケージからNEWS.jaが漏れてしまうのを修正 !! 0.0.4から0.0.5の変更点: 2010-08-26 * 同一行に含まれる非WikiName表記以降の文字が出力されないバグを修正 * 新しい文字の修飾``等幅表示``を追加 * Hoe 1.9.0 またはそれ以降でrakeが失敗する問題を修正 * google-code-prettifyでのシンタックスハイライトを追加 !! 0.0.3から0.0.4の変更点: 2009-08-17 * inline_pluginでblock_plugin同様にエスケープするように修正 * プラグイン表記の解釈におけるDoS脆弱性に対する修正 !! 0.0.2から0.0.3の変更点: 2008-08-25 * gemからのインストール時に"Could not find main page README.txt"という警告メッセージが出力され問題を修正 !! 0.0.1から0.0.2の変更点: 2008-08-11 * 修飾系インライン中のインライン記法が展開されないバグを修正 * hikidocコマンドに--no-wikinameオプションを追加 * InterWikiNameでURI schemeとして扱うものをhttp(s),file,ftpに限定するよう修正 * テストを強化 * Rakeタスクcoverageを追加(要rcov) hikidoc-0.0.6/README.ja0000644000175000017500000000555011603207143014236 0ustar uwabamiuwabami! HikiDoc !! はじめに 'HikiDoc' は「テキスト→ HTML」変換ツールです。書きやすく読みやすい文法の テキストをまともな HTML (や XHTML) に変換します。 !! 必要なもの HikiDoc の実行には Ruby 1.8.2 以降が必要です。 !! ダウンロード Subversion レポジトリ http://hikidoc.rubyforge.org/svn/ から取得して ください。 (例) svn co http://hikidoc.rubyforge.org/svn/trunk/ hikidoc !! インストール 以下のように 'setup.rb' スクリプトを用いてインストールします。 $ ruby setup.rb config $ ruby setup.rb setup # ruby setup.rb install !! 文法 [[TextFormattingRules.ja]] をご覧ください。 !! メーリングリスト 参加を希望される方は、以下のようなメールを送信してください。 To: hikidoc@ml.fdiary.net Cc: kazuhiko@fdiary.net 本文に自己紹介など 過去のメールは http://www.fdiary.net/ml/hikidoc/ で公開しています。 !! 関連するソフトウェア 以下のソフトウェアで HikiDoc ライブラリ、または HikiDoc フォーマットが用いられています。 :[[tDiary|http://www.tdiary.org/]]:ウェブ日記ソフトウェア :[[Hiki|http://hikiwiki.org/]]:多機能かつ高速な Wiki クローン :[[lily|http://lily.sourceforge.jp/]]:シンプルな CMS (Web サイト構築システム) :[[Text::HikiDoc|http://search.cpan.org/perldoc?Text::HikiDoc]]:Perl による HikiDoc の実装 :[[PikiDoc|http://github.com/moro/piki_doc/]]:HikiDocの「プラグイン」機能を追加できるライブラリです !! ライセンス Modified BSD ライセンスです。 Copyright (c) 2005, Kazuhiko All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the HikiDoc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. hikidoc-0.0.6/NEWS0000644000175000017500000000157411603207143013466 0ustar uwabamiuwabami! NEWS !! Changes 0.0.6 from 0.0.5: 2010-08-28 * fix missing NEWS.ja for packaging !! Changes 0.0.5 from 0.0.4: 2010-08-26 * fix a bug: strings after non-WikiName expression are ignored * new text decoration ``monospaced text`` * fix rake failure with Hoe 1.9.0 or later * add syntax highlighting with google-code-prettify !! Changes 0.0.4 from 0.0.3: 2009-08-17 * escape collectly in inline_plugin same as block_plugin does. * fix a DoS vulnerability processing a plugin expression. !! Changes 0.0.3 from 0.0.2: 2008-08-25 * fix warning message "Could not find main page README.txt" at installation via gem !! Changes 0.0.2 from 0.0.1: 2008-08-11 * fix a bug: an inline that is inside of a modifier inline do not works * add a option "--no-wikiname" to `hikidoc' command * correct URI scheme behavior of InterWikiName * add some tests * add a Rake task "coverage" (requires rcov) hikidoc-0.0.6/metadata.yml0000664000175000017500000000370211603207143015267 0ustar uwabamiuwabami--- !ruby/object:Gem::Specification name: hikidoc version: !ruby/object:Gem::Version version: 0.0.6 platform: ruby authors: - Kazuhiko autorequire: bindir: bin cert_chain: [] date: 2010-08-27 00:00:00 +09:00 default_executable: dependencies: - !ruby/object:Gem::Dependency name: rubyforge type: :development version_requirement: version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.0.4 version: - !ruby/object:Gem::Dependency name: hoe type: :development version_requirement: version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.6.1 version: description: |- 'HikiDoc' is a text-to-HTML conversion tool for web writers. HikiDoc allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid HTML (or XHTML). email: - kazuhiko@fdiary.net executables: - hikidoc extensions: [] extra_rdoc_files: - README - COPYING - NEWS - TextFormattingRules files: - COPYING - NEWS.ja - README - README.ja - Rakefile - TextFormattingRules - TextFormattingRules.ja - bin/hikidoc - lib/hikidoc.rb - setup.rb - test/run-test.rb - test/test_hikidoc.rb - NEWS has_rdoc: true homepage: http://rubyforge.org/projects/hikidoc/ licenses: [] post_install_message: rdoc_options: - --main - lib/hikidoc.rb require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: "0" version: required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: "0" version: requirements: [] rubyforge_project: hikidoc rubygems_version: 1.3.5 signing_key: specification_version: 3 summary: "'HikiDoc' is a text-to-HTML conversion tool for web writers." test_files: - test/test_hikidoc.rb hikidoc-0.0.6/lib/0000775000175000017500000000000011603207143013530 5ustar uwabamiuwabamihikidoc-0.0.6/lib/hikidoc.rb0000644000175000017500000004622411603207143015475 0ustar uwabamiuwabami# -*- coding: utf-8 -*- # Copyright (c) 2005, Kazuhiko # Copyright (c) 2007 Minero Aoki # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of the HikiDoc nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. require "stringio" require "strscan" require "uri" begin require "syntax/convertors/html" rescue LoadError end class HikiDoc VERSION = "0.0.6" # FIXME class Error < StandardError end class UnexpectedError < Error end def HikiDoc.to_html(src, options = {}) new(HTMLOutput.new(">"), options).compile(src) end def HikiDoc.to_xhtml(src, options = {}) new(HTMLOutput.new(" />"), options).compile(src) end def initialize(output, options = {}) @output = output @options = default_options.merge(options) @header_re = nil @level = options[:level] || 1 @plugin_syntax = options[:plugin_syntax] || method(:valid_plugin_syntax?) end def compile(src) @output.reset escape_plugin_blocks(src) {|escaped| compile_blocks escaped @output.finish } end # for backward compatibility def to_html $stderr.puts("warning: HikiDoc#to_html is deprecated. Please use HikiDoc.to_html or HikiDoc.to_xhtml instead.") self.class.to_html(@output, @options) end private def default_options { :allow_bracket_inline_image => true, :use_wiki_name => true, :use_not_wiki_name => true, } end # # Plugin # def valid_plugin_syntax?(code) /['"]/ !~ code.gsub(/\\\\/, "").gsub(/\\['"]/,"").gsub(/'[^']*'|"[^"]*"/m, "") end def escape_plugin_blocks(text) s = StringScanner.new(text) buf = "" @plugin_blocks = [] while chunk = s.scan_until(/\{\{/) tail = chunk[-2, 2] chunk[-2, 2] = "" buf << chunk # plugin if block = extract_plugin_block(s) @plugin_blocks.push block buf << "\0#{@plugin_blocks.size - 1}\0" else buf << "{{" end end buf << s.rest yield(buf) end def restore_plugin_block(str) str.gsub(/\0(\d+)\0/) { "{{" + plugin_block($1.to_i) + "}}" } end def evaluate_plugin_block(str, buf = nil) buf ||= @output.container str.split(/(\0\d+\0)/).each do |s| if s[0, 1] == "\0" and s[-1, 1] == "\0" buf << @output.inline_plugin(plugin_block(s[1..-2].to_i)) else buf << @output.text(s) end end buf end def plugin_block(id) @plugin_blocks[id] or raise UnexpectedError, "must not happen: #{id.inspect}" end def extract_plugin_block(s) pos = s.pos buf = "" while chunk = s.scan_until(/\}\}/) buf << chunk buf.chomp!("}}") if @plugin_syntax.call(buf) return buf end buf << "}}" end s.pos = pos nil end # # Block Level # def compile_blocks(src) f = LineInput.new(StringIO.new(src)) while line = f.peek case line when COMMENT_RE f.gets when HEADER_RE compile_header f.gets when HRULE_RE f.gets compile_hrule when LIST_RE compile_list f when DLIST_RE compile_dlist f when TABLE_RE compile_table f when BLOCKQUOTE_RE compile_blockquote f when INDENTED_PRE_RE compile_indented_pre f when BLOCK_PRE_OPEN_RE compile_block_pre f else if /^$/ =~ line f.gets next end compile_paragraph f end end end COMMENT_RE = %r<\A//> def skip_comments(f) f.while_match(COMMENT_RE) do |line| end end HEADER_RE = /\A!+/ def compile_header(line) @header_re ||= /\A!{1,#{7 - @level}}/ level = @level + (line.slice!(@header_re).size - 1) title = strip(line) @output.headline level, compile_inline(title) end HRULE_RE = /\A----$/ def compile_hrule @output.hrule end ULIST = "*" OLIST = "#" LIST_RE = /\A#{Regexp.union(ULIST, OLIST)}+/ def compile_list(f) typestack = [] level = 0 @output.list_begin f.while_match(LIST_RE) do |line| list_type = (line[0,1] == ULIST ? "ul" : "ol") new_level = line.slice(LIST_RE).size item = strip(line.sub(LIST_RE, "")) if new_level > level (new_level - level).times do typestack.push list_type @output.list_open list_type @output.listitem_open end @output.listitem compile_inline(item) elsif new_level < level (level - new_level).times do @output.listitem_close @output.list_close typestack.pop end @output.listitem_close @output.listitem_open @output.listitem compile_inline(item) elsif list_type == typestack.last @output.listitem_close @output.listitem_open @output.listitem compile_inline(item) else @output.listitem_close @output.list_close typestack.pop @output.list_open list_type @output.listitem_open @output.listitem compile_inline(item) typestack.push list_type end level = new_level skip_comments f end level.times do @output.listitem_close @output.list_close typestack.pop end @output.list_end end DLIST_RE = /\A:/ def compile_dlist(f) @output.dlist_open f.while_match(DLIST_RE) do |line| dt, dd = split_dlitem(line.sub(DLIST_RE, "")) @output.dlist_item compile_inline(dt), compile_inline(dd) skip_comments f end @output.dlist_close end def split_dlitem(line) re = /\A((?:#{BRACKET_LINK_RE}|.)*?):/o if m = re.match(line) return m[1], m.post_match else return line, "" end end TABLE_RE = /\A\|\|/ def compile_table(f) lines = [] f.while_match(TABLE_RE) do |line| lines.push line skip_comments f end @output.table_open lines.each do |line| @output.table_record_open split_columns(line.sub(TABLE_RE, "")).each do |col| mid = col.sub!(/\A!/, "") ? "table_head" : "table_data" span = col.slice!(/\A[\^>]*/) rs = span_count(span, "^") cs = span_count(span, ">") @output.__send__(mid, compile_inline(col), rs, cs) end @output.table_record_close end @output.table_close end def split_columns(str) cols = str.split(/\|\|/) cols.pop if cols.last.chomp.empty? cols end def span_count(str, ch) c = str.count(ch) c == 0 ? nil : c + 1 end BLOCKQUOTE_RE = /\A""[ \t]?/ def compile_blockquote(f) @output.blockquote_open lines = [] f.while_match(BLOCKQUOTE_RE) do |line| lines.push line.sub(BLOCKQUOTE_RE, "") skip_comments f end compile_blocks lines.join("") @output.blockquote_close end INDENTED_PRE_RE = /\A[ \t]/ def compile_indented_pre(f) lines = f.span(INDENTED_PRE_RE)\ .map {|line| rstrip(line.sub(INDENTED_PRE_RE, "")) } text = restore_plugin_block(lines.join("\n")) @output.preformatted(@output.text(text)) end BLOCK_PRE_OPEN_RE = /\A<<<\s*(\w+)?/ BLOCK_PRE_CLOSE_RE = /\A>>>/ def compile_block_pre(f) m = BLOCK_PRE_OPEN_RE.match(f.gets) or raise UnexpectedError, "must not happen" str = restore_plugin_block(f.break(BLOCK_PRE_CLOSE_RE).join.chomp) f.gets @output.block_preformatted(str, m[1]) end BLANK = /\A$/ PARAGRAPH_END_RE = Regexp.union(BLANK, HEADER_RE, HRULE_RE, LIST_RE, DLIST_RE, BLOCKQUOTE_RE, TABLE_RE, INDENTED_PRE_RE, BLOCK_PRE_OPEN_RE) def compile_paragraph(f) lines = f.break(PARAGRAPH_END_RE)\ .reject {|line| COMMENT_RE =~ line } if lines.size == 1 and /\A\0(\d+)\0\z/ =~ strip(lines[0]) @output.block_plugin plugin_block($1.to_i) else line_buffer = @output.container(:paragraph) lines.each_with_index do |line, i| buffer = @output.container line_buffer << buffer compile_inline(lstrip(line).chomp, buffer) end @output.paragraph(line_buffer) end end # # Inline Level # BRACKET_LINK_RE = /\[\[.+?\]\]/ URI_RE = /(?:https?|ftp|file|mailto):[A-Za-z0-9;\/?:@&=+$,\-_.!~*\'()#%]+/ WIKI_NAME_RE = /\b(?:[A-Z]+[a-z\d]+){2,}\b/ def inline_syntax_re if @options[:use_wiki_name] if @options[:use_not_wiki_name] / (#{BRACKET_LINK_RE}) | (#{URI_RE}) | (#{MODIFIER_RE}) | (\^?#{WIKI_NAME_RE}) /xo else / (#{BRACKET_LINK_RE}) | (#{URI_RE}) | (#{MODIFIER_RE}) | (#{WIKI_NAME_RE}) /xo end else / (#{BRACKET_LINK_RE}) | (#{URI_RE}) | (#{MODIFIER_RE}) /xo end end def compile_inline(str, buf = nil) buf ||= @output.container re = inline_syntax_re pending_str = nil while m = re.match(str) str = m.post_match link, uri, mod, wiki_name = m[1, 4] if wiki_name and wiki_name[0, 1] == "^" pending_str = m.pre_match + wiki_name[1..-1] + str next end pre_str = "#{pending_str}#{m.pre_match}" pending_str = nil evaluate_plugin_block(pre_str, buf) compile_inline_markup(buf, link, uri, mod, wiki_name) end evaluate_plugin_block(pending_str || str, buf) buf end def compile_inline_markup(buf, link, uri, mod, wiki_name) case when link buf << compile_bracket_link(link[2...-2]) when uri buf << compile_uri_autolink(uri) when mod buf << compile_modifier(mod) when wiki_name buf << @output.wiki_name(wiki_name) else raise UnexpectedError, "must not happen" end end def compile_bracket_link(link) if m = /\A(.*)\|/.match(link) title = m[0].chop uri = m.post_match fixed_uri = fix_uri(uri) if can_image_link?(uri) @output.image_hyperlink(fixed_uri, title) else @output.hyperlink(fixed_uri, compile_modifier(title)) end else fixed_link = fix_uri(link) if can_image_link?(link) @output.image_hyperlink(fixed_link) else @output.hyperlink(fixed_link, @output.text(link)) end end end def can_image_link?(uri) image?(uri) and @options[:allow_bracket_inline_image] end def compile_uri_autolink(uri) if image?(uri) @output.image_hyperlink(fix_uri(uri)) else @output.hyperlink(fix_uri(uri), @output.text(uri)) end end def fix_uri(uri) if /\A(?:https?|ftp|file):(?!\/\/)/ =~ uri uri.sub(/\A\w+:/, "") else uri end end IMAGE_EXTS = %w(.jpg .jpeg .gif .png) def image?(uri) IMAGE_EXTS.include?(uri[/\.[^.]+\z/].to_s.downcase) end STRONG = "'''" EM = "''" DEL = "==" TT = "``" STRONG_RE = /'''.+?'''/ EM_RE = /''.+?''/ DEL_RE = /==.+?==/ TT_RE = /``.+?``/ MODIFIER_RE = Regexp.union(STRONG_RE, EM_RE, DEL_RE, TT_RE) MODTAG = { STRONG => "strong", EM => "em", DEL => "del", TT => 'tt' } def compile_modifier(str) buf = @output.container while m = / (#{MODIFIER_RE}) /xo.match(str) evaluate_plugin_block(m.pre_match, buf) case when chunk = m[1] mod, s = split_mod(chunk) mid = MODTAG[mod] buf << @output.__send__(mid, compile_inline(s)) else raise UnexpectedError, "must not happen" end str = m.post_match end evaluate_plugin_block(str, buf) buf end def split_mod(str) case str when /\A'''/ return str[0, 3], str[3...-3] when /\A''/ return str[0, 2], str[2...-2] when /\A==/ return str[0, 2], str[2...-2] when /\A``/ return str[0, 2], str[2...-2] else raise UnexpectedError, "must not happen: #{str.inspect}" end end def strip(str) rstrip(lstrip(str)) end def rstrip(str) str.sub(/[ \t\r\n\v\f]+\z/, "") end def lstrip(str) str.sub(/\A[ \t\r\n\v\f]+/, "") end class HTMLOutput def initialize(suffix = " />") @suffix = suffix @f = nil end def reset @f = StringIO.new end def finish @f.string end def container(_for=nil) case _for when :paragraph [] else "" end end # # Procedures # def headline(level, title) @f.puts "#{title}" end def hrule @f.puts "" end def list_close(type) @f.print "" end def listitem_open @f.print "
  • " end def listitem_close @f.puts "
  • " end def listitem(item) @f.print item end def dlist_open @f.puts "
    " end def dlist_close @f.puts "
    " end def dlist_item(dt, dd) case when dd.empty? @f.puts "
    #{dt}
    " when dt.empty? @f.puts "
    #{dd}
    " else @f.puts "
    #{dt}
    " @f.puts "
    #{dd}
    " end end def table_open @f.puts %Q() end def table_close @f.puts "
    " end def table_record_open @f.print "" end def table_record_close @f.puts "" end def table_head(item, rs, cs) @f.print "#{item}" end def table_data(item, rs, cs) @f.print "#{item}" end def tdattr(rs, cs) buf = "" buf << %Q( rowspan="#{rs}") if rs buf << %Q( colspan="#{cs}") if cs buf end private :tdattr def blockquote_open @f.print "
    " end def blockquote_close @f.puts "
    " end def block_preformatted(str, info) syntax = info ? info.downcase : nil if syntax begin convertor = Syntax::Convertors::HTML.for_syntax(syntax) @f.puts convertor.convert(str) return rescue NameError, RuntimeError @f.puts %Q|
    #{text(str)}
    | return end end preformatted(text(str)) end def preformatted(str) @f.print "
    "
          @f.print str
          @f.puts "
    " end def paragraph(lines) @f.puts "

    #{lines.join("\n")}

    " end def block_plugin(str) @f.puts %Q(
    {{#{escape_html(str)}}}
    ) end # # Functions # def hyperlink(uri, title) %Q(#{title}) end def wiki_name(name) hyperlink(name, text(name)) end def image_hyperlink(uri, alt = nil) alt ||= uri.split(/\//).last alt = escape_html(alt) %Q(#{alt}#{item}" end def em(item) "#{item}" end def del(item) "#{item}" end def tt(item) "#{item}" end def text(str) escape_html(str) end def inline_plugin(src) %Q({{#{escape_html(src)}}}) end # # Utilities # def escape_html_param(str) escape_quote(escape_html(str)) end def escape_html(text) text.gsub(/&/, "&").gsub(//, ">") end def unescape_html(text) text.gsub(/>/, ">").gsub(/</, "<").gsub(/&/, "&") end def escape_quote(text) text.gsub(/"/, """) end end class LineInput def initialize(f) @input = f @buf = [] @lineno = 0 @eof_p = false end def inspect "\#<#{self.class} file=#{@input.inspect} line=#{lineno()}>" end def eof? @eof_p end def lineno @lineno end def gets unless @buf.empty? @lineno += 1 return @buf.pop end return nil if @eof_p # to avoid ARGF blocking. line = @input.gets line = line.sub(/\r\n/, "\n") if line @eof_p = line.nil? @lineno += 1 line end def ungets(line) return unless line @lineno -= 1 @buf.push line line end def peek line = gets() ungets line if line line end def next? peek() ? true : false end def skip_blank_lines n = 0 while line = gets() unless line.strip.empty? ungets line return n end n += 1 end n end def gets_if(re) line = gets() if not line or not (re =~ line) ungets line return nil end line end def gets_unless(re) line = gets() if not line or re =~ line ungets line return nil end line end def each while line = gets() yield line end end def while_match(re) while line = gets() unless re =~ line ungets line return end yield line end nil end def getlines_while(re) buf = [] while_match(re) do |line| buf.push line end buf end alias span getlines_while # from Haskell def until_match(re) while line = gets() if re =~ line ungets line return end yield line end nil end def getlines_until(re) buf = [] until_match(re) do |line| buf.push line end buf end alias break getlines_until # from Haskell def until_terminator(re) while line = gets() return if re =~ line # discard terminal line yield line end nil end def getblock(term_re) buf = [] until_terminator(term_re) do |line| buf.push line end buf end end end if __FILE__ == $0 puts HikiDoc.to_html(ARGF.read(nil)) end hikidoc-0.0.6/Rakefile0000644000175000017500000000421411603207143014426 0ustar uwabamiuwabami# -*- ruby -*- require 'rubygems' require 'hoe' require 'find' base_dir = File.expand_path(File.dirname(__FILE__)) $LOAD_PATH.unshift(File.join(base_dir, 'lib')) require 'hikidoc' truncate_base_dir = Proc.new do |x| x.gsub(/\A#{Regexp.escape(base_dir + File::SEPARATOR)}/, '') end manifest = File.join(base_dir, "Manifest.txt") manifest_contents = [] base_dir_included_components = %w(COPYING README README.ja Rakefile TextFormattingRules TextFormattingRules.ja NEWS.ja setup.rb) excluded_components = %w(.svn doc log pkg) Find.find(base_dir) do |target| target = truncate_base_dir[target] components = target.split(File::SEPARATOR) if components.size == 1 and !File.directory?(target) next unless base_dir_included_components.include?(components[0]) end Find.prune if (excluded_components - components) != excluded_components manifest_contents << target if File.file?(target) end File.open(manifest, "w") do |f| f.puts manifest_contents.sort.join("\n") end at_exit do FileUtils.rm_f(manifest) end ENV["VERSION"] ||= HikiDoc::VERSION project = Hoe.spec('hikidoc') do |project| project.version = HikiDoc::VERSION project.author = ['Kazuhiko'] project.email = ['kazuhiko@fdiary.net'] project.description = project.paragraphs_of('README', 2).join project.summary = project.description.split(/(\.)/, 3)[0, 2].join project.url = 'http://rubyforge.org/projects/hikidoc/' project.test_globs = ['test/test_*.rb'] project.extra_rdoc_files = %w(README COPYING NEWS TextFormattingRules) project.changes = File.read("NEWS").split(/^!! .*$/)[1].strip end desc 'Tag the repository for release.' task :tag do version = HikiDoc::VERSION message = "Released HikiDoc #{version}!" base = "svn+ssh://rubyforge.org/var/svn/hikidoc/" sh 'svn', 'copy', '-m', message, "#{base}trunk", "#{base}tags/#{version}" end # Fix Hoe's uncustomizable options rdoc_main = "lib/hikidoc.rb" project.spec.rdoc_options.each do |option| option.replace(rdoc_main) if option == "README.txt" end ObjectSpace.each_object(Rake::RDocTask) do |task| task.main = rdoc_main if task.main == "README.txt" end hikidoc-0.0.6/TextFormattingRules.ja0000644000175000017500000001264711603207143017300 0ustar uwabamiuwabami!パラグラフ 連続した複数行は連結されて一つのパラグラフになります。 空行 (改行のみ、またはスペース、タブだけの行) はパラグラフの区切りになります。 *記述例 例えば、 こういう風に記述すると、これらの行は 一つのパラグラフとして整形されます。 *出力例 例えば、 こういう風に記述すると、これらの行は 一つのパラグラフとして整形されます。 !リンク !!WikiName 大文字の英字で始まり、小文字の英字または数字が1文字以上続く この条件が2回以上繰り返される単語はWikiNameになり自動的にリンクがはられます。 *記述例 WikiName - WikiName HogeRule1 - WikiName NOTWIKINAME - 全て大文字なのでWikiNameではない WikiNAME - NAMEが全て大文字なのでWikiNameではない fooWikiName - 先頭に全て小文字の英字fooがあるためWikiNameではない *出力例 **WikiName - WikiName **HogeRule1 - WikiName **NOTWIKINAME - 全て大文字なのでWikiNameではない **WikiNAME - NAMEが全て大文字なのでWikiNameではない **fooWikiName - 先頭に全て小文字の英字fooがあるためWikiNameではない WikiNameの前に''^''をつけるとWikiNameへのリンクを抑制することができます。 *記述例 WikiName - WikiName ^WikiName - WikiNameへのリンクを抑制 *出力例 **WikiName - WikiName **^WikiName - WikiNameへのリンクを抑制 !!ページへのリンク ページ名を二つのカギカッコで囲むと、そのページへのリンクになります。 *記述例 例えば[[逆引きRuby]]とすると、そのページへのリンクになります。 *出力例 例えば[[逆引きRuby]]とすると、そのページへのリンクになります。 !!任意のURLへのリンク 単語|URLを二つのカギカッコで囲むとを任意のURLへのリンクになります。 *記述例 [[Yahoo!|http://www.yahoo.co.jp/]]とかもできます。 *出力例 [[Yahoo!|http://www.yahoo.co.jp/]]とかもできます。 パラグラフ中にURLっぽいものがあると勝手にリンクがはられます。 *記述例 Hikiのページはhttp://hikiwiki.org/ja/です。 *出力例 Hikiのページはhttp://hikiwiki.org/ja/です。 このときURLの末尾がjpg,jpeg,png,gifだとIMGタグに展開されます。 *記述例 http://jp.rubyist.net/theme/clover/clover_h1.png *出力例 http://jp.rubyist.net/theme/clover/clover_h1.png !整形済みテキスト 行の先頭がスペースまたはタブで始まっていると、その行は整形済みとして扱われます。 *出力例 require 'cgi' cgi = CGI::new cgi.header puts < Hello!

    Hello!

    EOS !文字の修飾 「'」2個ではさんだ部分は強調されます。 「'」3個ではさんだ部分はさらに強調されます。 「=」2個ではさんだ部分は取消線になります。 「`」2個ではさんだ部分は等幅表示になります。 *記述例 このようにすると''強調''になります。 そして、このようにすると'''さらに強調'''されます。 ==だるいけど==さらに、取り消し線もサポートしています。 またまた、このようにすると''等幅表示''になります。 *出力例 このようにすると''強調''になります。 そして、このようにすると'''さらに強調'''されます。 ==だるいけど==さらに、取り消し線もサポートしています。 またまた、このようにすると''等幅表示''になります。 !見出し 「!」を行の先頭に書くと見出しになります。 「!」は一つから六つまで記述することが可能で、それぞれ

    に変換されます。 *記述例 !見出し1 !!見出し2 !!!見出し3 !!!!見出し4 !!!!!見出し5 *出力例 !見出し1 !!見出し2 !!!見出し3 !!!!見出し4 !!!!!見出し5 !水平線 マイナス記号「-」を行の先頭から4つ書くと水平線になります。 *記述例 あいうえお。 ---- かきくけこ。 *出力例 あいうえお。 ---- かきくけこ。 !箇条書き 「*」を行の先頭に書くと箇条書きになります。 「*」は一つから三つまで記述することが可能で入れ子にすることもできます。 「#」を行の先頭に書くと番号付きの箇条書きになります。 *記述例 *アイテム1 **アイテム1.1 **アイテム1.2 ***アイテム1.2.1 ***アイテム1.2.2 ***アイテム1.2.3 **アイテム1.3 **アイテム1.4 *アイテム2 #その1 #その2 ##その2.1 ##その2.2 ##その2.3 #その3 ##その3.1 ###その3.1.1 ###その3.1.2 *出力例 *アイテム1 **アイテム1.1 **アイテム1.2 ***アイテム1.2.1 ***アイテム1.2.2 ***アイテム1.2.3 **アイテム1.3 **アイテム1.4 *アイテム2 #その1 #その2 ##その2.1 ##その2.2 ##その2.3 #その3 ##その3.1 ###その3.1.1 ###その3.1.2 !引用 「"」を行の先頭から二つ書くと引用になります。 *記述例 ""これは引用です。 ""さらに引用します。 ""続けて引用します。引用が連続する場合、 ""このように一つの引用として ""展開されます。 *出力例 ""これは引用です。 ""さらに引用します。 ""続けて引用します。引用が連続する場合、 ""このように一つの引用として ""展開されます。 !用語解説 コロン「:」を行の先頭に書き、続けて用語:解説文とすると用語解説になります。 *記述例 :りんご:apple :ゴリラ:gorilla :ラクダ:camel *出力例 :りんご:apple :ゴリラ:gorilla :ラクダ:camel !表 表(テーブル)は「||」で始めます。 セルの項目の頭に「!」をつけることにより見出しセルになります。 行の連結には「^」を列の連結には「>」を、連結したい数だけセルの項目頭につけてください。 *記述例 ||!行見出し\列見出し||!列-A||!列-B||!列-C||!>列-D-E(横連結) ||!行-1||A1||B1||^C1-C2(縦連結)||D1||E1 ||!行-2||A2||B2||^>D2-E2-D3-E3(縦横連結) ||!行-3||>>A3-C3(横3連結) *出力例 ||!行見出し\列見出し||!列-A||!列-B||!列-C||!>列-D-E(横連結) ||!行-1||A1||B1||^C1-C2(縦連結)||D1||E1 ||!行-2||A2||B2||^>D2-E2-D3-E3(縦横連結) ||!行-3||>>A3-C3(横3連結) !コメント行 「//」が行頭にある行はコメント行になり、出力されなくなります。 *記述例 // ここはコメントです。 *出力例(表示されません) // ここはコメントです。 !プラグイン 「{」二つと「}」二つで囲むとプラグインを呼び出すことができます。 パラメータを複数行に分けて書くことも可能です。 プラグインのみを単独行に書いた場合はブロックプラグインになり、前後に

    が付かなくなります。 *記述例 {{recent(3)}} *複数行記述例 {{pre( パラメータ1 パラメータ2 パラメータ3 )}} hikidoc-0.0.6/setup.rb0000644000175000017500000007110411603207143014450 0ustar uwabamiuwabami# # setup.rb # # Copyright (c) 2000-2004 Minero Aoki # # This program is free software. # You can distribute/modify this program under the terms of # the GNU LGPL, Lesser General Public License version 2.1. # unless Enumerable.method_defined?(:map) # Ruby 1.4.6 module Enumerable alias map collect end end unless File.respond_to?(:read) # Ruby 1.6 def File.read(fname) open(fname) {|f| return f.read } end end def File.binread(fname) open(fname, 'rb') {|f| return f.read } end # for corrupted windows stat(2) def File.dir?(path) File.directory?((path[-1,1] == '/') ? path : path + '/') end class SetupError < StandardError; end def setup_rb_error(msg) raise SetupError, msg end # # Config # if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg } ARGV.delete(arg) require arg.split(/=/, 2)[1] $".push 'rbconfig.rb' else require 'rbconfig' end def multipackage_install? FileTest.directory?(File.dirname($0) + '/packages') end class ConfigItem def initialize(name, template, default, desc) @name = name.freeze @template = template @value = default @default = default.dup.freeze @description = desc end attr_reader :name attr_reader :description attr_accessor :default alias help_default default def help_opt "--#{@name}=#{@template}" end def value @value end def eval(table) @value.gsub(%r<\$([^/]+)>) { table[$1] } end def set(val) @value = check(val) end private def check(val) setup_rb_error "config: --#{name} requires argument" unless val val end end class BoolItem < ConfigItem def config_type 'bool' end def help_opt "--#{@name}" end private def check(val) return 'yes' unless val unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ val setup_rb_error "config: --#{@name} accepts only yes/no for argument" end (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no' end end class PathItem < ConfigItem def config_type 'path' end private def check(path) setup_rb_error "config: --#{@name} requires argument" unless path path[0,1] == '$' ? path : File.expand_path(path) end end class ProgramItem < ConfigItem def config_type 'program' end end class SelectItem < ConfigItem def initialize(name, template, default, desc) super @ok = template.split('/') end def config_type 'select' end private def check(val) unless @ok.include?(val.strip) setup_rb_error "config: use --#{@name}=#{@template} (#{val})" end val.strip end end class PackageSelectionItem < ConfigItem def initialize(name, template, default, help_default, desc) super name, template, default, desc @help_default = help_default end attr_reader :help_default def config_type 'package' end private def check(val) unless File.dir?("packages/#{val}") setup_rb_error "config: no such package: #{val}" end val end end class ConfigTable_class def initialize(items) @items = items @table = {} items.each do |i| @table[i.name] = i end ALIASES.each do |ali, name| @table[ali] = @table[name] end end include Enumerable def each(&block) @items.each(&block) end def key?(name) @table.key?(name) end def lookup(name) @table[name] or raise ArgumentError, "no such config item: #{name}" end def add(item) @items.push item @table[item.name] = item end def remove(name) item = lookup(name) @items.delete_if {|i| i.name == name } @table.delete_if {|name, i| i.name == name } item end def new dup() end def savefile '.config' end def load begin t = dup() File.foreach(savefile()) do |line| k, v = *line.split(/=/, 2) t[k] = v.strip end t rescue Errno::ENOENT setup_rb_error $!.message + "#{File.basename($0)} config first" end end def save @items.each {|i| i.value } File.open(savefile(), 'w') {|f| @items.each do |i| f.printf "%s=%s\n", i.name, i.value if i.value end } end def [](key) lookup(key).eval(self) end def []=(key, val) lookup(key).set val end end c = ::Config::CONFIG rubypath = c['bindir'] + '/' + c['ruby_install_name'] major = c['MAJOR'].to_i minor = c['MINOR'].to_i teeny = c['TEENY'].to_i version = "#{major}.#{minor}" # ruby ver. >= 1.4.4? newpath_p = ((major >= 2) or ((major == 1) and ((minor >= 5) or ((minor == 4) and (teeny >= 4))))) if c['rubylibdir'] # V < 1.6.3 _stdruby = c['rubylibdir'] _siteruby = c['sitedir'] _siterubyver = c['sitelibdir'] _siterubyverarch = c['sitearchdir'] elsif newpath_p # 1.4.4 <= V <= 1.6.3 _stdruby = "$prefix/lib/ruby/#{version}" _siteruby = c['sitedir'] _siterubyver = "$siteruby/#{version}" _siterubyverarch = "$siterubyver/#{c['arch']}" else # V < 1.4.4 _stdruby = "$prefix/lib/ruby/#{version}" _siteruby = "$prefix/lib/ruby/#{version}/site_ruby" _siterubyver = _siteruby _siterubyverarch = "$siterubyver/#{c['arch']}" end libdir = '-* dummy libdir *-' stdruby = '-* dummy rubylibdir *-' siteruby = '-* dummy site_ruby *-' siterubyver = '-* dummy site_ruby version *-' parameterize = lambda {|path| path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')\ .sub(/\A#{Regexp.quote(libdir)}/, '$libdir')\ .sub(/\A#{Regexp.quote(stdruby)}/, '$stdruby')\ .sub(/\A#{Regexp.quote(siteruby)}/, '$siteruby')\ .sub(/\A#{Regexp.quote(siterubyver)}/, '$siterubyver') } libdir = parameterize.call(c['libdir']) stdruby = parameterize.call(_stdruby) siteruby = parameterize.call(_siteruby) siterubyver = parameterize.call(_siterubyver) siterubyverarch = parameterize.call(_siterubyverarch) if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg } makeprog = arg.sub(/'/, '').split(/=/, 2)[1] else makeprog = 'make' end common_conf = [ PathItem.new('prefix', 'path', c['prefix'], 'path prefix of target environment'), PathItem.new('bindir', 'path', parameterize.call(c['bindir']), 'the directory for commands'), PathItem.new('libdir', 'path', libdir, 'the directory for libraries'), PathItem.new('datadir', 'path', parameterize.call(c['datadir']), 'the directory for shared data'), PathItem.new('mandir', 'path', parameterize.call(c['mandir']), 'the directory for man pages'), PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']), 'the directory for man pages'), PathItem.new('stdruby', 'path', stdruby, 'the directory for standard ruby libraries'), PathItem.new('siteruby', 'path', siteruby, 'the directory for version-independent aux ruby libraries'), PathItem.new('siterubyver', 'path', siterubyver, 'the directory for aux ruby libraries'), PathItem.new('siterubyverarch', 'path', siterubyverarch, 'the directory for aux ruby binaries'), PathItem.new('rbdir', 'path', '$siterubyver', 'the directory for ruby scripts'), PathItem.new('sodir', 'path', '$siterubyverarch', 'the directory for ruby extentions'), PathItem.new('rubypath', 'path', rubypath, 'the path to set to #! line'), ProgramItem.new('rubyprog', 'name', rubypath, 'the ruby program using for installation'), ProgramItem.new('makeprog', 'name', makeprog, 'the make program to compile ruby extentions'), SelectItem.new('shebang', 'all/ruby/never', 'ruby', 'shebang line (#!) editing mode'), BoolItem.new('without-ext', 'yes/no', 'no', 'does not compile/install ruby extentions') ] class ConfigTable_class # open again ALIASES = { 'std-ruby' => 'stdruby', 'site-ruby-common' => 'siteruby', # For backward compatibility 'site-ruby' => 'siterubyver', # For backward compatibility 'bin-dir' => 'bindir', 'bin-dir' => 'bindir', 'rb-dir' => 'rbdir', 'so-dir' => 'sodir', 'data-dir' => 'datadir', 'ruby-path' => 'rubypath', 'ruby-prog' => 'rubyprog', 'ruby' => 'rubyprog', 'make-prog' => 'makeprog', 'make' => 'makeprog' } end multipackage_conf = [ PackageSelectionItem.new('with', 'name,name...', '', 'ALL', 'package names that you want to install'), PackageSelectionItem.new('without', 'name,name...', '', 'NONE', 'package names that you do not want to install') ] if multipackage_install? ConfigTable = ConfigTable_class.new(common_conf + multipackage_conf) else ConfigTable = ConfigTable_class.new(common_conf) end module MetaConfigAPI def eval_file_ifexist(fname) instance_eval File.read(fname), fname, 1 if File.file?(fname) end def config_names ConfigTable.map {|i| i.name } end def config?(name) ConfigTable.key?(name) end def bool_config?(name) ConfigTable.lookup(name).config_type == 'bool' end def path_config?(name) ConfigTable.lookup(name).config_type == 'path' end def value_config?(name) case ConfigTable.lookup(name).config_type when 'bool', 'path' true else false end end def add_config(item) ConfigTable.add item end def add_bool_config(name, default, desc) ConfigTable.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc) end def add_path_config(name, default, desc) ConfigTable.add PathItem.new(name, 'path', default, desc) end def set_config_default(name, default) ConfigTable.lookup(name).default = default end def remove_config(name) ConfigTable.remove(name) end end # # File Operations # module FileOperations def mkdir_p(dirname, prefix = nil) dirname = prefix + File.expand_path(dirname) if prefix $stderr.puts "mkdir -p #{dirname}" if verbose? return if no_harm? # does not check '/'... it's too abnormal case dirs = File.expand_path(dirname).split(%r<(?=/)>) if /\A[a-z]:\z/i =~ dirs[0] disk = dirs.shift dirs[0] = disk + dirs[0] end dirs.each_index do |idx| path = dirs[0..idx].join('') Dir.mkdir path unless File.dir?(path) end end def rm_f(fname) $stderr.puts "rm -f #{fname}" if verbose? return if no_harm? if File.exist?(fname) or File.symlink?(fname) File.chmod 0777, fname File.unlink fname end end def rm_rf(dn) $stderr.puts "rm -rf #{dn}" if verbose? return if no_harm? Dir.chdir dn Dir.foreach('.') do |fn| next if fn == '.' next if fn == '..' if File.dir?(fn) verbose_off { rm_rf fn } else verbose_off { rm_f fn } end end Dir.chdir '..' Dir.rmdir dn end def move_file(src, dest) File.unlink dest if File.exist?(dest) begin File.rename src, dest rescue File.open(dest, 'wb') {|f| f.write File.binread(src) } File.chmod File.stat(src).mode, dest File.unlink src end end def install(from, dest, mode, prefix = nil) $stderr.puts "install #{from} #{dest}" if verbose? return if no_harm? realdest = prefix ? prefix + File.expand_path(dest) : dest realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest) str = File.binread(from) if diff?(str, realdest) verbose_off { rm_f realdest if File.exist?(realdest) } File.open(realdest, 'wb') {|f| f.write str } File.chmod mode, realdest File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| if prefix f.puts realdest.sub(prefix, '') else f.puts realdest end } end end def diff?(new_content, path) return true unless File.exist?(path) new_content != File.binread(path) end def command(str) $stderr.puts str if verbose? system str or raise RuntimeError, "'system #{str}' failed" end def ruby(str) command config('rubyprog') + ' ' + str end def make(task = '') command config('makeprog') + ' ' + task end def extdir?(dir) File.exist?(dir + '/MANIFEST') end def all_files_in(dirname) Dir.open(dirname) {|d| return d.select {|ent| File.file?("#{dirname}/#{ent}") } } end REJECT_DIRS = %w( CVS SCCS RCS CVS.adm .svn ) def all_dirs_in(dirname) Dir.open(dirname) {|d| return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS } end end # # Main Installer # module HookUtils def run_hook(name) try_run_hook "#{curr_srcdir()}/#{name}" or try_run_hook "#{curr_srcdir()}/#{name}.rb" end def try_run_hook(fname) return false unless File.file?(fname) begin instance_eval File.read(fname), fname, 1 rescue setup_rb_error "hook #{fname} failed:\n" + $!.message end true end end module HookScriptAPI def get_config(key) @config[key] end alias config get_config def set_config(key, val) @config[key] = val end # # srcdir/objdir (works only in the package directory) # #abstract srcdir_root #abstract objdir_root #abstract relpath def curr_srcdir "#{srcdir_root()}/#{relpath()}" end def curr_objdir "#{objdir_root()}/#{relpath()}" end def srcfile(path) "#{curr_srcdir()}/#{path}" end def srcexist?(path) File.exist?(srcfile(path)) end def srcdirectory?(path) File.dir?(srcfile(path)) end def srcfile?(path) File.file? srcfile(path) end def srcentries(path = '.') Dir.open("#{curr_srcdir()}/#{path}") {|d| return d.to_a - %w(. ..) } end def srcfiles(path = '.') srcentries(path).select {|fname| File.file?(File.join(curr_srcdir(), path, fname)) } end def srcdirectories(path = '.') srcentries(path).select {|fname| File.dir?(File.join(curr_srcdir(), path, fname)) } end end class ToplevelInstaller Version = '3.3.1' Copyright = 'Copyright (c) 2000-2004 Minero Aoki' TASKS = [ [ 'all', 'do config, setup, then install' ], [ 'config', 'saves your configurations' ], [ 'show', 'shows current configuration' ], [ 'setup', 'compiles ruby extentions and others' ], [ 'install', 'installs files' ], [ 'clean', "does `make clean' for each extention" ], [ 'distclean',"does `make distclean' for each extention" ] ] def ToplevelInstaller.invoke instance().invoke end @singleton = nil def ToplevelInstaller.instance @singleton ||= new(File.dirname($0)) @singleton end include MetaConfigAPI def initialize(ardir_root) @config = nil @options = { 'verbose' => true } @ardir = File.expand_path(ardir_root) end def inspect "#<#{self.class} #{__id__()}>" end def invoke run_metaconfigs case task = parsearg_global() when nil, 'all' @config = load_config('config') parsearg_config init_installers exec_config exec_setup exec_install else @config = load_config(task) __send__ "parsearg_#{task}" init_installers __send__ "exec_#{task}" end end def run_metaconfigs eval_file_ifexist "#{@ardir}/metaconfig" end def load_config(task) case task when 'config' ConfigTable.new when 'clean', 'distclean' if File.exist?(ConfigTable.savefile) then ConfigTable.load else ConfigTable.new end else ConfigTable.load end end def init_installers @installer = Installer.new(@config, @options, @ardir, File.expand_path('.')) end # # Hook Script API bases # def srcdir_root @ardir end def objdir_root '.' end def relpath '.' end # # Option Parsing # def parsearg_global valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/ while arg = ARGV.shift case arg when /\A\w+\z/ setup_rb_error "invalid task: #{arg}" unless valid_task =~ arg return arg when '-q', '--quiet' @options['verbose'] = false when '--verbose' @options['verbose'] = true when '-h', '--help' print_usage $stdout exit 0 when '-v', '--version' puts "#{File.basename($0)} version #{Version}" exit 0 when '--copyright' puts Copyright exit 0 else setup_rb_error "unknown global option '#{arg}'" end end nil end def parsearg_no_options unless ARGV.empty? setup_rb_error "#{task}: unknown options: #{ARGV.join ' '}" end end alias parsearg_show parsearg_no_options alias parsearg_setup parsearg_no_options alias parsearg_clean parsearg_no_options alias parsearg_distclean parsearg_no_options def parsearg_config re = /\A--(#{ConfigTable.map {|i| i.name }.join('|')})(?:=(.*))?\z/ @options['config-opt'] = [] while i = ARGV.shift if /\A--?\z/ =~ i @options['config-opt'] = ARGV.dup break end m = re.match(i) or setup_rb_error "config: unknown option #{i}" name, value = *m.to_a[1,2] @config[name] = value end end def parsearg_install @options['no-harm'] = false @options['install-prefix'] = '' while a = ARGV.shift case a when /\A--no-harm\z/ @options['no-harm'] = true when /\A--prefix=(.*)\z/ path = $1 path = File.expand_path(path) unless path[0,1] == '/' @options['install-prefix'] = path else setup_rb_error "install: unknown option #{a}" end end end def print_usage(out) out.puts 'Typical Installation Procedure:' out.puts " $ ruby #{File.basename $0} config" out.puts " $ ruby #{File.basename $0} setup" out.puts " # ruby #{File.basename $0} install (may require root privilege)" out.puts out.puts 'Detailed Usage:' out.puts " ruby #{File.basename $0} " out.puts " ruby #{File.basename $0} [] []" fmt = " %-24s %s\n" out.puts out.puts 'Global options:' out.printf fmt, '-q,--quiet', 'suppress message outputs' out.printf fmt, ' --verbose', 'output messages verbosely' out.printf fmt, '-h,--help', 'print this message' out.printf fmt, '-v,--version', 'print version and quit' out.printf fmt, ' --copyright', 'print copyright and quit' out.puts out.puts 'Tasks:' TASKS.each do |name, desc| out.printf fmt, name, desc end fmt = " %-24s %s [%s]\n" out.puts out.puts 'Options for CONFIG or ALL:' ConfigTable.each do |item| out.printf fmt, item.help_opt, item.description, item.help_default end out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's" out.puts out.puts 'Options for INSTALL:' out.printf fmt, '--no-harm', 'only display what to do if given', 'off' out.printf fmt, '--prefix=path', 'install path prefix', '$prefix' out.puts end # # Task Handlers # def exec_config @installer.exec_config @config.save # must be final end def exec_setup @installer.exec_setup end def exec_install @installer.exec_install end def exec_show ConfigTable.each do |i| printf "%-20s %s\n", i.name, i.value end end def exec_clean @installer.exec_clean end def exec_distclean @installer.exec_distclean end end class ToplevelInstallerMulti < ToplevelInstaller include HookUtils include HookScriptAPI include FileOperations def initialize(ardir) super @packages = all_dirs_in("#{@ardir}/packages") raise 'no package exists' if @packages.empty? end def run_metaconfigs eval_file_ifexist "#{@ardir}/metaconfig" @packages.each do |name| eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig" end end def init_installers @installers = {} @packages.each do |pack| @installers[pack] = Installer.new(@config, @options, "#{@ardir}/packages/#{pack}", "packages/#{pack}") end with = extract_selection(config('with')) without = extract_selection(config('without')) @selected = @installers.keys.select {|name| (with.empty? or with.include?(name)) \ and not without.include?(name) } end def extract_selection(list) a = list.split(/,/) a.each do |name| setup_rb_error "no such package: #{name}" unless @installers.key?(name) end a end def print_usage(f) super f.puts 'Inluded packages:' f.puts ' ' + @packages.sort.join(' ') f.puts end # # multi-package metaconfig API # attr_reader :packages def declare_packages(list) raise 'package list is empty' if list.empty? list.each do |name| raise "directory packages/#{name} does not exist"\ unless File.dir?("#{@ardir}/packages/#{name}") end @packages = list end # # Task Handlers # def exec_config run_hook 'pre-config' each_selected_installers {|inst| inst.exec_config } run_hook 'post-config' @config.save # must be final end def exec_setup run_hook 'pre-setup' each_selected_installers {|inst| inst.exec_setup } run_hook 'post-setup' end def exec_install run_hook 'pre-install' each_selected_installers {|inst| inst.exec_install } run_hook 'post-install' end def exec_clean rm_f ConfigTable.savefile run_hook 'pre-clean' each_selected_installers {|inst| inst.exec_clean } run_hook 'post-clean' end def exec_distclean rm_f ConfigTable.savefile run_hook 'pre-distclean' each_selected_installers {|inst| inst.exec_distclean } run_hook 'post-distclean' end # # lib # def each_selected_installers Dir.mkdir 'packages' unless File.dir?('packages') @selected.each do |pack| $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose'] Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}") Dir.chdir "packages/#{pack}" yield @installers[pack] Dir.chdir '../..' end end def verbose? @options['verbose'] end def no_harm? @options['no-harm'] end end class Installer FILETYPES = %w( bin lib ext data ) include HookScriptAPI include HookUtils include FileOperations def initialize(config, opt, srcroot, objroot) @config = config @options = opt @srcdir = File.expand_path(srcroot) @objdir = File.expand_path(objroot) @currdir = '.' end def inspect "#<#{self.class} #{File.basename(@srcdir)}>" end # # Hook Script API base methods # def srcdir_root @srcdir end def objdir_root @objdir end def relpath @currdir end # # configs/options # def no_harm? @options['no-harm'] end def verbose? @options['verbose'] end def verbose_off begin save, @options['verbose'] = @options['verbose'], false yield ensure @options['verbose'] = save end end # # TASK config # def exec_config exec_task_traverse 'config' end def config_dir_bin(rel) end def config_dir_lib(rel) end def config_dir_ext(rel) extconf if extdir?(curr_srcdir()) end def extconf opt = @options['config-opt'].join(' ') command "#{config('rubyprog')} #{curr_srcdir()}/extconf.rb #{opt}" end def config_dir_data(rel) end # # TASK setup # def exec_setup exec_task_traverse 'setup' end def setup_dir_bin(rel) all_files_in(curr_srcdir()).each do |fname| adjust_shebang "#{curr_srcdir()}/#{fname}" end end def adjust_shebang(path) return if no_harm? tmpfile = File.basename(path) + '.tmp' begin File.open(path, 'rb') {|r| first = r.gets return unless File.basename(config('rubypath')) == 'ruby' return unless File.basename(first.sub(/\A\#!/, '').split[0]) == 'ruby' $stderr.puts "adjusting shebang: #{File.basename(path)}" if verbose? File.open(tmpfile, 'wb') {|w| w.print first.sub(/\A\#!\s*\S+/, '#! ' + config('rubypath')) w.write r.read } move_file tmpfile, File.basename(path) } ensure File.unlink tmpfile if File.exist?(tmpfile) end end def setup_dir_lib(rel) end def setup_dir_ext(rel) make if extdir?(curr_srcdir()) end def setup_dir_data(rel) end # # TASK install # def exec_install rm_f 'InstalledFiles' exec_task_traverse 'install' end def install_dir_bin(rel) install_files collect_filenames_auto(), "#{config('bindir')}/#{rel}", 0755 end def install_dir_lib(rel) install_files ruby_scripts(), "#{config('rbdir')}/#{rel}", 0644 end def install_dir_ext(rel) return unless extdir?(curr_srcdir()) install_files ruby_extentions('.'), "#{config('sodir')}/#{File.dirname(rel)}", 0555 end def install_dir_data(rel) install_files collect_filenames_auto(), "#{config('datadir')}/#{rel}", 0644 end def install_files(list, dest, mode) mkdir_p dest, @options['install-prefix'] list.each do |fname| install fname, dest, mode, @options['install-prefix'] end end def ruby_scripts collect_filenames_auto().select {|n| /\.rb\z/ =~ n } end # picked up many entries from cvs-1.11.1/src/ignore.c reject_patterns = %w( core RCSLOG tags TAGS .make.state .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb *~ *.old *.bak *.BAK *.orig *.rej _$* *$ *.org *.in .* ) mapping = { '.' => '\.', '$' => '\$', '#' => '\#', '*' => '.*' } REJECT_PATTERNS = Regexp.new('\A(?:' + reject_patterns.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] } }.join('|') + ')\z') def collect_filenames_auto mapdir((existfiles() - hookfiles()).reject {|fname| REJECT_PATTERNS =~ fname }) end def existfiles all_files_in(curr_srcdir()) | all_files_in('.') end def hookfiles %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| %w( config setup install clean ).map {|t| sprintf(fmt, t) } }.flatten end def mapdir(filelist) filelist.map {|fname| if File.exist?(fname) # objdir fname else # srcdir File.join(curr_srcdir(), fname) end } end def ruby_extentions(dir) Dir.open(dir) {|d| ents = d.select {|fname| /\.#{::Config::CONFIG['DLEXT']}\z/ =~ fname } if ents.empty? setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first" end return ents } end # # TASK clean # def exec_clean exec_task_traverse 'clean' rm_f ConfigTable.savefile rm_f 'InstalledFiles' end def clean_dir_bin(rel) end def clean_dir_lib(rel) end def clean_dir_ext(rel) return unless extdir?(curr_srcdir()) make 'clean' if File.file?('Makefile') end def clean_dir_data(rel) end # # TASK distclean # def exec_distclean exec_task_traverse 'distclean' rm_f ConfigTable.savefile rm_f 'InstalledFiles' end def distclean_dir_bin(rel) end def distclean_dir_lib(rel) end def distclean_dir_ext(rel) return unless extdir?(curr_srcdir()) make 'distclean' if File.file?('Makefile') end # # lib # def exec_task_traverse(task) run_hook "pre-#{task}" FILETYPES.each do |type| if config('without-ext') == 'yes' and type == 'ext' $stderr.puts 'skipping ext/* by user option' if verbose? next end traverse task, type, "#{task}_dir_#{type}" end run_hook "post-#{task}" end def traverse(task, rel, mid) dive_into(rel) { run_hook "pre-#{task}" __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') all_dirs_in(curr_srcdir()).each do |d| traverse task, "#{rel}/#{d}", mid end run_hook "post-#{task}" } end def dive_into(rel) return unless File.dir?("#{@srcdir}/#{rel}") dir = File.basename(rel) Dir.mkdir dir unless File.dir?(dir) prevdir = Dir.pwd Dir.chdir dir $stderr.puts '---> ' + rel if verbose? @currdir = rel yield Dir.chdir prevdir $stderr.puts '<--- ' + rel if verbose? @currdir = File.dirname(rel) end end if $0 == __FILE__ begin if multipackage_install? ToplevelInstallerMulti.invoke else ToplevelInstaller.invoke end rescue SetupError raise if $DEBUG $stderr.puts $!.message $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." exit 1 end end hikidoc-0.0.6/TextFormattingRules0000644000175000017500000001545611603207143016710 0ustar uwabamiuwabami!Paragraphs Consecutive lines are concatenated into a single paragraph. Blank lines (ones with only a carriage return or with only spaces and tabs) mark the end of a paragraph. *Example statement For example, if I write like this, these lines will be formatted as one paragraph. *Example output For example, if I write like this, these lines will be formatted as one paragraph. !Links !!WikiNames WikiNames are comprised of two or more words put together; each word begins with an uppercase letter, and is followed by at least one lowercase letter or number. Words in which this condition is met become a WikiName, and a link is automatically attached. *Example statement WikiName - WikiName HogeRule1 - WikiName NOTWIKINAME - All of the letters are uppercase, so this is not a WikiName WikiNAME - All of the letters in NAME are uppercase, so this is not a WikiName fooWikiName - This begins with "foo", which is in all lowercase, so this is not a WikiName *Example output **WikiName - WikiName **HogeRule1 - WikiName **NOTWIKINAME - All of the letters are uppercase, so this is not a WikiName **WikiNAME - All of the letters in NAME are uppercase, so this is not a WikiName **fooWikiName - This begins with "foo", which is in all lowercase, so this is not a WikiName You can disable an auto WikiName link by putting ''^'' to the WikiName. *Example statement WikiName - WikiName ^WikiName - Disable WikiName link *Example output **WikiName - WikiName **^WikiName - Disable WikiName link !!Linking to other Wiki pages If a page name is surrounded with two pairs of brackets, it becomes a link to that page. *Example statement For example, if you write [[TextFormattingRules]], it becomes a link to that page. *Example output For example, if you write [[TextFormattingRules]], it becomes a link to that page. !!Linking to an arbitrary URL If a phrase and URL, separated by a vertical line, are surrounded with two pairs of brackets, it becomes a link to an arbitrary URL. *Example statement Links like [[Yahoo!|http://www.yahoo.com/]] are also possible. *Example output Links like [[Yahoo!|http://www.yahoo.com/]] are also possible. Text in a paragraph that looks like a URL will automatically become a link. *Example statement Hiki's home page is http://hikiwiki.org/en/ (English). *Example output Hiki's home page is http://hikiwiki.org/en/ (English). In this case, if the URL ends with jpg., .jpeg, .png, or .gif, the image is displayed on the page. *Example statement http://jp.rubyist.net/theme/clover/clover_h1.png *Example output http://jp.rubyist.net/theme/clover/clover_h1.png !Preformatted text Lines beginning with spaces or tabs will be treated as preformatted text. *Example output require 'cgi' cgi = CGI::new cgi.header puts < Hello!

    Hello!

    EOS !Text decoration Text surrounded by sets of two single quotes ('') is emphasised. Text surrounded by sets of three single quotes (''') is strongly emphasised. Text surrounded by sets of double equal signs (===) is struck out. Text surrounded by sets of double backquotes (``) is inline literal. *Example statement If you write like this, it becomes ''emphasised''. And if you write like this, it becomes '''strongly emphasised'''. ==This is dull, but== And struck-out text is supported, too! If you write like this, it becomes ``monospaced text``. *Example output If you write like this, it becomes ''emphasised''. And if you write like this, it becomes '''strongly emphasised'''. ==This is dull, but== And struck-out text is supported, too! If you write like this, it becomes ``monospaced text``. !Headings Lines with exclamation marks at the beginning become headings. One can use up to six exclamation marks; they will be converted to

    to

    tags. *Example statement !Heading1 !!Heading2 !!!Heading3 !!!!Heading4 !!!!!Heading5 *Example output !Heading1 !!Heading2 !!!Heading3 !!!!Heading4 !!!!!Heading5 !Horizontal lines Four hyphens at the beginning of the line (----) become a horizontal rule. *Example statement A B C D E ---- F G H I J *Example output A B C D E ---- F G H I J !Lists Lines beginning with asterisks become list items. It is possible to use up to three asterisks; it is also possible to create nested lists. Lines beginning with a # become numbered lists. *Example statement *Item 1 **Item 1.1 **Item 1.2 ***Item 1.2.1 ***Item 1.2.2 ***Item 1.2.3 **Item 1.3 **Item 1.4 *Item 2 #Item 1 #Item 2 ##Item 2.1 ##Item 2.2 ##Item 2.3 #Item 3 ##Item 3.1 ###Item 3.1.1 ###Item 3.1.2 *Example output *Item 1 **Item 1.1 **Item 1.2 ***Item 1.2.1 ***Item 1.2.2 ***Item 1.2.3 **Item 1.3 **Item 1.4 *Item 2 #Item 1 #Item 2 ##Item 2.1 ##Item 2.2 ##Item 2.3 #Item 3 ##Item 3.1 ###Item 3.1.1 ###Item 3.1.2 !Quotations Lines beginning with two double quotes become quotations. *Example statement ""This is a quotation. ""This is another quote. ""This is a continued quote. When there are consecutive quotations, ""they are displayed as one quote, ""like this. *Example output ""This is a quotation. ""This is another quote. ""This is a continued quote. When there are consecutive quotations, ""they are displayed as one quote, ""like this. !Definitions Lines beginning with a colon and have a phrase and explanation separated by another colon will become a definition. *Example statement :ringo:apple :gorira:gorilla :rakuda:camel *Example output :ringo:apple :gorira:gorilla :rakuda:camel ! Tables Tables begin with two vertical bars. Leading `!' in a cell means that it is a heading cell. To concatenate columns or rows, put `>'(columns) or `^'(rows) at head of the cell. * Example statement ||!row heading \ column heading||!column A||!column B||!column C||!>column D-E (horizontal concatenation) ||!row 1||A1||B1||^C1-C2 (vertical concatenation)||D1||E1 ||!row 2||A2||B2||^>D2-E2-D3-E3 (vertical and horizontal concatenation) ||!row 3||>>A3-C3 (horizontal concatenation) * Example output ||!row heading \ column heading||!column A||!column B||!column C||!>column D-E (horizontal concatenation) ||!row 1||A1||B1||^C1-C2 (vertical concatenation)||D1||E1 ||!row 2||A2||B2||^>D2-E2-D3-E3 (vertical and horizontal concatenation) ||!row 3||>>A3-C3 (horizontal concatenation) ! Comments Lines starting with `//' becomes a comment line. Comment lines is not outputted. * Example statement // This is a comment line. * Example output (not displayed) // This is a comment line. !Plugins One can use a plugin by surrounding text with two pairs of brackets. Multiple lines parameter is supported. When a line contains plugin only, it becomes a block plugin, which is not surrounded by

    ...

    . *Example statement {{recent(3)}} * Example statement of multiple lines {{pre(' ... ')}}