├── data ├── cache │ └── .keep ├── sessions ├── articles │ ├── FAQ │ ├── About │ └── Main_Page ├── page_tags │ ├── FAQ │ ├── About │ └── Main_Page ├── index ├── recent-changes ├── tags_count ├── tags_index ├── users └── modifications │ ├── 0 │ ├── 16571 │ ├── 164992 │ ├── 634664.2746 │ └── 404869.874449968338 ├── deps.proto ├── t ├── tags │ ├── data │ │ ├── tags_count │ │ ├── tags_index │ │ └── page_tags │ │ │ ├── Test_Page │ │ │ └── Another_Page │ ├── norm.t │ ├── parser.t │ ├── norm_counts.t │ └── update_tags.t ├── storage │ ├── data │ │ └── modifications │ │ │ └── empty-file │ ├── save_page.t │ ├── modification.t │ └── index.t ├── markup │ ├── minimal │ │ ├── 01-use.t │ │ ├── 02-normal-text.t │ │ ├── 04-paragraphs.t │ │ ├── 03-escaping.t │ │ ├── 05-headings.t │ │ └── 06-links.t │ └── mediawiki │ │ ├── 01-use.t │ │ ├── 27-entities.t │ │ ├── 02-normal-text.t │ │ ├── 16-pre.t │ │ ├── 03-escaping.t │ │ ├── 99-fail.t │ │ ├── 04-paragraphs.t │ │ ├── 09-line-breaks.t │ │ ├── 15-mixed-lists.t │ │ ├── 12-unordered-lists.t │ │ ├── 13-numbered-lists.t │ │ ├── 14-definition-lists.t │ │ ├── 05-headings.t │ │ ├── 08-formatting-and-links.t │ │ ├── 07-italic-and-bold.t │ │ └── 06-links.t ├── config.t ├── utils │ ├── r_remove.t │ └── get_period.t ├── cgi │ ├── cgi_post_test │ ├── 03-urlencoded.t │ ├── 02-cgi_post.t.sh │ └── 01-cgi.t ├── dispatcher │ ├── 02-add_rules.t │ ├── 05-junctions.t │ ├── 06-set-param.t │ ├── 03-whatever.t │ ├── 04-regex.t │ └── 01-basics.t ├── integration │ └── 01-view_page.t └── uri │ └── 01.t ├── p5w ├── data │ ├── page_tags │ │ └── Main_Page │ ├── tags_count │ ├── articles │ │ ├── Main_Page │ │ ├── Another_Page │ │ └── Not_Yet_Created_Page │ ├── modifications │ │ ├── 1215026435 │ │ ├── 1215026471 │ │ ├── 1218056287 │ │ ├── 1218056698 │ │ ├── 1218056837 │ │ ├── 1218057191 │ │ ├── 1218057231 │ │ ├── 1218057283 │ │ ├── 1218057386 │ │ ├── 1218057494 │ │ ├── 1218088792 │ │ ├── 1218088859 │ │ ├── 1218370550 │ │ └── 1219443872 │ ├── users │ └── recent-changes ├── skins │ ├── CleanAndSoft │ │ ├── .DS_Store │ │ ├── header.png │ │ ├── sunset1.jpg │ │ ├── sunset2.jpg │ │ ├── grey_stripes.png │ │ ├── november_logo.png │ │ ├── toolbar.tmpl │ │ ├── login_succeeded.tmpl │ │ ├── login_failed.tmpl │ │ ├── logout_succeeded.tmpl │ │ ├── unknown_action.tmpl │ │ ├── action_not_authorized.tmpl │ │ ├── page_too_old.tmpl │ │ ├── not_found.tmpl │ │ ├── recent_changes.tmpl │ │ ├── view_diff.tmpl │ │ ├── view.tmpl │ │ ├── page_history.tmpl │ │ ├── log_in.tmpl │ │ ├── edit.tmpl │ │ └── november_logo.svg │ ├── LoneMountain │ │ ├── bullet.png │ │ ├── footer.png │ │ ├── header.png │ │ ├── background.gif │ │ ├── background.png │ │ ├── horizontal_rule.png │ │ ├── login_succeeded.tmpl │ │ ├── login_failed.tmpl │ │ ├── logout_succeeded.tmpl │ │ ├── unknown_action.tmpl │ │ ├── not_found.tmpl │ │ ├── action_not_authorized.tmpl │ │ ├── toolbar.tmpl │ │ ├── recent_changes.tmpl │ │ ├── log_in.tmpl │ │ ├── page_history.tmpl │ │ ├── view_diff.tmpl │ │ ├── edit.tmpl │ │ └── view.tmpl │ └── DeleteMe │ │ ├── login_succeeded.tmpl │ │ ├── login_failed.tmpl │ │ ├── logout_succeeded.tmpl │ │ ├── unknown_action.tmpl │ │ ├── not_found.tmpl │ │ ├── action_not_authorized.tmpl │ │ ├── toolbar.tmpl │ │ ├── recent_changes.tmpl │ │ ├── view.tmpl │ │ ├── log_in.tmpl │ │ ├── page_history.tmpl │ │ ├── view_diff.tmpl │ │ ├── edit.tmpl │ │ └── spartan.css ├── wiki └── t │ ├── tags_parser.t │ └── tag_count_normalize.t ├── .gitignore ├── talks ├── NPW-2009.pdf ├── YAPC-EU-2008.pdf └── ru │ └── Bittersweet │ ├── c1.png │ ├── n1.png │ └── README ├── logotype └── logo-base.png ├── skins ├── Autumn │ ├── images │ │ └── tag.png │ ├── november-logo.png │ ├── november-tile.png │ ├── _head.tmpl │ ├── tags │ │ ├── page.tmpl │ │ └── all_rblock.tmpl │ ├── nav │ │ └── top.tmpl │ ├── login_succeeded.tmpl │ ├── logout_succeeded.tmpl │ ├── login_failed.tmpl │ ├── action_not_authorized.tmpl │ ├── recent_changes.tmpl │ ├── not_found.tmpl │ ├── log_in.tmpl │ ├── edit.tmpl │ ├── view.tmpl │ ├── list_all_pages.tmpl │ └── spartan.css └── CleanAndSoft │ ├── .DS_Store │ ├── header.png │ ├── sunset1.jpg │ ├── sunset2.jpg │ ├── grey_stripes.png │ ├── november_logo.png │ ├── page_tags.tmpl │ ├── header.tmpl │ ├── toolbar.tmpl │ ├── login_succeeded.tmpl │ ├── register_succeeded.tmpl │ ├── logout_succeeded.tmpl │ ├── login_failed.tmpl │ ├── unknown_action.tmpl │ ├── register_failed.tmpl │ ├── action_not_authorized.tmpl │ ├── not_found.tmpl │ ├── error.tmpl │ ├── view.tmpl │ ├── recent_changes.tmpl │ ├── sidebar.tmpl │ ├── page_history.tmpl │ ├── log_in.tmpl │ ├── register.tmpl │ ├── view_diff.tmpl │ ├── list_all_pages.tmpl │ ├── edit.tmpl │ └── november_logo.svg ├── wiki.sh.in ├── .travis.yml ├── test_wiki.sh.in ├── lib ├── Test │ ├── CGI.pm │ └── InputOutput.pm ├── November │ ├── Config.pm │ ├── Cache.pm │ ├── URI │ │ └── Grammar.pm │ ├── Session.pm │ ├── Utils.pm │ ├── Storage.pm │ ├── Storage │ │ └── File.pm │ └── URI.pm ├── Text │ └── Markup │ │ └── Wiki │ │ ├── Minimal │ │ └── Grammar.pm │ │ └── Minimal.pm ├── Dispatcher.pm └── Dispatcher │ └── Rule.pm ├── wiki ├── bin └── generate-password.pl ├── docs ├── LOOKINTO ├── JANITORS ├── blog-posts.md └── FEATURES ├── Makefile ├── AUTHORS └── META6.json /data/cache/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/sessions: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /deps.proto: -------------------------------------------------------------------------------- 1 | html-template 2 | -------------------------------------------------------------------------------- /data/articles/FAQ: -------------------------------------------------------------------------------- 1 | ["16571"] 2 | -------------------------------------------------------------------------------- /data/page_tags/FAQ: -------------------------------------------------------------------------------- 1 | faq, stub 2 | -------------------------------------------------------------------------------- /t/tags/data/tags_count: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /t/tags/data/tags_index: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /data/articles/About: -------------------------------------------------------------------------------- 1 | ["164992"] 2 | -------------------------------------------------------------------------------- /t/tags/data/page_tags/Test_Page: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /t/storage/data/modifications/empty-file: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /t/tags/data/page_tags/Another_Page: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data/index: -------------------------------------------------------------------------------- 1 | ["Main_Page", "About", "FAQ"] 2 | -------------------------------------------------------------------------------- /data/page_tags/About: -------------------------------------------------------------------------------- 1 | github, source, perl 6, rakudo 2 | -------------------------------------------------------------------------------- /p5w/data/page_tags/Main_Page: -------------------------------------------------------------------------------- 1 | Perl 6, Wiki, November, Fun! -------------------------------------------------------------------------------- /data/page_tags/Main_Page: -------------------------------------------------------------------------------- 1 | wiki, november, perl 6, rakudo, fun! 2 | -------------------------------------------------------------------------------- /data/articles/Main_Page: -------------------------------------------------------------------------------- 1 | ["0", "404869.874449968338", "634664.2746"] 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pir 2 | test_wiki.sh 3 | wiki.sh 4 | index_data 5 | data/cache/* 6 | -------------------------------------------------------------------------------- /data/recent-changes: -------------------------------------------------------------------------------- 1 | ["16571", "164992", "0", "404869.874449968338", "634664.2746"] 2 | -------------------------------------------------------------------------------- /talks/NPW-2009.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/talks/NPW-2009.pdf -------------------------------------------------------------------------------- /logotype/logo-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/logotype/logo-base.png -------------------------------------------------------------------------------- /talks/YAPC-EU-2008.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/talks/YAPC-EU-2008.pdf -------------------------------------------------------------------------------- /skins/Autumn/images/tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/skins/Autumn/images/tag.png -------------------------------------------------------------------------------- /skins/CleanAndSoft/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/skins/CleanAndSoft/.DS_Store -------------------------------------------------------------------------------- /talks/ru/Bittersweet/c1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/talks/ru/Bittersweet/c1.png -------------------------------------------------------------------------------- /talks/ru/Bittersweet/n1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/talks/ru/Bittersweet/n1.png -------------------------------------------------------------------------------- /p5w/data/tags_count: -------------------------------------------------------------------------------- 1 | { 2 | 'fun!' => 2, 3 | 'wiki' => 1, 4 | 'perl 6' => 3, 5 | 'november' => 2 6 | } 7 | -------------------------------------------------------------------------------- /skins/Autumn/november-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/skins/Autumn/november-logo.png -------------------------------------------------------------------------------- /skins/Autumn/november-tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/skins/Autumn/november-tile.png -------------------------------------------------------------------------------- /skins/CleanAndSoft/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/skins/CleanAndSoft/header.png -------------------------------------------------------------------------------- /skins/CleanAndSoft/sunset1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/skins/CleanAndSoft/sunset1.jpg -------------------------------------------------------------------------------- /skins/CleanAndSoft/sunset2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/skins/CleanAndSoft/sunset2.jpg -------------------------------------------------------------------------------- /p5w/data/articles/Main_Page: -------------------------------------------------------------------------------- 1 | [ 2 | 1219443872, 3 | '1218088859', 4 | '1218057283', 5 | '1218057231' 6 | ] 7 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/CleanAndSoft/.DS_Store -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/CleanAndSoft/header.png -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/bullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/LoneMountain/bullet.png -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/LoneMountain/footer.png -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/LoneMountain/header.png -------------------------------------------------------------------------------- /p5w/data/articles/Another_Page: -------------------------------------------------------------------------------- 1 | [ 2 | '1218057494', 3 | '1218057386', 4 | '1218056287', 5 | '1215026471' 6 | ] 7 | -------------------------------------------------------------------------------- /p5w/data/modifications/1215026435: -------------------------------------------------------------------------------- 1 | [ 2 | 'Not_Yet_Created_Page', 3 | 'Aaarhg! I created it! :)', 4 | 'johan' 5 | ] 6 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/sunset1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/CleanAndSoft/sunset1.jpg -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/sunset2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/CleanAndSoft/sunset2.jpg -------------------------------------------------------------------------------- /skins/CleanAndSoft/grey_stripes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/skins/CleanAndSoft/grey_stripes.png -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/LoneMountain/background.gif -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/LoneMountain/background.png -------------------------------------------------------------------------------- /skins/CleanAndSoft/november_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/skins/CleanAndSoft/november_logo.png -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/grey_stripes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/CleanAndSoft/grey_stripes.png -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/november_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/CleanAndSoft/november_logo.png -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/horizontal_rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viklund/november/HEAD/p5w/skins/LoneMountain/horizontal_rule.png -------------------------------------------------------------------------------- /p5w/wiki: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | use strict; 3 | 4 | use November; 5 | 6 | # start the server on port 8080 7 | November->new(8080)->run(); 8 | -------------------------------------------------------------------------------- /wiki.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PARROT_DIR= 4 | RAKUDO_DIR= 5 | exec $PARROT_DIR/parrot $RAKUDO_DIR/perl6.pbc wiki 6 | -------------------------------------------------------------------------------- /data/tags_count: -------------------------------------------------------------------------------- 1 | {"wiki" => "1", "perl 6" => 2, "november" => 1, "rakudo" => 2, "fun!" => 1, "github" => 1, "source" => 1, "faq" => 1, "stub" => 1} 2 | -------------------------------------------------------------------------------- /p5w/data/articles/Not_Yet_Created_Page: -------------------------------------------------------------------------------- 1 | [ 2 | '1218088792', 3 | '1218057191', 4 | '1218056837', 5 | '1218056698', 6 | '1215026435' 7 | ] 8 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218056698: -------------------------------------------------------------------------------- 1 | [ 2 | 'Not_Yet_Created_Page', 3 | 'Aaarhg! I created it! :) 4 | 5 | That\'s ok, there are other not yet created pages...' 6 | ] 7 | -------------------------------------------------------------------------------- /p5w/data/modifications/1215026471: -------------------------------------------------------------------------------- 1 | [ 2 | 'Another_Page', 3 | 'Time to clean up a bit here. 4 | 5 | Hm, let\'s actually keep the link to [[Main_Page]]. It\'s handy.' 6 | ] 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | branches: 2 | except: 3 | - gh-pages 4 | language: perl6 5 | sudo: false 6 | perl6: 7 | - latest 8 | install: 9 | - rakudobrew build-panda 10 | - panda installdeps . 11 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218056287: -------------------------------------------------------------------------------- 1 | [ 2 | 'Another_Page', 3 | 'Time to clean up a bit here. 4 | 5 | Hm, let\'s actually keep the link to [[Main_Page]]. It\'s a yellow toy duck. Bzaaah!' 6 | ] 7 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218057386: -------------------------------------------------------------------------------- 1 | [ 2 | 'Another_Page', 3 | 'Time to crank it up a bit here. 4 | 5 | Hm, let\'s actually keep the link to [[Main_Page]]. It\'s a yellow toy duck. Bzaaah!' 6 | ] 7 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218056837: -------------------------------------------------------------------------------- 1 | [ 2 | 'Not_Yet_Created_Page', 3 | 'Aaarhg! I created it! :) 4 | 5 | That\'s ok, there are other not yet created pages... Though maybe none as beutiful as this was... wasn\'t...' 6 | ] 7 | -------------------------------------------------------------------------------- /data/tags_index: -------------------------------------------------------------------------------- 1 | {"rakudo" => ["Main_Page", "About"], "wiki" => ["Main_Page"], "november" => ["Main_Page"], "perl 6" => ["Main_Page", "About"], "fun!" => ["Main_Page"], "github" => ["About"], "source" => ["About"], "faq" => ["FAQ"], "stub" => ["FAQ"]} 2 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218088792: -------------------------------------------------------------------------------- 1 | [ 2 | 'Not_Yet_Created_Page', 3 | 'Aaarhg! I created it! :) 4 | 5 | That\'s ok, there are other not yet created pages... 6 | 7 | Adding some more stuff, destroying the beautiful ideal of this page even more.' 8 | ] 9 | -------------------------------------------------------------------------------- /test_wiki.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | QS=$1 4 | PARROT_DIR= 5 | RAKUDO_DIR= 6 | env REQUEST_METHOD=GET \ 7 | SERVER_NAME='test.foo' \ 8 | SERVER_PORT='80' \ 9 | REQUEST_URI=$QS \ 10 | $PARROT_DIR/parrot $RAKUDO_DIR/perl6.pbc wiki 11 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218370550: -------------------------------------------------------------------------------- 1 | [ 2 | 'Another_Page', 3 | 'Time to crank it up a bit here. The word "crank" can mean many things, even at the same time. 4 | 5 | Hm, let\'s actually keep the link to [[Main_Page]]. It\'s a yellow toy duck.', 6 | 'carl' 7 | ] 8 | -------------------------------------------------------------------------------- /skins/Autumn/_head.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <TMPL_VAR NAME=TITLE> 5 | 6 | -------------------------------------------------------------------------------- /skins/Autumn/tags/page.tmpl: -------------------------------------------------------------------------------- 1 |
2 | 3 | ., 4 | 5 |
6 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/page_tags.tmpl: -------------------------------------------------------------------------------- 1 |
2 | 3 | ., 4 | 5 |
6 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218057494: -------------------------------------------------------------------------------- 1 | [ 2 | 'Another_Page', 3 | 'Time to crank it up a bit here. The word "crank" can mean many things, even at the same time. 4 | 5 | Hm, let\'s actually keep the link to [[Main_Page]]. It\'s a yellow toy duck. Bzaaah!', 6 | 'carl' 7 | ] 8 | -------------------------------------------------------------------------------- /p5w/data/users: -------------------------------------------------------------------------------- 1 | { 2 | 'johan' => { 3 | 'password' => 'hdm24HFlfrBgIX3bTsVLIQ' 4 | }, 5 | 'carl' => { 6 | 'password' => '3l9drfMnROgPQTNicdGFQg' 7 | }, 8 | 'ihrd' => { 9 | 'password' => 'yG7xslKNZt59hpwVBkWrFQ', 10 | 'plain_text' => 'gfhjkm' 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /t/markup/minimal/01-use.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 1; 5 | 6 | my $used_successfully = False; 7 | try { 8 | use Text::Markup::Wiki::Minimal; 9 | $used_successfully = True; 10 | } 11 | 12 | ok( $used_successfully, "use Text::Markup::Wiki::Minimal" ); 13 | 14 | # vim:ft=perl6 15 | -------------------------------------------------------------------------------- /skins/Autumn/tags/all_rblock.tmpl: -------------------------------------------------------------------------------- 1 |
2 |

All tags

3 | 4 | 5 | 6 |
7 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218057191: -------------------------------------------------------------------------------- 1 | [ 2 | 'Not_Yet_Created_Page', 3 | 'Aaarhg! I created it! :) 4 | 5 | That\'s ok, there are other not yet created pages... Though maybe none as beutiful as this was... wasn\'t... 6 | 7 | Adding some more stuff, destroying the beautiful ideal of this page even more.' 8 | ] 9 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218057231: -------------------------------------------------------------------------------- 1 | [ 2 | 'Main_Page', 3 | 'This is the glorious contents of Main. (Note how HTML tags are escaped.) 4 | 5 | I now \'magically\' link to [[Another_Page]]. Kazam! 6 | 7 | Let me just try to create a [[Not_Yet_Created_Page]] and see what happens. 8 | ' 9 | ] 10 | -------------------------------------------------------------------------------- /t/markup/mediawiki/01-use.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 1; 5 | 6 | my $used_successfully = False; 7 | try { 8 | use Text::Markup::Wiki::MediaWiki; 9 | $used_successfully = True; 10 | } 11 | 12 | ok( $used_successfully, "Text::Markup::Wiki::MediaWiki can be use:d" ); 13 | 14 | # vim:ft=perl6 15 | -------------------------------------------------------------------------------- /t/config.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 3; 5 | 6 | use November::Config; 7 | 8 | my $c = November::Config.new; 9 | 10 | ok($c.skin, 'find skin in Config'); 11 | ok(defined($c.web_root), 'find web_root in Config'); 12 | ok(defined($c.server_root), 'find server_root in Config'); 13 | 14 | # vim:ft=perl6 15 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218057283: -------------------------------------------------------------------------------- 1 | [ 2 | 'Main_Page', 3 | 'This is the glorious contents of Main. (Note how HTML tags are escaped.) 4 | 5 | I now \'magically\' link to [[Another_Page]]. Kazam! 6 | 7 | Let me just try to create a [[Not_Yet_Created_Page]] and see what happens. 8 | 9 | Hah!' 10 | ] 11 | -------------------------------------------------------------------------------- /p5w/data/modifications/1218088859: -------------------------------------------------------------------------------- 1 | [ 2 | 'Main_Page', 3 | 'This is the glorious contents of Main. (Note how HTML tags are escaped.) 4 | 5 | I now \'magically\' link to [[Another_Page]]. Kazam! 6 | 7 | Let me just try to create a [[Not_Yet_Created_Page]] and... see what happens.', 8 | 'carl' 9 | ] 10 | -------------------------------------------------------------------------------- /talks/ru/Bittersweet/README: -------------------------------------------------------------------------------- 1 | [en] 2 | This is a Takahashi presentation. 3 | Using Firefox, surf to the takahashi.xul file with ?data=bn.taka 4 | 5 | There's a video, too: 6 | 7 | [ru] 8 | Это такахаши презентация. 9 | Нужно натравить Огнелиса на takahashi.xul с ?data=bn.taka 10 | 11 | -------------------------------------------------------------------------------- /data/users: -------------------------------------------------------------------------------- 1 | # Password generation is a manual process right now; run bin/generate-password.pl USER PASS 2 | # The plain_text value isn't used anywhere, it's just handy for human reference 3 | { 4 | 'someone' => { 5 | 'password' => '47c96e61cbcb31e648b1987107117ca4f524658460b955e290675789466fcd1a', 6 | 'plain_text' => 'howdy' 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /t/utils/r_remove.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | use Test; 3 | plan 2; 4 | 5 | use November::Utils; 6 | 7 | my $str = 'ar r \ r'; 8 | r_remove($str); 9 | is($str, 'ar r \ r', 'r_remove do nothing with string without \r' ); 10 | 11 | $str = 'foo\r\nbar\r\n'; 12 | r_remove($str); 13 | is($str, 'foo\nbar\n', 'r_remove remove \r' ); 14 | 15 | # vim:ft=perl6 16 | -------------------------------------------------------------------------------- /t/cgi/cgi_post_test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl6 2 | use Test; 3 | 4 | use CGI; 5 | my $cgi = CGI.new(); 6 | $cgi.init(); 7 | 8 | print _is-deeply( $cgi.params, eval( %*ENV ) ) 9 | ?? "ok " 10 | !! "not ok \n" ~ "got: " ~ $cgi.param.perl ~ 11 | "\nexpected: " ~ %*ENV ~ "\n"; 12 | 13 | say "- " ~ %*ENV; 14 | -------------------------------------------------------------------------------- /lib/Test/CGI.pm: -------------------------------------------------------------------------------- 1 | use v6; 2 | use November::CGI; 3 | 4 | class Test::CGI is November::CGI { 5 | 6 | has $.response is rw; 7 | has %.response_opts is rw; 8 | 9 | method send_response($contents, %opts?) { 10 | $.response = $contents; 11 | if %opts { 12 | %.response_opts = %opts; 13 | } 14 | } 15 | 16 | } 17 | 18 | # vim:ft=perl6 19 | -------------------------------------------------------------------------------- /t/markup/mediawiki/27-entities.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 1; 5 | 6 | use Text::Markup::Wiki::MediaWiki; 7 | 8 | my $converter = Text::Markup::Wiki::MediaWiki.new; 9 | 10 | my $input = '—'; 11 | my $expected_output = '

'; 12 | my $actual_output = $converter.format($input); 13 | 14 | is( $actual_output, $expected_output, '— is handled' ); 15 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/header.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /skins/Autumn/nav/top.tmpl: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /wiki: -------------------------------------------------------------------------------- 1 | #!perl6 2 | use v6; 3 | 4 | use November; 5 | use November::CGI; 6 | use November::Config; 7 | use Text::Markup::Wiki::MediaWiki; 8 | 9 | my $c = November::Config.new( 10 | markup => Text::Markup::Wiki::MediaWiki.new(), 11 | skin => 'CleanAndSoft' 12 | ); 13 | my November $wiki = November.new( 14 | config => $c, 15 | ); 16 | my $cgi = November::CGI.new; 17 | $wiki.handle_request($cgi); 18 | -------------------------------------------------------------------------------- /t/markup/minimal/02-normal-text.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 1; 5 | 6 | use Text::Markup::Wiki::Minimal; 7 | my $converter = Text::Markup::Wiki::Minimal.new; 8 | 9 | my $input = 'normal text'; 10 | my $expected_output = '

normal text

'; 11 | my $actual_output = $converter.format($input); 12 | 13 | is( $actual_output, $expected_output, 'normal text goes through unchanged' ); 14 | 15 | # vim:ft=perl6 16 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/toolbar.tmpl: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /t/markup/mediawiki/02-normal-text.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 1; 5 | 6 | use Text::Markup::Wiki::MediaWiki; 7 | 8 | my $converter = Text::Markup::Wiki::MediaWiki.new; 9 | 10 | my $input = 'normal text'; 11 | my $expected_output = '

normal text

'; 12 | my $actual_output = $converter.format($input); 13 | 14 | is( $actual_output, $expected_output, 'normal text goes through unchanged' ); 15 | 16 | # vim:ft=perl6 17 | -------------------------------------------------------------------------------- /p5w/data/recent-changes: -------------------------------------------------------------------------------- 1 | [ 2 | 1222172067, 3 | 1222171596, 4 | 1222171556, 5 | 1222171521, 6 | 1222170836, 7 | 1221039758, 8 | 1221039474, 9 | 1221039457, 10 | 1219443872, 11 | 1218370550, 12 | 1218088859, 13 | 1218088792, 14 | 1218057494, 15 | 1218057386, 16 | 1218057283, 17 | 1218057231, 18 | 1218057191, 19 | 1218056837, 20 | 1218056698, 21 | 1218056287, 22 | 1215026471, 23 | 1215026435 24 | ] 25 | -------------------------------------------------------------------------------- /t/markup/mediawiki/16-pre.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | my @tests = 4 | [ 5 | " foo" => 6 | "
foo
", 7 | 'pre text' 8 | ], 9 | ; 10 | 11 | # RAKUDO: Doesn't respect "use Test :EXPORT" 12 | use Test; 13 | use Test::InputOutput; 14 | plan +@tests; 15 | todo 'Implement pre text'; 16 | 17 | use Text::Markup::Wiki::MediaWiki; 18 | 19 | my $converter = Text::Markup::Wiki::MediaWiki.new; 20 | Test::InputOutput.using( { $converter.format($^input) } ).test(@tests); 21 | 22 | # vim:ft=perl6 23 | -------------------------------------------------------------------------------- /data/modifications/634664.2746: -------------------------------------------------------------------------------- 1 | [ 2 | 'Main_Page', 3 | 'Hi there. November is a wiki engine written in Perl 6, and runs on top of Rakudo. It currently does viewing/editing of pages, and sessions. 4 | 5 | Pages are written in a simple wiki markup, and parsed using a Perl 6 grammar. This grammar is used to produce links, for example to [[Another_Page]]. A link to a [[Page_that_does_not_exist]] is shown in red, and clicking it takes you into edit mode for that page.', 6 | 'carl', 7 | 1227000000 8 | ] 9 | -------------------------------------------------------------------------------- /data/modifications/164992: -------------------------------------------------------------------------------- 1 | ["About", "This wiki is a test bed application for Perl 6 web development libraries, and Perl 6 implementations.\n\nSee [http://github.com/viklund/november/] for the sources. Contributions are welcome—come find us on irc.freenode.net at #perl6!\n\n\nIf you want to log in and play around with editing files, there is a hard-coded users database in the sources. Look at the file data/users in the november repo. User registration coming soon*!", "someone", "Add a simple About page", 1310164991] 2 | -------------------------------------------------------------------------------- /t/markup/mediawiki/03-escaping.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | use Test::InputOutput; 5 | 6 | use Text::Markup::Wiki::MediaWiki; 7 | 8 | my @tests = 9 | [ '<' => '

<

', '<' ], 10 | [ '>' => '

>

', '>' ], 11 | [ '&' => '

&

', '&' ], 12 | [ '\'' => '

'

', ''' ]; 13 | 14 | plan +@tests; 15 | 16 | my $converter = Text::Markup::Wiki::MediaWiki.new; 17 | Test::InputOutput.using( { $converter.format($^input) } ).test(@tests); 18 | 19 | # vim:ft=perl6 20 | -------------------------------------------------------------------------------- /skins/Autumn/login_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
    7 |   8 |
9 |
10 |

Login successful

11 |

You got in!

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /skins/Autumn/logout_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
    7 |   8 |
9 |
10 |

Logout successful

11 |

You got out!

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /bin/generate-password.pl: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Digest; 4 | 5 | if ( @*ARGS.elems != 2 ) { 6 | say 'This program expects two arguments, the first one should be the'; 7 | say 'username of the new user and the second one should be the passphrase'; 8 | say 'of the new user.'; 9 | say "\nThank You"; 10 | exit 1; 11 | } 12 | 13 | my ($username, $passphrase) = @*ARGS; 14 | 15 | say "The hashed passphrase for $username is:"; 16 | say " ", digest( digest( $username, 'sha256' ) ~ $passphrase, 'sha256'); 17 | 18 | # vim: ft=perl6 19 | -------------------------------------------------------------------------------- /skins/Autumn/login_failed.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
    7 |   8 |
9 |
10 |

Login failed

11 |

Something went wrong. Sorry.

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /t/markup/minimal/04-paragraphs.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 1; 5 | 6 | use Text::Markup::Wiki::Minimal; 7 | 8 | my $converter = Text::Markup::Wiki::Minimal.new; 9 | 10 | my @pars = 11 | "par 1", 12 | "par 2\nwith\nnewlines in it", 13 | "par 3"; 14 | my $input = join "\n\n", @pars; 15 | my $expected_output = join "\n\n", map { "

{$_}

" }, @pars; 16 | my $actual_output = $converter.format($input); 17 | 18 | is( $actual_output, $expected_output, 19 | 'paragraphs are turned into separate

blocks' ); 20 | 21 | # vim:ft=perl6 22 | -------------------------------------------------------------------------------- /lib/November/Config.pm: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Text::Markup::Wiki::MediaWiki; 4 | 5 | class November::Config { 6 | has $.server_root = ''; 7 | has $.web_root = ''; 8 | has $.skin = 'CleanAndSoft'; 9 | has $.markup = Text::Markup::Wiki::MediaWiki.new; 10 | 11 | method template_path { 12 | my $str = $!server_root ~ 'skins/' ~ $!skin ~ '/'; 13 | return $str; 14 | } 15 | 16 | method userfile_path { 17 | my $str = $!server_root ~ 'data/users'; 18 | return $str; 19 | } 20 | } 21 | 22 | # vim:ft=perl6 23 | -------------------------------------------------------------------------------- /t/markup/mediawiki/99-fail.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 1; 5 | 6 | use Text::Markup::Wiki::MediaWiki; 7 | 8 | my $converter = Text::Markup::Wiki::MediaWiki.new; 9 | 10 | # Issue #16: The MediaWiki parser crashes if it gets fed a page with at least 11 | # one trailing new-line (possibly followed by spaces). 12 | 13 | my $input = "Foo\n"; 14 | my $succeeded = False; 15 | try { 16 | my $actual_output = $converter.format($input); 17 | $succeeded = True; 18 | } 19 | 20 | ok( $succeeded, q[the parser doesn't crash on a final newline] ); # ' 21 | 22 | # vim:ft=perl6 23 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/login_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Login successful 5 | 6 | 7 | 8 | 9 |

10 |

Login successful

11 |

You got in!

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/login_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Login successful 5 | 6 | 7 | 8 | 9 |
10 |

Login successful

11 |

You got in!

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/login_failed.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Login failed 5 | 6 | 7 | 8 | 9 |
10 |

Login failed

11 |

Something went wrong. Sorry.

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/logout_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logout successful 5 | 6 | 7 | 8 | 9 |
10 |

Logout successful

11 |

You got out!

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/login_failed.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Login failed 5 | 6 | 7 | 8 | 9 |
10 |

Login failed

11 |

Something went wrong. Sorry.

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/logout_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logout successful 5 | 6 | 7 | 8 | 9 |
10 |

Logout successful

11 |

You got out!

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/unknown_action.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Unknown action 5 | 6 | 7 | 8 | 9 |
10 |

Unknown action

11 | Unknown action "". 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/unknown_action.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Unknown action 5 | 6 | 7 | 8 | 9 |
10 |

Unknown action

11 | Unknown action "". 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /t/markup/minimal/03-escaping.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 4; 5 | 6 | use Text::Markup::Wiki::Minimal; 7 | 8 | my %h = 9 | '<' => 'lt', 10 | '>' => 'gt', 11 | '&' => 'amp', 12 | '\'' => '#039'; 13 | 14 | my $converter = Text::Markup::Wiki::Minimal.new; 15 | 16 | for %h.kv -> $input, $abbr { 17 | my $expected_escape = '&' ~ $abbr ~ ';'; 18 | my $expected_output = "

{$expected_escape}

"; 19 | my $actual_output = $converter.format($input); 20 | 21 | is( $actual_output, $expected_output, "$input -> $expected_escape" ); 22 | } 23 | 24 | # vim:ft=perl6 25 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/not_found.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Page not found 5 | 6 | 7 | 8 | 9 |
10 |

Page not found

11 | The page '' was not found. 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/not_found.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Page not found 5 | 6 | 7 | 8 | 9 |
10 |

Page not found

11 | The page '' was not found. 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/action_not_authorized.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Not logged in 5 | 6 | 7 | 8 | 9 |
10 |

Not logged in

11 |

You need to be logged in to .

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/action_not_authorized.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Not logged in 5 | 6 | 7 | 8 | 9 |
10 |

Not logged in

11 |

You need to be logged in to .

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /t/markup/mediawiki/04-paragraphs.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 1; 5 | 6 | use Text::Markup::Wiki::MediaWiki; 7 | 8 | my $converter = Text::Markup::Wiki::MediaWiki.new; 9 | 10 | my @pars = 11 | "par 1", 12 | "par 2\nwith\nnewlines in it", 13 | "par 3"; 14 | my $input = join "\n\n", @pars; 15 | my $expected_output = join "\n\n", map { "

{$_}

" }, 16 | "par 1", "par 2 with newlines in it", "par 3"; 17 | my $actual_output = $converter.format($input); 18 | 19 | is( $actual_output, $expected_output, 20 | 'paragraphs are turned into separate

blocks' ); 21 | 22 | # vim:ft=perl6 23 | -------------------------------------------------------------------------------- /t/dispatcher/02-add_rules.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 5; 5 | 6 | use Dispatcher; 7 | 8 | my $d = Dispatcher.new; 9 | 10 | my @rules = 11 | ['foo'], { "A" }, 12 | [/\d+/], { "B" }, 13 | ['foo', 'bar'], { "C" }, 14 | ['her'|'boo'], { "D" }; 15 | 16 | is($d.add(@rules), 4, "add list of rules, get the number added back"); 17 | 18 | is($d.dispatch(['foo']), "A", "Dispatch rule ['foo']"); 19 | is($d.dispatch(['123']), "B", "Dispatch rule /\\d+/"); 20 | is($d.dispatch(['foo', 'bar']), "C", "Dispatch ['foo', 'bar']"); 21 | is($d.dispatch(['boo']), "D", "Dispatch ['boo']"); 22 | 23 | # vim:ft=perl6 24 | -------------------------------------------------------------------------------- /docs/LOOKINTO: -------------------------------------------------------------------------------- 1 | Things to investigate further with p6w: 2 | 3 | * Using {*} for call actions from grammar (trying in asterisk branch). 4 | 5 | * Using Parrot NCI to wrap SQLite. 6 | () 7 | 8 | * Using svk as a storage backend. 9 | 10 | * Packaging for CPAN. 11 | 12 | * Markups. 13 | ** MediaWiki 14 | ** Creole (file://feather/home/juerd/creole) 15 | ** Textile 16 | ** Markdown (http://blog.stackoverflow.com/2008/06/three-markdown-gotcha/) 17 | ** POD 18 | ** kwid 19 | ** Socialtext 20 | ** PhpWiki 21 | ** UseModWiki 22 | 23 | * Mirroring of the pugs and parrot svn repositories. 24 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/login_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Login successful 3 | 4 | 5 |

6 |
7 | 8 |
9 |
 
10 |
11 |

Login successful

12 |

You got in!

13 |
14 | 15 | 16 | 17 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /t/markup/mediawiki/09-line-breaks.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 2; 5 | todo('not yet implemented', 2); 6 | 7 | use Text::Markup::Wiki::MediaWiki; 8 | 9 | my $converter = Text::Markup::Wiki::MediaWiki.new; 10 | 11 | my $input = 'a
b
c'; 12 | my $expected_output = '

a
b
c

'; 13 | my $actual_output = $converter.format($input); 14 | 15 | is( $actual_output, $expected_output, '
line breaks work' ); 16 | 17 | # RAKUDO: $input ~~ s{
}{
}; 18 | $input.=trans( [ '
' ] => [ '
' ] ); 19 | $actual_output = $converter.format($input); 20 | 21 | is( $actual_output, $expected_output, '
line breaks work' ); 22 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/register_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Registration successful 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Registration successful

12 |

You have an account!

13 |
14 | 15 | 16 | 17 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /t/markup/minimal/05-headings.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 1; 5 | 6 | use Text::Markup::Wiki::Minimal; 7 | 8 | my $converter = Text::Markup::Wiki::Minimal.new; 9 | 10 | my @pars = 11 | "==heading 1==", 12 | "par 1", 13 | "== heading 2 ==", 14 | "== heading 3 ==", 15 | "par 2"; 16 | my $input = join "\n\n", @pars; 17 | my $expected_output = join "\n\n", 18 | '

heading 1

', 19 | '

par 1

', 20 | '

heading 2

', 21 | '

heading 3

', 22 | '

par 2

'; 23 | my $actual_output = $converter.format($input); 24 | 25 | is( $actual_output, $expected_output, 'mixing paragraphs and headings works' ); 26 | 27 | # vim:ft=perl6 28 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/logout_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Logout successful 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Logout successful

12 |

You got out!

13 |
14 | 15 | 16 | 17 | 22 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /skins/Autumn/action_not_authorized.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Not logged in 5 | 6 | 7 | 8 | 9 |
    10 |   11 |
12 |
13 |

Not logged in

14 |

You need to be logged in to .

15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/login_failed.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Login failed 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Login failed

12 |

Something went wrong. Sorry.

13 |
14 | 15 | 16 | 17 | 22 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /t/dispatcher/05-junctions.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 4; 5 | 6 | use Dispatcher; 7 | my $d = Dispatcher.new; 8 | 9 | $d.add: [ 10 | ['foo'|'bar'], { 'First' }, 11 | ['foo', 'a'|'b'], { 'Second' }, 12 | ]; 13 | 14 | is( $d.dispatch(['foo']), 15 | 'First', 16 | 'Pattern with Junction (foo|bar) foo' 17 | ); 18 | 19 | is( $d.dispatch(['bar']), 20 | 'First', 21 | 'Pattern with Junction (foo|bar) bar' 22 | ); 23 | 24 | is( $d.dispatch(['foo', 'a']), 25 | 'Second', 26 | 'Pattern with Junction (foo/a|b) a' 27 | ); 28 | 29 | is( $d.dispatch(['foo', 'b']), 30 | 'Second', 31 | 'Pattern with Junction (foo/a|b) b' 32 | ); 33 | 34 | # vim:ft=perl6 35 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/unknown_action.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Unknown action 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Unknown action

12 | Unknown action "". 13 |
14 | 15 | 16 | 17 | 22 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/register_failed.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Registration failed 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Registration failed

12 |

Something went wrong. Sorry.

13 |
14 | 15 | 16 | 17 | 22 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /p5w/t/tags_parser.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 8; 2 | use November; 3 | 4 | my $tf = \&November::tags_parse; 5 | 6 | my @to_parse = ( 7 | [ 'foo', 8 | ['foo'] ], 9 | [ 'foo,bar', 10 | ['foo', 'bar'] ], 11 | [ 'foo, bar', 12 | ['foo', 'bar'] ], 13 | [ 'foo, bar ,her', 14 | ['foo', 'bar', 'her'] ], 15 | [ "foo\n", 16 | ['foo'] ], 17 | [ 'foo , bar , her', 18 | ['foo', 'bar', 'her'] ], 19 | [ 'Foo', 20 | ['foo'] ], 21 | [ 'foo, BAR', 22 | ['foo', 'bar'] ], 23 | ); 24 | 25 | for (@to_parse) { 26 | my ($in, $result) = @$_; 27 | my $comment = 'Parse tags: ' . $in; 28 | $comment =~ s/\n/\\n/; 29 | is-deeply( $tf->($in), $result, $comment ); 30 | } 31 | -------------------------------------------------------------------------------- /lib/November/Cache.pm: -------------------------------------------------------------------------------- 1 | unit role November::Cache; 2 | 3 | use November::Config; 4 | 5 | method cache-dir { 6 | return $.config.server_root ~ 'data/cache'; 7 | } 8 | 9 | method set-cache-entry( $key, $value ) { 10 | my $file = self.cache-dir ~ '/' ~ $key; 11 | my $fh = open( $file, :w ); 12 | $fh.say( $value ); 13 | $fh.close; 14 | } 15 | 16 | method get-cache-entry( $key ) { 17 | my $file = self.cache-dir ~ '/' ~ $key; 18 | return Nil unless $file.IO ~~ :e; 19 | my $string = slurp( $file ); 20 | return $string; 21 | } 22 | 23 | method remove-cache-entry( $key ) { 24 | my $file = self.cache-dir ~ '/' ~ $key; 25 | return unless $file.IO ~~ :e; 26 | unlink( $file ); 27 | } 28 | 29 | # vim:ft=perl6 30 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/action_not_authorized.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Not logged in 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Not logged in

12 |

You need to be logged in to .

13 |
14 | 15 | 16 | 17 | 22 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /t/tags/norm.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 2; 5 | 6 | use November::Tags; 7 | 8 | my @counts_to_test = 9 | [ 2, 5, 6, 14 ], 10 | [ 0, 4, 5, 10 ], 11 | 12 | [ 5, 5, 2, 1 ], 13 | [ 10, 10, 4, 0 ] 14 | ; 15 | my $t = November::Tags.new; 16 | 17 | for @counts_to_test -> @in, @expected { 18 | my ($min, $max) = @in.minmax.bounds; 19 | 20 | # debugging 21 | # say $in.perl ~ " min:$min, max:$max"; 22 | 23 | # RAKUDO: min and max there save its values, and I cant reasign it :( 24 | # So, second map work with wrong min and max 25 | my @out = map { $t.norm($_, $min, $max) }, @in.values; 26 | 27 | is-deeply( @out, @expected, 'Normalize: ' ~ @in.perl ); 28 | } 29 | 30 | # vim:ft=perl6 31 | -------------------------------------------------------------------------------- /t/dispatcher/06-set-param.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 4; 5 | 6 | use Dispatcher; 7 | my $d = Dispatcher.new; 8 | 9 | $d.add: [ 10 | [:controller(*), :action(*) ], { 'c:' ~ $:controller ~ ' a:' ~ $:action }, 11 | [:controller(*), / \d / ], { $:controller ~ '/' ~ $^a }, 12 | [:controller(*), *, * ], { my $c = $:controller; is($^a, $^b, 'Test within Rule') }, 13 | ]; 14 | 15 | is( $d.dispatch(['one', 5]), 16 | 'one/5', 17 | 'Pattern set controller' 18 | ); 19 | 20 | is( $d.dispatch(['one', 'two']), 21 | 'c:one a:two', 22 | 'Pattern set controller and action' 23 | ); 24 | 25 | is( $d.dispatch(['Test', 3, 3]), 26 | Bool::True, 27 | 'Pattern set controller and action' 28 | ); 29 | 30 | # vim:ft=perl6 31 | -------------------------------------------------------------------------------- /t/dispatcher/03-whatever.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | use Test; 3 | plan 5; 4 | 5 | use Dispatcher; 6 | 7 | my $d = Dispatcher.new( default => { "default" } ); 8 | 9 | $d.add( 10 | [ 11 | [*,], { $^a }, 12 | [*,*], { $^a + $^b }, 13 | ['foo', *], { 'foo/' ~ $^a }, 14 | ['foo', *, *], { 'foo:' ~ $^a - $^b }, 15 | ['foo', *, 'bar'], { $^b }, 16 | ] 17 | ); 18 | 19 | is( $d.dispatch([42]), 42, 'Pattern *' ); 20 | is( $d.dispatch([1, 2]), 3, 'Pattern */* ' ); 21 | is( $d.dispatch(['foo', '5']), "foo/5", 'Pattern foo/*' ); 22 | is( $d.dispatch(['foo', '5', 1]), "foo:4", 'Pattern foo/*/*' ); 23 | is( $d.dispatch(['foo', 'baz', 'bar']), "baz", 'Pattern foo/*/bar' ); 24 | 25 | 26 | # vim:ft=perl6 27 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/not_found.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Page not found 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Page not found

12 |
13 | The page '' was not found. 14 |
15 |
16 | 17 | 18 | 19 | 24 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /lib/Text/Markup/Wiki/Minimal/Grammar.pm: -------------------------------------------------------------------------------- 1 | grammar Text::Markup::Wiki::Minimal::Grammar { 2 | 3 | token TOP { ^ [ || +] $ }; 4 | 5 | token heading { '==' + '==' }; 6 | 7 | token parchunk { || || || }; 8 | 9 | # RAKUDO: a token may not be called 'text' [perl #57864] 10 | token twext { [ <.alnum> || <.otherchar> || <.whitespace> ]+ }; 11 | 12 | token otherchar { <[ !..% (../ : ; ? @ \\ ^..` {..~ ]> }; 13 | 14 | token whitespace { ' ' | \n }; 15 | 16 | token wikimark { '[[' \s? [\s+ ]? \s? ']]' }; 17 | 18 | regex link { <[:/._@\-0..9]+alpha>+ }; 19 | regex link_title { <-[\]]>+ }; 20 | 21 | token metachar { '<' || '>' || '&' || \' }; 22 | 23 | token malformed { '[' || ']' } 24 | } 25 | -------------------------------------------------------------------------------- /skins/Autumn/recent_changes.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |

Recent changes

11 | 12 |
    13 | 14 |
  • 15 | was changed 16 | by 17 | 18 |
  • 19 |
    20 |
21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /skins/Autumn/not_found.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 14 |
15 |

Page not found

16 | The page was not found. 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/error.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Error 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Error

12 | 13 |

14 | 15 |

Something went wrong.

16 |
17 |
18 | 19 | 20 | 21 | 26 | 27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /t/utils/get_period.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | use Test; 3 | plan 9; 4 | 5 | use November::Utils; 6 | 7 | { 8 | my $t = get_period(1227315969, 1227316090); 9 | 10 | is($t[0], 0, 'Return 0 days when period < 24 hour' ); 11 | is($t[1], 0, 'Return 0 hour when period < hour' ); 12 | is($t[2], 2, 'Return 2 min when period 121 sec' ); 13 | } 14 | 15 | { 16 | my $t = get_period(1227315969, 1227321470); 17 | 18 | is($t[0], 0, 'Return 0 days when period < 24 hour' ); 19 | is($t[1], 1, 'Return 1 hour when period > 1 hour (5501)' ); 20 | is($t[2], 31, 'Return 3 min when period 5501 sec' ); 21 | } 22 | 23 | { 24 | my $t = get_period(1227315969, 1227514689); 25 | 26 | is($t[0], 2, 'Return number of days' ); 27 | is($t[1], 7, 'Return hours' ); 28 | is($t[2], 12, 'Return mins' ); 29 | } 30 | 31 | # vim:ft=perl6 32 | 33 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/toolbar.tmpl: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/toolbar.tmpl: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/toolbar.tmpl: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /skins/Autumn/log_in.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
    7 |   8 |
9 |
10 |

Log in

11 |

Once you are logged in, you can edit pages.

12 | 13 |
14 |

Username:

15 |

Password:

16 | 17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /t/tags/parser.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 11; 5 | 6 | use November::Tags; 7 | 8 | my @to_parse = ( 9 | 'foo', 10 | ['foo'], 11 | 'foo,bar', 12 | ['foo', 'bar'], 13 | 'foo, bar', 14 | ['foo', 'bar'], 15 | 'foo, bar ,her', 16 | ['foo', 'bar', 'her'], 17 | "foo\n", 18 | ['foo'], 19 | 'foo , bar , her', 20 | ['foo', 'bar', 'her'], 21 | 'Foo', 22 | ['foo'], 23 | 'foo, BAR', 24 | ['foo', 'bar'], 25 | 'foo, foo, bar, bar, bar', 26 | ['foo', 'bar'], 27 | 'foo, bar.', 28 | ['foo', 'bar'], 29 | 'foo. bar. Perl 6', 30 | ['foo', 'bar', 'perl 6'], 31 | ); 32 | 33 | my $t = November::Tags.new; 34 | 35 | for @to_parse -> $in, $expected { 36 | is-deeply( [$t.tags_parse($in)], $expected, 'Parse tags: ' ~ $in.perl); 37 | } 38 | 39 | # vim:ft=perl6 40 | -------------------------------------------------------------------------------- /t/storage/save_page.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 1; 5 | 6 | use November::Storage::File; 7 | 8 | role Testing { 9 | method beforeTest { 10 | my $fh = open($.index_path, :w); 11 | $fh.say('[]'); 12 | $fh.close; 13 | } 14 | 15 | method afterTest { 16 | # TODO: Make more platform-independent, somehow. 17 | run("rm $.index_path"); 18 | } 19 | } 20 | 21 | my $s = November::Storage::File.new does Testing; 22 | $s.content_path = 't/storage/data/articles/'; 23 | $s.modifications_path = 't/storage/data/modifications/'; 24 | $s.recent_changes_path = 't/storage/data/recent-changes'; 25 | $s.index_path = 't/storage/index_data'; 26 | 27 | $s.beforeTest; 28 | 29 | is($s.read_index.perl, '[]', 'Read clear index'); 30 | 31 | #TODO: more tests here :) 32 | 33 | $s.afterTest; 34 | 35 | 36 | # vim:ft=perl6 37 | -------------------------------------------------------------------------------- /p5w/t/tag_count_normalize.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 2; 2 | use November; 3 | use Data::Dumper; 4 | 5 | my $tf = \&November::tag_count_normalize; 6 | 7 | my @counts_to_test = ( 8 | [ { one => 2, foo => 5, bar => 6, her => 14 }, 9 | { one => 0, foo => 4, bar => 5, her => 10} ], 10 | [ { one => 5, foo => 5, bar => 2, her => 1 }, 11 | { one => 10, foo => 10, bar => 4, her => 0} ], 12 | ); 13 | 14 | for (@counts_to_test) { 15 | my ($tags, $expected) = @$_; 16 | 17 | my %tags = %$tags; 18 | my %expected = %$expected; 19 | 20 | 21 | use List::Util qw| max min |; 22 | 23 | my $min = min values %tags; 24 | my $max = max values %tags; 25 | my %out; 26 | for (keys %tags) { 27 | $out{$_} = $tf->($tags{$_}, $min, $max); 28 | } 29 | 30 | is-deeply( \%out , \%expected, 'Normalize: ' . Dumper(\%tags) ); 31 | } 32 | -------------------------------------------------------------------------------- /t/storage/modification.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 5; 5 | 6 | use November::Storage::File; 7 | 8 | role Testing { 9 | method clear { 10 | run 'rm t/storage/data/modifications/*'; 11 | run 'touch t/storage/data/modifications/empty-file'; 12 | } 13 | } 14 | 15 | my $s = November::Storage::File.new does Testing; 16 | $s.modifications_path = 't/storage/data/modifications/'; 17 | 18 | my $id = $s.write_modification([ 'Page', 'Text', 'Author' ]); 19 | 20 | ok($id, 'write_modification returns an id'); 21 | 22 | my $modif = $s.read_modification($id); 23 | 24 | is($modif[0], 'Page', 'read modification data -- Page'); 25 | is($modif[1], 'Text', 'read modification data -- Text'); 26 | is($modif[2], 'Author', 'read modification data -- Author'); 27 | ok($modif[3] <= time.Int, 'read time, and it <= now'); 28 | 29 | $s.clear; 30 | 31 | # vim:ft=perl6 32 | -------------------------------------------------------------------------------- /t/cgi/03-urlencoded.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | use November::CGI; 5 | 6 | my @t = 7 | '%61' => 'a', 8 | '%C3%A5' => 'å', 9 | '%C4%AC' => 'Ĭ', 10 | '%C7%82' => 'ǂ', 11 | '%E2%98%BA' => '☺', 12 | '%E2%98%BB' => '☻', 13 | 'alla+snubbar' => 'alla snubbar', 14 | 'text%61+abc' => 'texta abc', 15 | 'unicode+%C7%82%C3%A5' => 'unicode ǂå', 16 | '%25' => '%', 17 | '%25+25' => '% 25', 18 | '%25rr' => '%rr', 19 | '%2561' => '%61', 20 | ; 21 | 22 | plan +@t; 23 | 24 | for @t { 25 | my $ans = November::CGI::unescape( ~.key ); 26 | ok( $ans eq .value, 'Decoding ' ~ .key ) 27 | or say "GOT: {$ans.perl}\nEXPECTED: {.value.perl}"; 28 | 29 | } 30 | 31 | # vim: ft=perl6 32 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/recent_changes.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Recent changes 5 | 6 | 7 | 8 | 9 |
10 |

Recent changes

11 | 12 |
    13 | 14 |
  • 15 | was changed on 16 | by 17 | 18 |
  • 19 |
    20 |
21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/recent_changes.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Recent changes 5 | 6 | 7 | 8 | 9 |
10 |

Recent changes

11 | 12 |
    13 | 14 |
  • 15 | was changed on 16 | by 17 | 18 |
  • 19 |
    20 |
21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /t/tags/norm_counts.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 3; 5 | 6 | use November::Tags; 7 | 8 | use November::Config; 9 | my $config = November::Config.new( 10 | server_root => 't/tags/', 11 | ); 12 | 13 | role Testing { 14 | method clear { 15 | my $c = {}; 16 | self.write_tags_count( $c ); 17 | } 18 | } 19 | 20 | my $t = November::Tags.new(:$config) does Testing; 21 | $t.clear; 22 | 23 | is( ($t.norm_counts).perl, '{}', 'With empty tags_count norm_counts produce empty Hash' ); 24 | 25 | my $in = { foo => 5, bar => 5, baz => 2, her => 1 }; 26 | $t.write_tags_count($in); 27 | 28 | is-deeply( $t.norm_counts, {"foo" => 10, "bar" => 10, "baz" => 4, "her" => 0}, 'Normalize all from: ' ~ $in.perl ); 29 | 30 | my @tags = ; 31 | is-deeply( $t.norm_counts(@tags), {"foo" => 10, "baz" => 4}, 'Normalize foo and baz from: ' ~ $in.perl ); 32 | 33 | 34 | $t.clear; 35 | 36 | # vim:ft=perl6 37 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/view.tmpl: -------------------------------------------------------------------------------- 1 | 2 | <TMPL_VAR NAME=TITLE> 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

12 | 13 | 14 | 15 | 16 |
17 | 18 |
19 |
20 | 21 | 22 | 23 | 28 | 29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PERL6 = perl6 2 | 3 | SOURCES = \ 4 | lib/Digest.pm \ 5 | lib/Digest/SHA.pm \ 6 | lib/Dispatcher.pm \ 7 | lib/Dispatcher/Rule.pm \ 8 | lib/November.pm \ 9 | lib/November/CGI.pm \ 10 | lib/November/Cache.pm \ 11 | lib/November/Config.pm \ 12 | lib/November/Session.pm \ 13 | lib/November/Storage.pm \ 14 | lib/November/Storage/File.pm \ 15 | lib/November/Tags.pm \ 16 | lib/November/URI.pm \ 17 | lib/November/URI/Grammar.pm \ 18 | lib/November/Utils.pm \ 19 | lib/November/Utils.pm \ 20 | lib/Test/CGI.pm \ 21 | lib/Test/InputOutput.pm \ 22 | lib/Text/Markup/Wiki/MediaWiki.pm \ 23 | lib/Text/Markup/Wiki/Minimal.pm 24 | 25 | PIRS = $(SOURCES:.pm=.pir) 26 | 27 | all: $(PIRS) 28 | 29 | %.pir: %.pm 30 | $(PERL6) --target=pir --output=$@ $< 31 | 32 | clean: 33 | rm -f $(PIRS) 34 | 35 | tests: test 36 | 37 | test: all 38 | prove -e '$(PERL6)' -r --nocolor t/ 39 | -------------------------------------------------------------------------------- /t/storage/index.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 4; 5 | 6 | use November::Storage::File; 7 | 8 | role Testing { 9 | method beforeTest { 10 | my $fh = open($.index_path, :w); 11 | $fh.say('[]'); 12 | $fh.close; 13 | } 14 | 15 | method afterTest { 16 | # TODO: Make more platform-independent, somehow. 17 | run("rm $.index_path"); 18 | } 19 | } 20 | 21 | my $s = November::Storage::File.new does Testing; 22 | $s.index_path = 't/storage/index_data'; 23 | 24 | $s.beforeTest; 25 | 26 | is($s.read_index.perl, '[]', 'Read clear index'); 27 | $s.add_to_index('Foo'); 28 | is($s.read_index.perl, '["Foo"]', 'Add to index one page'); 29 | $s.add_to_index('Bar'); 30 | is($s.read_index.perl, '["Foo", "Bar"]', 'Add to index another page'); 31 | $s.add_to_index('Foo'); 32 | is($s.read_index.perl, '["Foo", "Bar"]', 'Do not add dup to index page'); 33 | 34 | $s.afterTest; 35 | 36 | 37 | # vim:ft=perl6 38 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/view.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <TMPL_VAR NAME=TITLE> 5 | 6 | 7 | 8 | 9 |
10 |

11 | 12 |
13 |
14 | 15 | 16 |
17 |

All tags

18 | 19 |
20 |
21 | 22 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /skins/Autumn/edit.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |

11 |
12 | 13 |

14 | Tags: 15 |

16 | or cancel 17 |

18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /lib/Test/InputOutput.pm: -------------------------------------------------------------------------------- 1 | use v6; 2 | use Test; 3 | 4 | class Test::InputOutput { 5 | has $.filter; 6 | 7 | method using($filter) { 8 | return Test::InputOutput.new( filter => $filter ); 9 | } 10 | 11 | method test(@tests) { 12 | for @tests -> $test { 13 | my ($input, $expected, $description); 14 | 15 | if $test[0] ~~ Pair { 16 | $input = $test[0].key; 17 | $expected = $test[0].value; 18 | $description = $test[1] // ''; 19 | } 20 | else { 21 | if $test.elems < 2 { 22 | ok(0); 23 | return (); 24 | } 25 | $input, $expected, $description = $test.values; 26 | } 27 | 28 | my $actual = $!filter($input); 29 | 30 | is( $actual, $expected, $description ); 31 | } 32 | } 33 | } 34 | 35 | # vim:ft=perl6 36 | -------------------------------------------------------------------------------- /t/markup/mediawiki/15-mixed-lists.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | my @tests = 4 | [ 5 | "* a\n** a1\n* b" => 6 | "
    \n
  • a\n
      \n
    • a1
    • \n
    \n
  • \n
  • b
  • \n
", 7 | 'a list inside a list' 8 | ], 9 | 10 | [ 11 | "* a\n*; a1: a2\n* b" => 12 | "
    \n
  • a\n" 13 | ~ "
    \n
    a1
    \n
    a2
    \n
    \n
  • \n
  • b
  • \n
", 14 | 'a definition list inside a bullet list' 15 | ], 16 | 17 | [ 18 | "*:##; OH HAI" => 19 | "
    \n
  • \n
    \n
    \n
      \n
    1. \n
        \n
      1. \n
        \n
        OH HAI
        " 20 | ~ "\n
        \n
      \n
    \n
    \n
", 21 | 'deep nesting' 22 | ], 23 | ; 24 | 25 | # RAKUDO: Doesn't respect "use Test :EXPORT" 26 | use Test; 27 | use Test::InputOutput; 28 | plan +@tests; 29 | 30 | todo('not implemented yet', +@tests); 31 | 32 | use Text::Markup::Wiki::MediaWiki; 33 | 34 | my $converter = Text::Markup::Wiki::MediaWiki.new; 35 | Test::InputOutput.using( { $converter.format($^input) } ).test(@tests); 36 | 37 | # vim:ft=perl6 38 | -------------------------------------------------------------------------------- /lib/November/URI/Grammar.pm: -------------------------------------------------------------------------------- 1 | use v6; 2 | grammar November::URI::Grammar { 3 | token TOP { ^ [ ':']? [ '//' ]? ['?' ]? ['#' ]? $ }; 4 | token scheme { <-[:/&?#]>+ }; 5 | token authority { [':' ]? }; 6 | token host { <-[/&?#:]>* }; 7 | token port { (\d**1..5) 8 | 9 | }; 10 | token path { ? [ '/'?]* }; # * mb wrong, because that allow '' URI 11 | token slash { '/' }; 12 | token chunk { <-[/?#]>+ }; 13 | token query { <-[#]>* }; 14 | token fragment { .* }; 15 | } 16 | 17 | # Official regexp (p5): 18 | # my($scheme, $authority, $path, $query, $fragment) = 19 | # $uri =~ m/ 20 | # (?:([^:/?#]+):)? 21 | # (?://([^/?#]*))? 22 | # ([^?#]*) 23 | # (?:\?([^#]*))? 24 | # (?:#(.*))? 25 | # /x; 26 | 27 | # vim:ft=perl6 28 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/recent_changes.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Recent changes 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Recent changes

12 | 13 |
    14 | 15 |
  • 16 | was changed 17 | by 18 | 19 |
  • 20 |
    21 |
22 |
23 | 24 | 25 | 26 | 31 | 32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/sidebar.tmpl: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /t/markup/mediawiki/12-unordered-lists.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | my @tests = 4 | [ 5 | "* a\n* b\n* c" => 6 | "
    \n
  • a
  • \n
  • b
  • \n
  • c
  • \n
", 7 | 'an ordinary bullet list' 8 | ], 9 | 10 | [ 11 | "* a\n\n* c" => 12 | "
    \n
  • a
  • \n
\n\n
    \n
  • c
  • \n
", 13 | 'an empty line creates a new list' 14 | ], 15 | 16 | [ 17 | "foo\n* a\n* b\nbar" => 18 | "

foo

\n\n
    \n
  • a
  • \n
  • b
  • \n
\n\n

bar

", 19 | 'text before and after without empty lines' 20 | ], 21 | 22 | [ 23 | "foo\n\n* a\n* b\n\nbar" => 24 | "

foo

\n\n
    \n
  • a
  • \n
  • b
  • \n
\n\n

bar

", 25 | 'text before and after with empty lines' 26 | ], 27 | ; 28 | 29 | # RAKUDO: Doesn't respect "use Test :EXPORT" 30 | use Test; 31 | use Test::InputOutput; 32 | plan +@tests; 33 | 34 | use Text::Markup::Wiki::MediaWiki; 35 | 36 | my $converter = Text::Markup::Wiki::MediaWiki.new; 37 | Test::InputOutput.using( { $converter.format($^input) } ).test(@tests); 38 | 39 | # vim:ft=perl6 40 | -------------------------------------------------------------------------------- /t/markup/mediawiki/13-numbered-lists.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | my @tests = 4 | [ 5 | "# a\n# b\n# c" => 6 | "
    \n
  1. a
  2. \n
  3. b
  4. \n
  5. c
  6. \n
", 7 | 'an ordinary numbered list' 8 | ], 9 | 10 | [ 11 | "# a\n\n# c" => 12 | "
    \n
  1. a
  2. \n
\n\n
    \n
  1. c
  2. \n
", 13 | 'an empty line creates a new list' 14 | ], 15 | 16 | [ 17 | "foo\n# a\n# b\nbar" => 18 | "

foo

\n\n
    \n
  1. a
  2. \n
  3. b
  4. \n
\n\n

bar

", 19 | 'text before and after without empty lines' 20 | ], 21 | 22 | [ 23 | "foo\n\n# a\n# b\n\nbar" => 24 | "

foo

\n\n
    \n
  1. a
  2. \n
  3. b
  4. \n
\n\n

bar

", 25 | 'text before and after with empty lines' 26 | ], 27 | ; 28 | 29 | # RAKUDO: Doesn't respect "use Test :EXPORT" 30 | use Test; 31 | use Test::InputOutput; 32 | plan +@tests; 33 | 34 | use Text::Markup::Wiki::MediaWiki; 35 | 36 | my $converter = Text::Markup::Wiki::MediaWiki.new; 37 | Test::InputOutput.using( { $converter.format($^input) } ).test(@tests); 38 | 39 | # vim:ft=perl6 40 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/log_in.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Log in 5 | 6 | 7 | 8 | 9 |
10 |

Log in

11 |

Everything you say can, and will, be used against you. Please 12 | put on your own mask first, then help others.

13 | 14 |
15 | 16 |

Username:

17 |

Password:

18 | 19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/log_in.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Log in 5 | 6 | 7 | 8 | 9 |
10 |

Log in

11 |

Everything you say can, and will, be used against you. Please 12 | put on your own mask first, then help others.

13 | 14 |
15 | 16 |

Username:

17 |

Password:

18 | 19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/page_history.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | History of '<TMPL_VAR NAME=TITLE>' 5 | 6 | 7 | 8 | 9 |
10 |

History of ''

11 | 12 |
    13 | 14 |
  • 15 | (view) 16 | (diff) 17 | Changed on 18 | by 19 | 20 |
  • 21 |
    22 |
23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/page_history.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | History of '<TMPL_VAR NAME=TITLE>' 5 | 6 | 7 | 8 | 9 |
10 |

History of ''

11 | 12 |
    13 | 14 |
  • 15 | (view) 16 | (diff) 17 | Changed on 18 | by 19 | 20 |
  • 21 |
    22 |
23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /data/modifications/16571: -------------------------------------------------------------------------------- 1 | ["FAQ", "''Larry Wall: You should not take this picture to mean that linguistics is the opposite of common sense. But ehm, there are many computer scientists, who have complained that it should be more like engineering and less like an art. And I disagree. But that's okay.''\n\n== Excerpt from the ''Language Design'' Tablet ==\n\nThe complete text can be found at [http://www.perlfoundation.org/perl6/index.cgi?perl_6_language_design_tablet].\n\n== Main Goal ==\n\nEnjoy Life and enjoy the freedom of expressing yourself. Which means: support you as much as possible and not to force you in any way. Perl 6 likes to be even better than Perl 5, your humble servant for translating your thoughts into binary code (if possible).\n\n== Strategy ==\n\nEvery style and level of expertise has to be supported and even more difficult: all of them have to play together well. The default often imitates a natural language (i.e. english). Strategies and concepts for this are coined in several often repeated terms.\n\n\n", "someone", "basic FAQ page so there's something to look at", 1310165701] 2 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Here is a list of people and their CPAN id. These people have either 2 | submitted patches or suggestions, or their bug reports or comments 3 | have inspired the appropriate patches. Corrections, additions, 4 | deletions welcome: 5 | 6 | Andrew Shitov Андрей Шитов 7 | Carl Masak (MASAK) Carl Mäsak 8 | Conrad Schneiker 9 | Daniel Carrera 10 | Jason "Wolfman2000" Felds (WOLFMAN) 11 | Frederik Schwarzer 12 | Herbert Breunung (LICHTKIND) 13 | Ilya Belikin (aka Ihrd) Илья Беликин 14 | Johan Viklund (VIKLUND) 15 | Jonathan Scott Duff (DUFF) 16 | Lyle 17 | Michael Peters 18 | Moritz Lenz (MORITZ) 19 | Patrick R. "pmichaud" Michaud (PMICHAUD) 20 | 21 | -------------------------------------------------------------------------------- /lib/November/Session.pm: -------------------------------------------------------------------------------- 1 | unit role November::Session; 2 | 3 | method sessionfile-path { 4 | return $.config.server_root ~ 'data/sessions'; 5 | } 6 | 7 | method add_session($id, %stuff) { 8 | my $sessions = self.read_sessions(); 9 | $sessions{$id} = %stuff; 10 | self.write_sessions($sessions); 11 | } 12 | 13 | method remove_session($id) { 14 | my $sessions = self.read_sessions(); 15 | $sessions.delete($id); 16 | self.write_sessions($sessions); 17 | } 18 | 19 | method read_sessions { 20 | use MONKEY-SEE-NO-EVAL; 21 | return {} unless self.sessionfile-path.IO ~~ :e; 22 | my $string = slurp( self.sessionfile-path ); 23 | my $stuff = EVAL( $string ); 24 | return $stuff; 25 | } 26 | 27 | method write_sessions( $sessions ) { 28 | my $fh = open( self.sessionfile-path, :w ); 29 | $fh.say( $sessions.perl ); 30 | $fh.close; 31 | } 32 | 33 | method new_session($user_name) { 34 | use November::Utils; 35 | my $session_id = get_unique_id; 36 | self.add_session( $session_id, { user_name => $user_name } ); 37 | return $session_id; 38 | } 39 | 40 | # vim:ft=perl6 41 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/page_history.tmpl: -------------------------------------------------------------------------------- 1 | 2 | History of '<TMPL_VAR NAME=TITLE>' 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

History of ''

12 | 13 |
    14 | 15 |
  • 16 | (view) 17 | (diff) 18 | Changed on 19 | by 20 | 21 |
  • 22 |
    23 |
24 |
25 | 26 | 27 | 32 | 33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/view_diff.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Diff of <TMPL_VAR NAME=PAGE> 5 | 6 | 7 | 8 | 9 |
10 |

Diff of

11 | 12 | 13 | 14 | 15 | 16 | 19 | 22 | 23 | 24 | 25 |
17 | 18 | 20 | 21 |
26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/view_diff.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Diff of <TMPL_VAR NAME=PAGE> 5 | 6 | 7 | 8 | 9 |
10 |

Diff of

11 | 12 | 13 | 14 | 15 | 16 | 19 | 22 | 23 | 24 | 25 |
17 | 18 | 20 | 21 |
26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/edit.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <TMPL_VAR NAME=TITLE> 5 | 6 | 7 | 8 | 9 |
10 |

11 |
12 | 13 | 14 | 15 |

16 | Tags: 17 |

18 | or cancel 19 |

20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/edit.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <TMPL_VAR NAME=TITLE> 5 | 6 | 7 | 8 | 9 |
10 |

11 |
12 | 13 | 14 | 15 |

16 | Tags: 17 |

18 | or cancel 19 |

20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /t/dispatcher/04-regex.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 6; 5 | 6 | use Dispatcher; 7 | my $d = Dispatcher.new; 8 | $d.add: [ 9 | ['foo', /^ \d+ $/], { $^d }, 10 | [/^ \w+ $/], { "Yep!" if $^w ~~ Match }, 11 | ['foo', / \d+ /], { $^d + 10 }, 12 | ['foo', / \d+ /, 'bar' ], { $^d + 1 }, 13 | ['summ', / \d+ /, / \d+ / ], { $^a + $^b }, 14 | ['summ', / \w+ /, 1|2 ], { $^a ~ "oo" } 15 | ]; 16 | 17 | 18 | is( $d.dispatch(['foo']), 19 | 'Yep!', 20 | 'Pattern with regex \w+, put Match in args' 21 | ); 22 | 23 | is( $d.dispatch(['foo', '50']), 24 | '60', 25 | "Dispatch ['foo', '50'] to last matched Rule" 26 | ); 27 | 28 | is( $d.dispatch(['foo', 'a50z']), 29 | '60', 30 | 'Pattern with regex \d, put Match in args' 31 | ); 32 | 33 | is( $d.dispatch(['foo', 'item4', 'bar']), 34 | '5', 35 | 'Pattern with regexp in the middle (foo/\d+/bar)' 36 | ); 37 | 38 | is( $d.dispatch(['summ', '2', '3']), 39 | '5', 40 | 'Pattern with two regexs' 41 | ); 42 | 43 | is( $d.dispatch(['summ', 'Z', '2']), 44 | 'Zoo', 45 | 'Pattern with regexp and junction' 46 | ); 47 | 48 | # vim:ft=perl6 49 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/log_in.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Log in 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Log in

12 |

Everything you say can, and will, be used against you. Please 13 | put on your own mask first, then help others.

14 | 15 |
16 | 17 |

Username:

18 |

Password:

19 | 20 |
21 |
22 | 23 | 24 | 25 | 30 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /t/integration/01-view_page.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | use November; 5 | use Test::CGI; 6 | use November::Config; 7 | use November::URI; 8 | 9 | my @markups = < Text::Markup::Wiki::MediaWiki >; 10 | my @skins = < CleanAndSoft >; 11 | 12 | my %gets = { 13 | #'' => 'View main page', 14 | '/view/Main_Page' => 'View specific page', 15 | '/view/Snrsdfda' => 'View unexisting page', 16 | '/in' => 'Log in page', 17 | '/out' => 'Log out page', 18 | '/recent' => 'Recent changes', 19 | '/all' => 'All pages', 20 | '/all?tag=november' => 'All pages, specific tag', 21 | }; 22 | 23 | plan @markups * @skins * %gets; 24 | 25 | for @markups X @skins -> $m, $s { 26 | my $c = November::Config.new( markup => ::($m), skin => $s ); 27 | my $w = November.new( config => $c ); 28 | for %gets.kv -> $page, $description { 29 | my $uri = November::URI.new( uri => 'http://testserver' ~ $page ); 30 | my $cgi = Test::CGI.new( uri => $uri ); 31 | $cgi.parse_params( $page ); 32 | lives-ok( { $w.handle_request( $cgi ) }, "$m, $s, $description" ); 33 | } 34 | } 35 | 36 | # vim:ft=perl6 37 | -------------------------------------------------------------------------------- /skins/Autumn/view.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |

Recently changed

16 |
    17 | 18 |
  • 19 | by 20 |
  • 21 |
    22 |
23 |
24 |
25 | 26 |
27 |

28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/login_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Login successful 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

Login successful

15 |

You got in!

16 |
17 | 29 | 30 | 31 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /t/markup/mediawiki/14-definition-lists.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | my @tests = 4 | [ 5 | "; a: b\n; c: d" => 6 | "
\n
a
\n
b
\n
b
\n
c\n
", 7 | 'an ordinary definition list' 8 | ], 9 | 10 | [ 11 | "; a\n: b\n; c\n: d" => 12 | "
\n
a
\n
b
\n
b
\n
c\n
", 13 | 'definition list, values are on separate lines' 14 | ], 15 | 16 | [ 17 | "; a\n\n: c" => 18 | "
\n
a
\n
\n\n
\n
c
\n
", 19 | 'an empty line creates a new list' 20 | ], 21 | 22 | [ 23 | "foo\n; a\n: b\nbar" => 24 | "

foo

\n\n
\n
a
\n
b
\n
\n\n

bar

", 25 | 'text before and after without empty lines' 26 | ], 27 | 28 | [ 29 | "foo\n\n; a\n: b\n\nbar" => 30 | "

foo

\n\n
\n
a
\n
b
\n
\n\n

bar

", 31 | 'text before and after with empty lines' 32 | ], 33 | ; 34 | 35 | # RAKUDO: Doesn't respect "use Test :EXPORT" 36 | use Test; 37 | use Test::InputOutput; 38 | plan +@tests; 39 | 40 | todo('not implemented yet', +@tests); 41 | 42 | use Text::Markup::Wiki::MediaWiki; 43 | 44 | my $converter = Text::Markup::Wiki::MediaWiki.new; 45 | Test::InputOutput.using( { $converter.format($^input) } ).test(@tests); 46 | 47 | # vim:ft=perl6 48 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/register.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Register 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Register

12 |

Everything you say can, and will, be used against you. Please 13 | create your own mask first, then help others.

14 | 15 |
16 | 17 |

Username:

18 |

Password:

19 |

Password again:

20 | 21 |
22 |
23 | 24 | 25 | 26 | 31 | 32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/login_failed.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Login failed 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

Login failed

15 |

Something went wrong. Sorry.

16 |
17 | 28 | 29 | 30 | 35 | 36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/logout_succeeded.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logout successful 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

Logout successful

15 |

You got out!

16 |
17 | 28 | 29 | 30 | 35 | 36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/unknown_action.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Unknown action 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

Unknown action

15 | Unknown action "". 16 |
17 | 28 | 29 | 30 | 35 | 36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /skins/Autumn/list_all_pages.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |

15 | 16 | Articles with tag "" 17 | 18 | All articles list 19 | 20 |

21 | 22 | 23 |
    24 | 25 |
  • 26 | 27 |
  • 28 |
    29 |
30 |
31 | 32 | 33 |

Return to all articles list

34 |
35 | 36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/view_diff.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Diff of <TMPL_VAR NAME=PAGE> 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

Diff of

12 | 13 | 14 | 15 | 16 | 17 | 20 | 23 | 24 | 25 | 26 |
18 | 19 | 21 | 22 |
27 |
28 | 29 | 30 | 31 | 36 | 37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/action_not_authorized.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Not logged in 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

Not logged in

15 |

You need to be logged in to .

16 |
17 | 28 | 29 | 30 | 35 | 36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/page_too_old.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Unknown action 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

Page too old

15 | Someone hit the save button on '' before 16 | you did. 17 |
18 | 29 | 30 | 31 | 36 | 37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/list_all_pages.tmpl: -------------------------------------------------------------------------------- 1 | 2 | Articles list 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

12 | 13 | Articles with tag "" 14 | 15 | All articles list 16 | 17 |

18 | 19 | 20 |
    21 | 22 |
  • 23 | 24 |
  • 25 |
    26 |
27 |
28 | 29 | 30 |

Return to all articles list

31 |
32 |
33 | 34 | 35 | 36 | 41 | 42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/not_found.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Page not found 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

Page not found

15 |
16 | The page '' was not found. 17 |
18 |
19 | 32 | 33 | 34 | 39 | 40 |
41 | 42 | 43 | -------------------------------------------------------------------------------- /t/cgi/02-cgi_post.t.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Use shell script here, because 3 | # RAKUDO: Can`t modify %*ENV; 4 | 5 | echo -n "foo=bar" | 6 | REQUEST_METHOD='POST' \ 7 | SERVER_NAME='test.foo' \ 8 | TEST_RESULT='{"foo" => "bar"}' \ 9 | TEST_NAME='Post foo=bar' \ 10 | ./t/cgi/cgi_post_test; 11 | 12 | echo -n "foo=bar&boo=her" | 13 | REQUEST_METHOD='POST' \ 14 | SERVER_NAME='test.foo' \ 15 | TEST_RESULT='{"foo" => "bar", "boo" => "her"}' \ 16 | TEST_NAME='Post foo=bar&boo=her' \ 17 | ./t/cgi/cgi_post_test; 18 | 19 | echo -n "test=foo&test=bar" | 20 | REQUEST_METHOD='POST' \ 21 | SERVER_NAME='test.foo' \ 22 | TEST_RESULT='{"test" => ["foo", "bar"] }' \ 23 | TEST_NAME='Post test=foo&test=bar' \ 24 | ./t/cgi/cgi_post_test; 25 | 26 | echo -n "test=foo&test=bar&foo=bar" | 27 | REQUEST_METHOD='POST' \ 28 | SERVER_NAME='test.foo' \ 29 | TEST_RESULT='{"test" => ["foo", "bar"], "foo" => "bar"}' \ 30 | TEST_NAME='Post test=foo&test=bar&foo=bar' \ 31 | ./t/cgi/cgi_post_test; 32 | 33 | echo -n "test=foo" | 34 | REQUEST_METHOD='POST' \ 35 | SERVER_NAME='test.foo' \ 36 | QUERY_STRING="boom=bar" \ 37 | TEST_RESULT='{"test" => "foo", "boom" => "bar" }' \ 38 | TEST_NAME='Post test=foo Get boom=bar (test get and post mix)' \ 39 | ./t/cgi/cgi_post_test; 40 | 41 | echo -n "test=foo" | 42 | REQUEST_METHOD='POST' \ 43 | SERVER_NAME='test.foo' \ 44 | QUERY_STRING="test=bar" \ 45 | TEST_RESULT='{"test" => ["bar", "foo"] }' \ 46 | TEST_NAME='Post test=foo Get test=bar (test get and post mix)' \ 47 | ./t/cgi/cgi_post_test; 48 | -------------------------------------------------------------------------------- /t/dispatcher/01-basics.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 9; 5 | 6 | use Dispatcher; 7 | ok(1,'We use Dispatcher and we are still alive'); 8 | 9 | use Dispatcher::Rule; 10 | ok(1,'We use Dispatcher::Rule and we are still alive'); 11 | 12 | my $d = Dispatcher.new; 13 | 14 | dies-ok( { $d.add: Dispatcher::Rule.new }, 15 | '.add adds only complete Rule objects' ); 16 | 17 | $d.add: Dispatcher::Rule.new( :pattern(['']), code => { "Krevedko" } ); 18 | 19 | is( $d.dispatch(['']), 20 | 'Krevedko', 21 | "Pattern ['']" 22 | ); 23 | 24 | ok( $d.add( ['foo', 'bar'], { "Yay" } ), 25 | '.add(@pattern, $code) -- shortcut for fast add Rule object' ); 26 | 27 | # RAKUDO: dispatch() returns Failure here, and rakudo gives Null PMC access 28 | # when converting that to Bool; this works around it somehow 29 | #nok( $d.dispatch(['foo']), 30 | nok( $d.dispatch(['foo']) ?? True !! False, 31 | 'Dispatcher return False if can`t find matched Rule and do not have default' ); 32 | 33 | 34 | is( $d.dispatch(['foo', 'bar']), 35 | "Yay", 36 | "Dispatch to Rule ['foo', 'bar'])" 37 | ); 38 | 39 | $d.default = { "Woow" }; 40 | 41 | is( $d.dispatch(['foo', 'bar', 'baz']), 42 | "Woow", 43 | 'Dispatch to default, when there\'s no matched Rule' 44 | ); 45 | 46 | $d = Dispatcher.new( default => { "Woow" } ); 47 | 48 | is( $d.dispatch(['foo', 'bar', 'baz']), 49 | "Woow", 50 | 'Dispatch to default created on init, when there\'s no matched Rule' 51 | ); 52 | # vim:ft=perl6 53 | -------------------------------------------------------------------------------- /lib/November/Utils.pm: -------------------------------------------------------------------------------- 1 | unit module November::Utils; 2 | 3 | sub r_remove( $str is rw ) is export { 4 | $str .= subst( /\\r/, '', :g ); 5 | } 6 | 7 | sub get_unique_id is export { 8 | # hopefully pretty unique ID 9 | return (time%1000000/100).Int ~ time%100 10 | 11 | # mb that? just for simple time extracts after? 12 | # return int rand ~ ':' ~ time; 13 | } 14 | 15 | sub get_period ($modif_time, $time_now?) is export { 16 | my $time = $time_now || time.Int; 17 | my $period = $time - $modif_time; 18 | 19 | my $mins = ($period / 60).Int; 20 | my $hours = ($period / 60 / 60).Int; 21 | my $days = ($period / 60 / 60 / 24).Int; 22 | 23 | if $days >= 1 { 24 | $hours = $hours - $days * 24; 25 | $mins = $mins - $days * 60 * 24; 26 | } else { 27 | $days = 0; 28 | } 29 | 30 | if $hours >= 1 { 31 | $mins = $mins - $hours * 60; 32 | } 33 | else { 34 | $hours = 0; 35 | } 36 | 37 | $mins = 1 if $mins < 1; 38 | return ($days, $hours, $mins) 39 | } 40 | 41 | sub time_to_period_str ($time) is export { 42 | return False unless $time; 43 | my $t = get_period($time); 44 | my $str = '~'; 45 | 46 | # return only days if period > day 47 | if $t[0] -> $days { 48 | $str ~= $days; 49 | $str ~= (+$days == 1 ) ?? ' day' !! ' days'; 50 | $str ~= ' ago'; 51 | return $str; 52 | } 53 | 54 | $str ~= $t[1] ~ 'h ' if $t[1]; 55 | $str ~= $t[2] ~ 'm ago'; 56 | return $str; 57 | } 58 | 59 | 60 | # vim:ft=perl6 61 | -------------------------------------------------------------------------------- /META6.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "November", 3 | "version" : "*", 4 | "author" : "github:viklund", 5 | "description" : "A wiki engine written in Perl 6", 6 | "provides" : { 7 | "November" : "lib/November.pm", 8 | "Dispatcher" : "lib/Dispatcher.pm", 9 | "Test::CGI" : "lib/Test/CGI.pm", 10 | "Test::InputOutput" : "lib/Test/InputOutput.pm", 11 | "Text::Markup::Wiki::Minimal" : 12 | "lib/Text/Markup/Wiki/Minimal.pm", 13 | "Text::Markup::Wiki::MediaWiki" : 14 | "lib/Text/Markup/Wiki/MediaWiki.pm", 15 | "Text::Markup::Wiki::Minimal::Grammar" : 16 | "lib/Text/Markup/Wiki/Minimal/Grammar.pm", 17 | "Dispatcher::Rule" : "lib/Dispatcher/Rule.pm", 18 | "November::URI" : "lib/November/URI.pm", 19 | "November::Tags" : "lib/November/Tags.pm", 20 | "November::Storage" : "lib/November/Storage.pm", 21 | "November::CGI" : "lib/November/CGI.pm", 22 | "November::Session" : "lib/November/Session.pm", 23 | "November::Utils" : "lib/November/Utils.pm", 24 | "November::Config" : "lib/November/Config.pm", 25 | "November::Cache" : "lib/November/Cache.pm", 26 | "November::URI::Grammar" : "lib/November/URI/Grammar.pm", 27 | "November::Storage::File" : "lib/November/Storage/File.pm" 28 | }, 29 | "depends" : ["HTML::Template", "Digest"], 30 | "source-url" : "git://github.com/viklund/november.git" 31 | } 32 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/recent_changes.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Recent changes 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

Recent changes

15 | 16 |
    17 | 18 |
  • 19 | was changed on 20 | by 21 | 22 |
  • 23 |
    24 |
25 |
26 | 38 | 39 | 40 | 45 | 46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/edit.tmpl: -------------------------------------------------------------------------------- 1 | 2 | <TMPL_VAR NAME=TITLE> 3 | 4 | 5 |
6 |
7 | 8 |
9 |
 
10 |
11 |

12 | 13 |

PREVIEW

14 | 15 |
16 |
17 | 18 | 19 |
20 | 21 |
22 | Tags: 23 | Summary: 24 |

25 | , or cancel 26 |

27 |
28 | 29 | 30 | 31 | 36 | 37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /lib/Dispatcher.pm: -------------------------------------------------------------------------------- 1 | class Dispatcher { 2 | use Dispatcher::Rule; 3 | 4 | has @.rules; 5 | has $.default is rw; 6 | 7 | multi method add (Dispatcher::Rule $rule) { 8 | die "Only complete rules allowed" unless $rule.?is_complete; 9 | @!rules.push($rule); 10 | } 11 | 12 | multi method add (@pattern, Code $code) { 13 | my $rule = Dispatcher::Rule.new( pattern => @pattern, code => $code ); 14 | @!rules.push($rule); 15 | } 16 | 17 | multi method add (@rules) { 18 | # The following line of code is in relatively high flux, due to 19 | # changes in the Spec and Rakudo when it comes to handling of 20 | # typed arrays etc. For a long time, it said 'Object @pattern', 21 | # in order to prevent autothreading on the elements of @pattern. 22 | # (Object, as opposed to Any, causes signature bindings not to 23 | # autothread.) However, (a) this typing might not be needed, because 24 | # 'Object' might actually be the default, and (b) in current 25 | # versions of Rakudo, writing 'Object @pattern' wrongly causes 26 | # the Array not to bind, despite the fact that any Array should. 27 | for @rules -> @pattern, $action { 28 | self.add(@pattern, $action); 29 | } 30 | return @.rules.elems; 31 | } 32 | 33 | method dispatch (@chunks) { 34 | my @matched = @!rules.grep: { .match(@chunks) }; 35 | 36 | if @matched { 37 | my $result = @matched[*-1].apply; 38 | .clear for @!rules; 39 | return $result; 40 | } 41 | elsif defined $.default { 42 | $.default().(); 43 | } 44 | else { 45 | return Failure; 46 | } 47 | } 48 | } 49 | 50 | # vim:ft=perl6 51 | -------------------------------------------------------------------------------- /lib/Dispatcher/Rule.pm: -------------------------------------------------------------------------------- 1 | unit class Dispatcher::Rule; 2 | has @.pattern; 3 | has @.args; 4 | 5 | has Str $.controller is rw; 6 | has Str $.action is rw; 7 | 8 | has Code $.code; 9 | 10 | method match (@chunks) { 11 | return False if @chunks != @!pattern; 12 | # RAKUDO: Z seems to have a bug (fixed in nom), where [1,2] Z [*,*] yields (1, Any, 2, Any): the Whatever is lost 13 | #for @chunks Z @!pattern -> $chunk, $rule is copy { 14 | for ^@chunks -> $i { 15 | my $chunk = @chunks[$i]; 16 | my $rule = @!pattern[$i]; 17 | #note "- chunk ({$chunk.perl}), rule ({$rule.perl})"; 18 | 19 | my $param; 20 | if $rule ~~ Pair { ($param, $rule) = $rule.kv } 21 | 22 | if ~$chunk ~~ $rule { 23 | if $param { 24 | self."$param"() = ~($/ // $chunk); 25 | } else { 26 | @!args.push($/ || $chunk) if $rule ~~ Regex | Whatever; 27 | } 28 | } 29 | else { 30 | self.clear; 31 | return False; 32 | } 33 | } 34 | return True; 35 | } 36 | 37 | method apply { 38 | # RAKUDO: die with FixedIntegerArray: index out of bounds! on test 01/3 39 | #$!code(| @!args, controller => $.controller, action => $.action ); 40 | # workaround: 41 | if $!controller and $!action { 42 | $!code(| @!args, action => $.action, controller => $.controller ); 43 | } elsif $!action { 44 | $!code(| @!args, action => $.action ); 45 | } elsif $!controller { 46 | $!code(| @!args, controller => $.controller ); 47 | } else { 48 | $!code(| @!args ); 49 | } 50 | } 51 | 52 | method is_complete { 53 | return ?( @!pattern && $!code ); 54 | } 55 | 56 | method clear { 57 | @!args = (); 58 | $!controller = Nil; 59 | $!action = Nil; 60 | } 61 | 62 | # vim:ft=perl6 63 | -------------------------------------------------------------------------------- /lib/November/Storage.pm: -------------------------------------------------------------------------------- 1 | unit class November::Storage; 2 | 3 | method wiki_page_exists($page) { ... } 4 | 5 | method read_recent_changes() { ... } 6 | method write_recent_changes($recent_changes) { ... } 7 | 8 | method read_page_history($page) { ... } 9 | method write_page_history($page, $page_history) { ... } 10 | 11 | method read_modification($modification_id) { ... } 12 | method write_modification($modification) { ... } 13 | 14 | # RAKUDO: IO::Dir::open not implemented yet, 15 | # so we use index -- workaround for all_pages 16 | method add_to_index($page) { ... } 17 | method read_index() { ... } 18 | 19 | 20 | method save_page($_: $page, $new_text, $author, $summary) { 21 | .add_to_index($page) unless .wiki_page_exists($page); 22 | my $modif_id = .write_modification([$page, $new_text, $author, $summary]); 23 | .add_page_history($page, $modif_id); 24 | .add_recent_change($modif_id); 25 | } 26 | 27 | method add_page_history ($page, $modification_id) { 28 | my $page_history = self.read_page_history($page); 29 | $page_history.unshift($modification_id); 30 | self.write_page_history($page, $page_history); 31 | } 32 | 33 | method add_recent_change($modification_id) { 34 | my $recent_changes = self.read_recent_changes(); 35 | $recent_changes.unshift($modification_id); 36 | self.write_recent_changes( $recent_changes ); 37 | } 38 | 39 | method read_page($page) { 40 | my $page_history = self.read_page_history($page); 41 | return "" unless $page_history; 42 | my $latest_change = self.read_modification( $page_history.shift ); 43 | return $latest_change[1]; 44 | } 45 | 46 | # vim:ft=perl6 47 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/view_diff.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Diff of <TMPL_VAR NAME=PAGE> 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

Diff of

15 | 16 | 17 | 18 | 19 | 20 | 23 | 26 | 27 | 28 | 29 |
21 | 22 | 24 | 25 |
30 |
31 | 42 | 43 | 44 | 49 | 50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /p5w/skins/DeleteMe/spartan.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: white; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | h1, h2, h3, h4, h5, h6 { 8 | font-family: sans-serif; 9 | } 10 | 11 | h1 { 12 | border-bottom: solid 3px #888; 13 | } 14 | 15 | #toolbar { 16 | border-bottom: solid #88f 1px; 17 | background: #ccf; 18 | padding-top: 1em; 19 | list-style: none; 20 | margin: 0; 21 | font-family: sans-serif; 22 | } 23 | 24 | #toolbar li { 25 | line-height: 1.4em; 26 | display: inline; 27 | } 28 | 29 | #toolbar a { 30 | color: black; 31 | text-decoration: none; 32 | padding: .4em 1em 0; 33 | } 34 | 35 | #toolbar a:link { background: #bbe; } 36 | #toolbar a:visited { background: #bbe; } 37 | #toolbar a:hover { background: #ffc; } 38 | #toolbar a:active { background: #cca; } 39 | 40 | #content { 41 | padding: 20px 40px 0; 42 | } 43 | 44 | .diff .insertion { 45 | border: solid 1px #080; 46 | background: #8f8; 47 | } 48 | 49 | .diff .deletion { 50 | border: solid 1px #800; 51 | background: #f88; 52 | } 53 | 54 | a.nonexistent { 55 | color: #F00; 56 | } 57 | 58 | .pagetags a, .cloud a { 59 | color: #333; 60 | } 61 | 62 | .pagetags a:hover, .cloud a:hover { 63 | color: #00c; 64 | } 65 | 66 | .cloud a { 67 | margin-right:12px; 68 | } 69 | .cloud { 70 | float:right; 71 | clear:both; 72 | line-height:1.9em; 73 | width: 200px; 74 | padding:0 0 30px 30px; 75 | } 76 | 77 | .pagetags { 78 | font-size:0.6em; 79 | margin:-12px 0 10px 0; 80 | background-image: url('/imgs/tag.png'); 81 | background-position: left bottom; 82 | background-repeat: no-repeat; 83 | } 84 | 85 | .t0 { font-size:0.7em;} 86 | .t1 { font-size:0.8em;} 87 | .t2 { font-size:0.9em;} 88 | .t2 { font-size:1.0em;} 89 | .t3 { font-size:1.1em;} 90 | .t4 { font-size:1.2em;} 91 | .t5 { font-size:1.3em;} 92 | .t6 { font-size:1.4em;} 93 | .t7 { font-size:1.5em;} 94 | .t8 { font-size:1.6em;} 95 | .t9 { font-size:1.7em;} 96 | .t10 { font-size:1.8em;} 97 | -------------------------------------------------------------------------------- /t/markup/mediawiki/05-headings.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 4; 5 | 6 | use Text::Markup::Wiki::MediaWiki; 7 | 8 | my $converter = Text::Markup::Wiki::MediaWiki.new; 9 | 10 | { 11 | my @pars = 12 | "==heading 1==", 13 | "par 1", 14 | "== heading 2 ==", 15 | "== heading 3 ==", 16 | "par 2"; 17 | my $input = join "\n\n", @pars; 18 | my $expected_output = join "\n\n", 19 | '

heading 1

', 20 | '

par 1

', 21 | '

heading 2

', 22 | '

heading 3

', 23 | '

par 2

'; 24 | my $actual_output = $converter.format($input); 25 | 26 | is( $actual_output, $expected_output, 27 | 'mixing paragraphs and headings works' ); 28 | } 29 | 30 | { 31 | # RAKUDO: heredocs 32 | my $input = '== Mr Heading == 33 | ...and immediately some paragraph text.'; 34 | my $expected_output = join "\n\n", 35 | '

Mr Heading

', 36 | '

...and immediately some paragraph text.

'; 37 | my $actual_output = $converter.format($input); 38 | 39 | is( $actual_output, $expected_output, 40 | 'really mixing paragraphs and headings works I' ); 41 | } 42 | 43 | { 44 | # RAKUDO: heredocs 45 | my $input = 'Some text. 46 | ==Mr Surprise Heading=='; 47 | my $expected_output = join "\n\n", 48 | '

Some text.

', 49 | '

Mr Surprise Heading

'; 50 | my $actual_output = $converter.format($input); 51 | 52 | is( $actual_output, $expected_output, 53 | 'really mixing paragraphs and headings works II' ); 54 | } 55 | 56 | { 57 | # RAKUDO: heredocs 58 | my $input = 'Paragraph. 59 | ==Heading== 60 | Paragraph.'; 61 | my $expected_output = join "\n\n", 62 | '

Paragraph.

', 63 | '

Heading

', 64 | '

Paragraph.

'; 65 | my $actual_output = $converter.format($input); 66 | 67 | is( $actual_output, $expected_output, 68 | 'really mixing paragraphs and headings works III' ); 69 | } 70 | 71 | # vim:ft=perl6 72 | -------------------------------------------------------------------------------- /t/uri/01.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | use Test; 3 | plan 28; 4 | 5 | use November::URI; 6 | ok(1,'We use URI and we are still alive'); 7 | 8 | my $u = November::URI.new(uri => 'http://example.com:80/about/us?foo#bar'); 9 | 10 | is($u.scheme, 'http', 'scheme'); 11 | is($u.host, 'example.com', 'host'); 12 | is($u.port, '80', 'port'); 13 | is($u.path, '/about/us', 'path'); 14 | is($u.query, 'foo', 'query'); 15 | is($u.frag, 'bar', 'frag'); 16 | is($u.chunks, 'about us', 'chunks'); 17 | is($u.chunks[0], 'about', 'first chunk'); 18 | is($u.chunks[1], 'us', 'second chunk'); 19 | 20 | is( ~$u, 'http://example.com:80/about/us?foo#bar', 21 | 'Complete path stringification'); 22 | 23 | $u = November::URI.new(uri => 'https://eXAMplE.COM'); 24 | 25 | is($u.scheme, 'https', 'scheme'); 26 | is($u.host, 'example.com', 'host'); 27 | is( "$u", 'https://example.com', 28 | 'https://eXAMplE.COM stringifies to https://example.com'); 29 | 30 | $u = November::URI.new(uri => '/foo/bar/baz'); 31 | 32 | is($u.chunks, 'foo bar baz', 'chunks from absolute path'); 33 | ok($u.absolute, 'absolute path'); 34 | nok($u.relative, 'not relative path'); 35 | 36 | $u = November::URI.new(uri => 'foo/bar/baz'); 37 | 38 | is($u.chunks, 'foo bar baz', 'chunks from relative path'); 39 | ok( $u.relative, 'relative path'); 40 | nok($u.absolute, 'not absolute path'); 41 | 42 | is($u.chunks[0], 'foo', 'first chunk'); 43 | is($u.chunks[1], 'bar', 'second chunk'); 44 | is($u.chunks[*-1], 'baz', 'last chunk'); 45 | 46 | $u = November::URI.new(uri => 'http://foo.com'); 47 | ok($u.chunks.perl eq 'Array.new("")', ".chunks return [''] for empty path"); 48 | ok($u.absolute, 'http://foo.com has an absolute path'); 49 | nok($u.relative, 'http://foo.com does not have a relative path'); 50 | 51 | # test November::URI parsing with <> or "" and spaces 52 | $u = November::URI.new(uri => " "); 53 | is("$u", 'http://foo.com', '<> removed from str'); 54 | 55 | $u = November::URI.new(uri => ' "http://foo.com"'); 56 | is("$u", 'http://foo.com', '"" removed from str'); 57 | 58 | 59 | # vim:ft=perl6 60 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/view.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <TMPL_VAR NAME=TITLE> 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

15 | 16 |
17 |
18 | 19 | 20 |
21 |

All tags

22 | 23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 | 48 | 49 | 50 | 55 | 56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /p5w/skins/LoneMountain/view.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <TMPL_VAR NAME=TITLE> 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

15 | 16 |
17 |
18 | 19 | 20 |
21 |

All tags

22 | 23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 | 48 | 49 | 50 | 55 | 56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/page_history.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | History of '<TMPL_VAR NAME=TITLE>' 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

History of ''

15 | 16 |
    17 | 18 |
  • 19 | (view) 20 | (diff) 21 | Changed on 22 | by 23 | 24 |
  • 25 |
    26 |
27 |
28 | 49 | 50 | 51 | 56 | 57 |
58 | 59 | 60 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/log_in.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Log in 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

Log in

15 |

Everything you say can, and will, be used against you. Please 16 | put on your own mask first, then help others.

17 | 18 |
19 | 20 |

Username:

21 |

Password:

22 | 23 |
24 |
25 | 46 | 47 | 48 | 53 | 54 |
55 | 56 | 57 | -------------------------------------------------------------------------------- /docs/JANITORS: -------------------------------------------------------------------------------- 1 | This is the JANITORS file, where small p5w tasks are written down so that they 2 | are not forgotten. Since the tasks are often fairly low-hanging fruit, many of 3 | them are likely to be good starting-points for volunteers. 4 | 5 | If there's an item appearing here which has already been implemented, feel 6 | free to remove it. 7 | 8 | * Find all messages on the page and replace them with sensible things. 9 | 10 | * Rethink the exact layout of the login screen. 11 | 12 | * Refine the time indications in recent changes. (Right now they are just 13 | seconds since epoch.) 14 | 15 | * Add 'return_to' links for the login and logout actions. And maybe redirects, 16 | or at least manual links. 17 | 18 | * Implement 'created new page' flag in recent-changes. 19 | 20 | * Implement 'minor edits'. 21 | 22 | * Think about the pre- and postconditions of every subroutine. For example, 23 | read_old_page currently assumes that $revision lies in the right interval 24 | (1..$latest). Implement checks so that the wiki engine never crashes from 25 | this kind of user input. Document pre- and postconditions. 26 | 27 | * Add a nice little message 'You are viewing an old revision of this page' 28 | to the view-old-revision pages. 29 | 30 | * Add nice little '<- go to previous edition' and 'go to next revision ->' 31 | to the view-old-revision pages. Provided such previous/next revisions 32 | exist, of course. 33 | 34 | * Make the CSS stylesheet adhere to a baseline grid 35 | 36 | 37 | 38 | * It would probably be a good idea to make the contents of the files in 39 | data/modifications/ hash references instead of array references. Right now, 40 | different fields are indexed by number, which is quite opaque. 41 | 42 | * Add ability to edit old revision pages. This should be accompanied by a 43 | "Warning: this is an old revision you're editing." and a link to editing 44 | the latest version of the page. 45 | 46 | * Don't save an edit unless anything is changed. 47 | 48 | * Add a 'Cancel' button to the edit form. 49 | 50 | * Consider following this advice: 51 | 52 | -------------------------------------------------------------------------------- /t/tags/update_tags.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 8; 5 | 6 | use November::Tags; 7 | 8 | use November::Config; 9 | my $config = November::Config.new( 10 | server_root => 't/tags/', 11 | ); 12 | 13 | role Testing { 14 | method clear ($_:) { 15 | my $c = {}; 16 | .write_tags_count($c); 17 | .write_tags_index($c); 18 | .write_page_tags('Test_Page', ''); 19 | .write_page_tags('Another_Page', ''); 20 | } 21 | } 22 | 23 | my $t = November::Tags.new(:$config) does Testing; 24 | $t.page_tags_path = 't/tags/data/page_tags/'; 25 | $t.tags_count_path = 't/tags/data/tags_count'; 26 | $t.tags_index_path = 't/tags/data/tags_index'; 27 | 28 | $t.clear; 29 | 30 | $t.update_tags('Test_Page', 'Foo, Bar'); 31 | 32 | is-deeply( 33 | $t.read_tags_count, 34 | {"foo" => 1, "bar" => 1}, 35 | 'Simple tag counting' 36 | ); 37 | is-deeply( 38 | $t.read_tags_index, 39 | {"foo" => ["Test_Page"], "bar" => ["Test_Page"]}, 40 | 'Simple tag indexing' 41 | ); 42 | 43 | $t.update_tags('Test_Page', 'Bar, Her'); 44 | 45 | is-deeply( 46 | $t.read_tags_count, 47 | {"bar" => 1, "her" => 1}, 48 | 'Tag count after addition and removal' 49 | ); 50 | is-deeply( 51 | $t.read_tags_index, 52 | {"foo" => [], "bar" => ["Test_Page"], "her" => ["Test_Page"]}, 53 | 'Tag index after add and remove' 54 | ); 55 | 56 | $t.update_tags('Another_Page', 'Bar, Her'); 57 | 58 | is-deeply( 59 | $t.read_tags_count, 60 | {"bar" => 2, "her" => 2}, 61 | 'Tag count after adding another page' 62 | ); 63 | is-deeply( 64 | $t.read_tags_index, 65 | { 66 | "foo" => [], 67 | "bar" => ["Test_Page", "Another_Page"], 68 | "her" => ["Test_Page", "Another_Page"] 69 | }, 70 | 'Tags index after adding another page' 71 | ); 72 | 73 | $t.update_tags('Test_Page', 'Bar, Her'); 74 | 75 | is-deeply( 76 | $t.read_tags_count, 77 | {"bar" => 2, "her" => 2}, 78 | 'Tag count after saving a page without changes'); 79 | is-deeply( 80 | $t.read_tags_index, 81 | { 82 | "foo" => [], 83 | "bar" => ["Test_Page", "Another_Page"], 84 | "her" => ["Test_Page", "Another_Page"] 85 | }, 86 | 'Tag index after save page without changes' 87 | ); 88 | 89 | $t.clear; 90 | 91 | # vim:ft=perl6 92 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/edit.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <TMPL_VAR NAME=TITLE> 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
 
13 |
14 |

15 |
16 | 17 | 18 | 19 |
20 | 21 |
22 | Tags: 23 |

24 | or cancel 25 |

26 |
27 | 48 | 49 | 50 | 55 | 56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /t/markup/mediawiki/08-formatting-and-links.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 6; 5 | todo('not yet implemented', 6); 6 | 7 | use Text::Markup::Wiki::MediaWiki; 8 | 9 | my $converter = Text::Markup::Wiki::MediaWiki.new; 10 | my $link_maker = { "$^page" } 11 | 12 | { 13 | my $input = "a[http://example.com b''c''d]e"; 14 | my $expected_output 15 | = '

abcde

'; 16 | my $actual_output = $converter.format($input, :$link_maker); 17 | 18 | is( $actual_output, $expected_output, 'italic text in a link' ); 19 | } 20 | 21 | { 22 | my $input = "a[http://example.com b''c]d"; 23 | my $expected_output 24 | = '

abcd

'; 25 | my $actual_output = $converter.format($input, :$link_maker); 26 | 27 | is( $actual_output, $expected_output, 'mismatched italic text in a link' ); 28 | } 29 | 30 | { 31 | my $input = "a[http://example.com b''''c]d"; 32 | my $expected_output 33 | = '

abcd

'; 34 | my $actual_output = $converter.format($input, :$link_maker); 35 | 36 | is( $actual_output, $expected_output, 37 | 'mismatched italic/bold text in a link' ); 38 | } 39 | 40 | { 41 | my $input = "a[http://example.com b'''c''d]e"; 42 | my $expected_output 43 | = '

abcde

'; 44 | my $actual_output = $converter.format($input, :$link_maker); 45 | 46 | is( $actual_output, $expected_output, 47 | 'mismatched bold/italic text in a link' ); 48 | } 49 | 50 | { 51 | my $input = "a''b[http://example.com c''d]e"; 52 | my $expected_output 53 | = '

abcde

'; 54 | my $actual_output = $converter.format($input, :$link_maker); 55 | 56 | is( $actual_output, $expected_output, 57 | 'in-link italic markers ignored if italic already active outside I' ); 58 | } 59 | 60 | { 61 | my $input = "a''b[http://example.com c''d''e]f"; 62 | my $expected_output 63 | = '

abcdef

'; 64 | my $actual_output = $converter.format($input, :$link_maker); 65 | 66 | is( $actual_output, $expected_output, 67 | 'in-link italic markers ignored if italic already active outside II' ); 68 | } 69 | 70 | # vim:ft=perl6 71 | -------------------------------------------------------------------------------- /t/markup/mediawiki/07-italic-and-bold.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | my @tests = 4 | [ 5 | "Oh, how I ''italicize''." => 6 | '

Oh, how I italicize.

', 7 | 'italic text works', 8 | ], 9 | 10 | [ 11 | "Doing it ''once still produces results." => 12 | "

Doing it once still produces results.

", 13 | 'malformed italic I', 14 | ], 15 | 16 | [ 17 | "But ''only until\nthe next line break." => 18 | "

But only until the next line break.

", 19 | 'malformed italic II', 20 | ], 21 | 22 | [ 23 | "Oh, how I '''embolden'''." => 24 | '

Oh, how I embolden.

', 25 | 'bold text works', 26 | ], 27 | 28 | [ 29 | "Doing it '''once still produces results." => 30 | "

Doing it once still produces results.

", 31 | 'malformed bold I', 32 | ], 33 | 34 | [ 35 | "But '''only until\nthe next line break." => 36 | "

But only until the next line break.

", 37 | 'malformed bold II', 38 | ], 39 | 40 | [ 41 | "Oh, how I '''''embolden and italizice'''''." => 42 | '

Oh, how I embolden and italizice.

', 43 | 'italic/bold text works', 44 | ], 45 | 46 | [ 47 | "a''b'''c'''d''e" => 48 | '

abcde

', 49 | 'nested italic/bold I', 50 | ], 51 | 52 | [ 53 | "a'''b''c''d'''e" => 54 | '

abcde

', 55 | 'nested italic/bold II', 56 | ], 57 | 58 | [ 59 | "Doing it '''''once still produces results." => 60 | "

Doing it once still produces results.

", 61 | 'malformed italic/bold I', 62 | ], 63 | 64 | [ 65 | "But '''''only until\nthe next line break." => 66 | "

But only until the next line break.

", 67 | 'malformed italic/bold II', 68 | ], 69 | 70 | [ 71 | "a''b'''c''d'''e" => 72 | '

abcde

', 73 | 'mis-nested italic/bold I', 74 | ], 75 | 76 | [ 77 | "a'''b''c'''d''e" => 78 | '

abcde

', 79 | 'mis-nested italic/bold II', 80 | ], 81 | 82 | [ 83 | "a'''b''c\nd" => 84 | '

abc d

', 85 | 'mis-nested italic/bold III', 86 | ], 87 | ; 88 | 89 | # RAKUDO: Doesn't respect "use Test :EXPORT" 90 | use Test; 91 | use Test::InputOutput; 92 | plan +@tests; 93 | 94 | use Text::Markup::Wiki::MediaWiki; 95 | 96 | my $converter = Text::Markup::Wiki::MediaWiki.new; 97 | Test::InputOutput.using( { $converter.format($^input) } ).test(@tests); 98 | 99 | # vim:ft=perl6 100 | -------------------------------------------------------------------------------- /lib/Text/Markup/Wiki/Minimal.pm: -------------------------------------------------------------------------------- 1 | unit class Text::Markup::Wiki::Minimal; 2 | 3 | method format($text, :$link_maker, :$extlink_maker) { 4 | my @pars = grep { $_ ne "" }, 5 | map { $_.subst( / ^ \n /, '' ) }, 6 | $text.split( /\n\n/ ); 7 | 8 | my @formatted; 9 | for @pars -> $par { 10 | 11 | my $result; 12 | use Text::Markup::Wiki::Minimal::Grammar; 13 | Text::Markup::Wiki::Minimal::Grammar.parse($par); 14 | 15 | if $/ { 16 | 17 | if $/ { 18 | my $heading = ~$/[0]; 19 | $heading .= subst( / ^ \s+ /, '' ); 20 | $heading .= subst( / \s+ $ /, '' ); 21 | $result = "

{$heading}

"; 22 | } 23 | else { 24 | $result = '

'; 25 | 26 | for $/.list { 27 | if $_ { 28 | $result ~= $_; 29 | } 30 | elsif $_ { 31 | if defined $link_maker { 32 | # RAKUDO: second arg transform to '1' by some dark magic 33 | # $result ~= $link_maker( ~$_, ~$_ ); 34 | # workaround: 35 | my $title = $_; 36 | 37 | $result ~= $link_maker( ~$_, $title ); 38 | } 39 | else { 40 | $result ~= $_; 41 | } 42 | } 43 | elsif $_ { 44 | $result ~= quote($_) 45 | } 46 | elsif $_ { 47 | $result ~= $_ 48 | } 49 | } 50 | $result ~= "

"; 51 | } 52 | } 53 | else { 54 | $result = '

Could not parse paragraph.

'; 55 | } 56 | 57 | push @formatted, $result; 58 | } 59 | 60 | return join "\n\n", @formatted; 61 | } 62 | 63 | sub quote($metachar) { 64 | # RAKUDO: Chained trinary operators do not do what we mean yet. 65 | return ''' if $metachar eq '\''; 66 | return '<' if $metachar eq '<'; 67 | return '>' if $metachar eq '>'; 68 | return '&' if $metachar eq '&'; 69 | return $metachar; 70 | } 71 | 72 | 73 | # vim:ft=perl6 74 | -------------------------------------------------------------------------------- /t/cgi/01-cgi.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 22; 5 | 6 | use November::CGI; 7 | ok(1,'We use November::CGI and we are still alive'); 8 | 9 | my $cgi; 10 | $cgi = November::CGI.new(); 11 | ok( $cgi ~~ November::CGI, 'an instance is of the right class'); 12 | 13 | my @queries = ( 14 | 'test=', 15 | { :test('') } , 16 | 'test=1', 17 | { :test('1') }, 18 | 'test=2¶ms=2', 19 | { :test('2'), :params('2') }, 20 | 'test=3¶ms=3&words=first+second', 21 | { :test('3'), :params('3') :words('first second') }, 22 | 'test=4¶ms=3&words=first+%41+second', 23 | { :test('4'), :params('3') :words('first A second') }, 24 | 'test=5¶ms=3&words=first%0Asecond', 25 | { :test('5'), :params('3') :words("first\nsecond") }, 26 | 'test=foo&test=bar', 27 | { test => [] }, 28 | 'test=2;params=2', 29 | { :test('2'), :params('2') }, 30 | 'test=3;params=3;words=first+second', 31 | { :test('3'), :params('3'), :words('first second') }, 32 | 'test=4;params=3&words=first+%41+second', 33 | { :test('4'), :params('3'), :words('first A second') }, 34 | ); 35 | 36 | for @queries -> $in, $expected { 37 | my $c = November::CGI.new(); 38 | $c.parse_params($in); 39 | is-deeply($c.params, $expected, 'Parse param: ' ~ $in); 40 | } 41 | 42 | my @keywords = ( 43 | 'foo', 44 | ['foo'], 45 | 'foo+bar+her', 46 | ['foo','bar','her'], 47 | ); 48 | 49 | for @keywords -> $in, $expected { 50 | $cgi.parse_params($in); 51 | is-deeply($cgi.keywords, $expected , 'Parse param (keywords): ' ~ $in); 52 | } 53 | 54 | $cgi = November::CGI.new(); 55 | 56 | my @add_params = ( 57 | :key1 , { :key1 }, 58 | :key2 , { :key1, :key2 }, 59 | :key1, { key1 => [], :key2 }, 60 | :key3<4> , { key1 => [], :key2, :key3<4> }, 61 | :key4<4.1> , { key1 => [], :key2, :key3<4>, :key4<4.1> }, 62 | 63 | # Do not consistency :( but we don`t have adverbial syntax to set pairs 64 | # with undefined value 65 | # see http://www.nntp.perl.org/group/perl.perl6.language/2008/09/msg29610.html 66 | # Skip now, because is-deeply do not work properly with Mu :( 67 | #key2 => Mu , { :key1, key2 => ["val", Mu], :key3<4>, :key4<4.1> }, 68 | ); 69 | 70 | for @add_params -> $in, $expected { 71 | my $key = $in.key; 72 | my $val = $in.value; 73 | $cgi.add_param($key, $val); 74 | is-deeply( $cgi.params, $expected, "Add kv: :{$key}<" ~ ($val or '') ~ ">" ); 75 | } 76 | 77 | is( $cgi.param('key3'), '4', 'Test param' ); 78 | 79 | my @cookies = ( 80 | 'foo=bar', 81 | { :foo('bar') }, 82 | 'foo=bar; bar=12.20', 83 | { :foo('bar') :bar('12.20') }, 84 | ); 85 | 86 | for @cookies -> $in, $expected { 87 | $cgi.eat_cookie($in); 88 | is-deeply($cgi.cookie, $expected, 'Parse cookies: ' ~ $in); 89 | } 90 | 91 | # vim:ft=perl6 92 | 93 | -------------------------------------------------------------------------------- /skins/Autumn/spartan.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: white; 3 | margin: 0; 4 | padding: 0; 5 | line-height:1.5em; 6 | } 7 | 8 | h1, h2, h3, h4, h5, h6 { 9 | font-family: sans-serif; 10 | } 11 | 12 | h1 { 13 | font-size:2em; /* 32px */ 14 | line-height:1.25em; /* 45px */ 15 | border-bottom: solid 3px #888; 16 | } 17 | 18 | h3 { 19 | font-size:1.125em; /* 18px */ 20 | margin:1em 0 0.5625em 0; 21 | color:#330; 22 | } 23 | 24 | #toolbar { 25 | border-bottom: solid #330 2px; 26 | background: #863; 27 | padding-top: 1em; 28 | list-style: none; 29 | margin: 0; 30 | font-family: sans-serif; 31 | } 32 | 33 | #toolbar li { 34 | line-height: 1.4em; 35 | display: inline; 36 | } 37 | 38 | #toolbar a { 39 | color: black; 40 | text-decoration: none; 41 | padding: .4em 1em 0; 42 | } 43 | 44 | #toolbar a:link { background: #dc8; } 45 | #toolbar a:visited { background: #dc8; } 46 | #toolbar a:hover { background: #ee8; } 47 | #toolbar a:active { background: #ffa; } 48 | 49 | #logo { 50 | position: absolute; 51 | top: 5px; 52 | right: 35px; 53 | background: no-repeat 100% 0% url(november-logo.png); 54 | width: 70px; 55 | height: 70px; 56 | } 57 | 58 | #content { 59 | padding: 1.4em 40px 0; 60 | margin-right:284px; 61 | } 62 | 63 | .diff .insertion { 64 | border: solid 1px #080; 65 | background: #8f8; 66 | } 67 | 68 | .diff .deletion { 69 | border: solid 1px #800; 70 | background: #f88; 71 | } 72 | 73 | a.nonexistent { 74 | color: #F00; 75 | } 76 | 77 | .block-right { 78 | float:right; 79 | clear:both; 80 | margin: 1.5625em 40px 0px 20px; 81 | border: 2px solid #863; 82 | 83 | width: 200px; 84 | padding:0 20px 20px 20px; 85 | } 86 | .space-top-h1 { 87 | margin-top:5.1875em /* 83px */ 88 | } 89 | 90 | .list-simple { 91 | margin:0; padding:0; 92 | list-style:none; 93 | } 94 | 95 | .list-simple li { 96 | margin-bottom:0.3em; 97 | } 98 | 99 | /* Tags 100 | ----------------------------------------------*/ 101 | .pagetags a, .cloud a { 102 | color: #333; 103 | } 104 | 105 | .pagetags a:hover, .cloud a:hover { 106 | color: #00c; 107 | } 108 | 109 | .cloud { 110 | line-height:1.8em; 111 | } 112 | 113 | 114 | .cloud a { 115 | margin-right:12px; 116 | } 117 | 118 | .pagetags { 119 | font-size:0.8em; 120 | margin-top:-12px; 121 | padding-left:22px; 122 | /* TODO: need WEBROOT here? */ 123 | background-image: url('/skins/Autumn/images/tag.png'); 124 | background-position: left bottom; 125 | background-repeat: no-repeat; 126 | } 127 | 128 | .t0 { font-size:0.7em;} 129 | .t1 { font-size:0.8em;} 130 | .t2 { font-size:0.9em;} 131 | .t2 { font-size:1.0em;} 132 | .t3 { font-size:1.1em;} 133 | .t4 { font-size:1.2em;} 134 | .t5 { font-size:1.3em;} 135 | .t6 { font-size:1.4em;} 136 | .t7 { font-size:1.5em;} 137 | .t8 { font-size:1.6em;} 138 | .t9 { font-size:1.7em;} 139 | .t10 { font-size:1.8em;} 140 | 141 | -------------------------------------------------------------------------------- /lib/November/Storage/File.pm: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use November::Storage; 4 | use November::Utils; 5 | use MONKEY-SEE-NO-EVAL; 6 | 7 | class November::Storage::File is November::Storage { 8 | 9 | has $.storage_root is rw; 10 | #my $r = $.config.server_root; 11 | 12 | # RAKUDO: initial attr value do not fully works 13 | # given November::Config.server_root { # and use $_ inside. 14 | # But we can`t do that now because "my". 15 | has $.content_path is rw; # = $r ~ 'data/articles/'; 16 | has $.modifications_path is rw; # = $r ~ 'data/modifications/'; 17 | has $.recent_changes_path is rw; # = $r ~ 'data/recent-changes'; 18 | has $.index_path is rw; # = $r ~ 'data/index'; 19 | 20 | submethod BUILD(:$storage_root) { 21 | $!storage_root = $storage_root; 22 | 23 | $!content_path = $!storage_root ~ 'articles/'; 24 | $!modifications_path = $!storage_root ~ 'modifications/'; 25 | $!recent_changes_path = $!storage_root ~ 'recent-changes'; 26 | $!index_path = $!storage_root ~ 'index'; 27 | } 28 | 29 | method wiki_page_exists($page) { 30 | return ($.content_path ~ $page).IO ~~ :e; 31 | } 32 | 33 | method read_recent_changes { 34 | return [] unless $.recent_changes_path.IO ~~ :e; 35 | return EVAL( slurp( $.recent_changes_path ) ); 36 | } 37 | 38 | method write_recent_changes ($recent_changes) { 39 | my $fh = open($.recent_changes_path, :w); 40 | $fh.say($recent_changes.perl); 41 | $fh.close; 42 | } 43 | 44 | method read_page_history($page) { 45 | my $file = $.content_path ~ $page; 46 | return [] unless $file.IO ~~ :e; 47 | my $page_history = EVAL( slurp($file) ); 48 | return $page_history; 49 | } 50 | 51 | method write_page_history($page, $page_history) { 52 | my $file = $.content_path ~ $page; 53 | my $fh = open($file, :w); 54 | $fh.say( $page_history.perl ); 55 | $fh.close; 56 | } 57 | 58 | method read_modification($modification_id) { 59 | my $file = $.modifications_path ~ $modification_id; 60 | return [] unless $file.IO ~~ :e; 61 | return EVAL( slurp($file) ); 62 | } 63 | 64 | method write_modification ($modification) { 65 | my $modif = $modification; 66 | $modif.push(time.Int); 67 | my $data = $modif.perl; 68 | r_remove($data); 69 | 70 | my $modification_id = get_unique_id; 71 | 72 | my $file = $.modifications_path ~ $modification_id; 73 | my $fh = open( $file, :w ); 74 | $fh.say( $data ); 75 | $fh.close(); 76 | 77 | return $modification_id; 78 | } 79 | 80 | method add_to_index ($page) { 81 | my $index = self.read_index; 82 | # RAKUDO: @ $index not impemented yet :( 83 | # unless any( @ $index) eq $page { 84 | unless any($index.values) eq $page { 85 | $index.push($page); 86 | my $fh = open($.index_path, :w); 87 | $fh.say($index.perl); 88 | $fh.close; 89 | } 90 | } 91 | 92 | method read_index { 93 | return EVAL( slurp($.index_path) ); 94 | } 95 | } 96 | 97 | # vim:ft=perl6 98 | -------------------------------------------------------------------------------- /docs/blog-posts.md: -------------------------------------------------------------------------------- 1 | * [Step 1 on the road to recovery: admitting you have a problem](http://use.perl.org/~masak/journal/40280) 2 | * [Some module names don't deserve to be short](http://use.perl.org/~masak/journal/40008) 3 | * [November 18 2009 -- the history mystery](http://use.perl.org/~masak/journal/39915) 4 | * [November 16 2009 -- digging into some real paperwork](http://use.perl.org/~masak/journal/39906) 5 | * [November 15 2009 -- money gets inflated, time gets deflated](http://use.perl.org/~masak/journal/39901) 6 | * [November 11 2009 -- nobody said it was going to be easy](http://use.perl.org/~masak/journal/39884) 7 | * [November 4 2009 -- no log in for you!](http://use.perl.org/~masak/journal/39843) 8 | * [November 2 2009 -- fighting servers and giant squids](http://use.perl.org/~masak/journal/39833) 9 | * [November 1 2009 -- a somewhat shaky start](http://use.perl.org/~masak/journal/39826) 10 | * [Here we go again; another full month of November](http://use.perl.org/~masak/journal/39825) 11 | * [November won a prize](http://use.perl.org/~masak/journal/38601) 12 | * [That was the month that was](http://use.perl.org/~masak/journal/38033) 13 | * [November 30, 2008 -- improvements](http://use.perl.org/~masak/journal/37988) 14 | * [November 29, 2008 -- "I will call it 'the graphophone'!"](http://use.perl.org/~masak/journal/37976) 15 | * [November 28, 2008 -- "...take thee, Annam Whatley..."](http://use.perl.org/~masak/journal/37969) 16 | * [November 25, 2008 -- the lexbug of death is dead](http://use.perl.org/~masak/journal/37944) 17 | * [November 24, 2008 -- evolving things](http://use.perl.org/~masak/journal/37935) 18 | * [November 23, 2008 -- the rite to write](http://use.perl.org/~masak/journal/37927) 19 | * [November 21, 2008 -- a torrent of things](http://use.perl.org/~masak/journal/37922) 20 | * [November 20, 2008 -- fifty thousand orbits around the Earth](http://use.perl.org/~masak/journal/37914) 21 | * [November 19, 2008 -- things to keep in mind](http://use.perl.org/~masak/journal/37908) 22 | * [November 18, 2008 -- of mice and babies](http://use.perl.org/~masak/journal/37903) 23 | * [November 17, 2008 -- it's a small step for a robotic dog...](http://use.perl.org/~masak/journal/37899) 24 | * [November 16, 2008 -- the right man for the job](http://use.perl.org/~masak/journal/37892) 25 | * [November 14, 2008 -- pioneers](http://use.perl.org/~masak/journal/37877) 26 | * [November 13, 2008 -- the storm after the storm](http://use.perl.org/~masak/journal/37871) 27 | * [November 11, 2008 -- the calm after the storm](http://use.perl.org/~masak/journal/37857) 28 | * [November 9, 2008 -- developing code is like baking bread](http://use.perl.org/~masak/journal/37837) 29 | * [November 8, 2008 -- the joys of discovery](http://use.perl.org/~masak/journal/37832) 30 | * [November 5, 2008 -- remember, remember](http://use.perl.org/~masak/journal/37812) 31 | * [November 3, 2008 -- today is Skin Monday!](http://use.perl.org/~masak/journal/37799) 32 | * [November 2, 2008 -- one step forward, two steps back](http://use.perl.org/~masak/journal/37787) 33 | * [A full month of November](http://use.perl.org/~masak/journal/37773) 34 | * [Nonlinear development history](http://use.perl.org/~masak/journal/37721) 35 | * [I'll call you back](http://use.perl.org/~masak/journal/37529) 36 | * [Comments](http://use.perl.org/~masak/journal/37341) 37 | * [Lovely patchers](http://use.perl.org/~masak/journal/37340) 38 | * [November meets the Web](http://use.perl.org/~masak/journal/37263) 39 | * [Announcing November, a wiki in Perl 6](http://use.perl.org/~masak/journal/37212) 40 | -------------------------------------------------------------------------------- /lib/November/URI.pm: -------------------------------------------------------------------------------- 1 | unit class November::URI; 2 | 3 | # This class used to be called just 'URI', but there was a collision with 4 | # the eponymous class in the 'uri' project. Arguably, that class has more 5 | # rights to that name, so this one was renamed. Since the 'uri' project 6 | # ought to cover the same functionality as this class, maybe long-term we 7 | # could switch to using that instead. One more dependency, but less code 8 | # duplication across projects. 9 | 10 | use November::URI::Grammar; 11 | # RAKUDO: Match object does not do assignment properly :( 12 | #my Match $.parts; dies in init with 'Type mismatch in assignment'; 13 | # workaround: 14 | has $.uri; 15 | has @.chunks; 16 | 17 | submethod BUILD(:$uri) { 18 | 19 | # clear string before parsing 20 | my $c_str = $uri; 21 | $c_str .= subst(/^ \s* ['<' | '"'] /, ''); 22 | $c_str .= subst(/ ['>' | '"'] \s* $/, ''); 23 | 24 | November::URI::Grammar.parse($c_str); 25 | unless $/ { die "Could not parse URI: $uri" } 26 | 27 | $!uri = $/; 28 | @!chunks = @($) || (''); 29 | } 30 | 31 | method scheme { 32 | my $s = $.uri || ''; 33 | # RAKUDO: return 1 if use ~ below die because can`t do lc on Math after 34 | return ~$s.lc; 35 | } 36 | 37 | method authority { 38 | my $a = $.uri || ''; 39 | # RAKUDO: return 1 if use ~ below die because can`t do lc on Math after 40 | return ~$a.lc; 41 | } 42 | 43 | method host { 44 | #RAKUDO: $.uri[0] return full now 45 | my $h = ~$.uri; 46 | return $h.lc || ''; 47 | } 48 | 49 | method port { 50 | # TODO: send rakudobug 51 | # RAKUDO: $.uri return full now 52 | # workaround: 53 | item $.uri || ''; 54 | } 55 | 56 | method path { 57 | my $p = ~$.uri || ''; 58 | return $p.lc; 59 | } 60 | 61 | method absolute { 62 | # RAKUDO: The grammar uses ?, so this should be either Nil or a 63 | # Match object. But Rakudo returns [] or [Match] instead, so we must use 64 | # || instead of // to test. 65 | return ?($.uri || $.scheme); 66 | } 67 | 68 | method relative { 69 | # Rakudo: Must use || instead of //, see above. 70 | return !($.uri || $.scheme); 71 | } 72 | 73 | method query { 74 | item $.uri || ''; 75 | } 76 | method frag { 77 | my $f = $.uri || ''; 78 | return ~$f.lc; 79 | } 80 | 81 | method fragment { $.frag } 82 | 83 | method Str() { 84 | my $str; 85 | $str ~= $.scheme if $.scheme; 86 | $str ~= '://' ~ $.authority if $.authority; 87 | $str ~= $.path; 88 | $str ~= '?' ~ $.query if $.query; 89 | $str ~= '#' ~ $.frag if $.frag; 90 | return $str; 91 | } 92 | 93 | 94 | =begin pod 95 | 96 | =head NAME 97 | 98 | November::URI — Uniform Resource Identifiers (absolute and relative) 99 | 100 | =head SYNOPSYS 101 | 102 | use November::URI; 103 | my $u = November::URI.new; 104 | $u.init('http://example.com/foo/bar?tag=woow#bla'); 105 | 106 | my $scheme = $u.scheme; 107 | my $authority = $u.authority; 108 | my $host = $u.host; 109 | my $port = $u.port; 110 | my $path = $u.path; 111 | my $query = $u.query; 112 | my $frag = $u.frag; # or $u.fragment; 113 | 114 | my $is_absolute = $u.absolute; 115 | my $is_relative = $u.relative; 116 | 117 | =end pod 118 | 119 | 120 | # vim:ft=perl6 121 | -------------------------------------------------------------------------------- /t/markup/mediawiki/06-links.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 11; 5 | 6 | use Text::Markup::Wiki::MediaWiki; 7 | 8 | my $converter = Text::Markup::Wiki::MediaWiki.new; 9 | my $link_maker = { 10 | my $l = $^page.tc; 11 | my $t = $^title // $^page; 12 | $l .= subst(' ', '_', :g); 13 | qq[{$t}]; 14 | } 15 | my $extlink_maker = -> $href, $title { 16 | qq[{$title}] 17 | } 18 | 19 | { 20 | my $input = 'An example of a [[link]]'; 21 | my $expected_output 22 | = '

An example of a link

'; 23 | my $actual_output = $converter.format($input, :$link_maker); 24 | 25 | is( $actual_output, $expected_output, '[[link]] conversion works' ); 26 | } 27 | 28 | { 29 | my $input = 'An example of a [[ link ]]'; 30 | my $expected_output 31 | = '

An example of a link

'; 32 | my $actual_output = $converter.format($input, :$link_maker); 33 | 34 | is( $actual_output, $expected_output, '[[ link ]] conversion works' ); 35 | } 36 | 37 | { 38 | my $input = 'An example of a [[link]]'; 39 | my $expected_output = '

An example of a [[link]]

'; 40 | my $actual_output = $converter.format($input); 41 | 42 | is( $actual_output, $expected_output, 'no link maker, no conversion' ); 43 | } 44 | 45 | { 46 | my $input = 'An example of a [[malformed link'; 47 | my $expected_output = '

An example of a [[malformed link

'; 48 | my $actual_output = $converter.format($input, :$link_maker); 49 | 50 | is( $actual_output, $expected_output, 'malformed link I' ); 51 | } 52 | 53 | { 54 | my $input = 'An example of a malformed link]]'; 55 | my $expected_output = '

An example of a malformed link]]

'; 56 | my $actual_output = $converter.format($input, :$link_maker); 57 | 58 | is( $actual_output, $expected_output, 'malformed link II' ); 59 | } 60 | 61 | { 62 | my $input = "[[A Link\nSpanning Two Lines]]"; 63 | my $expected_output = '

[[A Link Spanning Two Lines]]

'; 64 | my $actual_output = $converter.format($input, :$link_maker); 65 | 66 | is( $actual_output, $expected_output, 'malformed link III' ); 67 | } 68 | 69 | { 70 | my $input = "[[Link with spaces]]"; 71 | my $expected_output = '

Link with spaces

'; 72 | my $actual_output = $converter.format($input, :$link_maker); 73 | 74 | is( $actual_output, $expected_output, 'link with spaces' ); 75 | } 76 | 77 | { 78 | my $input = 'This is an [http://example.com] external link'; 79 | my $expected_output 80 | = '

This is an http://example.com ' 81 | ~ 'external link

'; 82 | my $actual_output = $converter.format($input, :$extlink_maker); 83 | 84 | is( $actual_output, $expected_output, 'external link I' ); 85 | } 86 | 87 | { 88 | my $input = 'This is an [ http://example.com ] external link'; 89 | my $expected_output 90 | = '

This is an http://example.com ' 91 | ~ 'external link

'; 92 | my $actual_output = $converter.format($input, :$extlink_maker); 93 | 94 | is( $actual_output, $expected_output, 'external link I with whatespaces' ); 95 | } 96 | 97 | { 98 | my $input = 'This is an [http://example.com external link with a title]'; 99 | my $expected_output 100 | = '

This is an external link with a ' 101 | ~ 'title

'; 102 | my $actual_output = $converter.format($input, :$extlink_maker); 103 | 104 | is( $actual_output, $expected_output, 'external link II' ); 105 | } 106 | 107 | { 108 | my $input = 'This is an [http://example.com] external link'; 109 | my $expected_output = "

{$input}

"; 110 | my $actual_output = $converter.format($input); 111 | 112 | is( $actual_output, $expected_output, 'no extlink maker, no conversion' ); 113 | } 114 | 115 | # vim:ft=perl6 116 | -------------------------------------------------------------------------------- /skins/CleanAndSoft/november_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 23 | 30 | 31 | 53 | 57 | 58 | 60 | 61 | 63 | image/svg+xml 64 | 66 | 67 | 68 | 69 | 73 | November 86 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /p5w/skins/CleanAndSoft/november_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 23 | 30 | 31 | 53 | 57 | 58 | 60 | 61 | 63 | image/svg+xml 64 | 66 | 67 | 68 | 69 | 73 | November 86 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /docs/FEATURES: -------------------------------------------------------------------------------- 1 | This is the FEATURES file, which lists the things the two implementations can 2 | do, along with the date the feature was implemented. The file is divided into 3 | three sections of decreasing feature importance. 4 | 5 | (There's also a JANITORS file, for desired smaller-than-feature changes and 6 | additions. Additionally, there's a LOOKINTO file, with possibly worthwhile 7 | not-yet-features to be investigated.) 8 | 9 | == Essential features ======================================================== 10 | (without which not even we would consider it a wiki) 11 | 12 | p5w | p6w 13 | -----------------------------------------------------------------+------------ 14 | * Linking . . . . . . . . . . . . . . . . . . . . . [2008-06-28] | [2008-07-30] 15 | * Editing . . . . . . . . . . . . . . . . . . . . . [2008-07-02] | [2008-08-13] 16 | -----------------------------------------------------------------+------------ 17 | 18 | == Important features ======================================================== 19 | (without which other people might not consider it a wiki) 20 | 21 | p5w | p6w 22 | -----------------------------------------------------------------+------------ 23 | * Creating new pages (without resorting to URL | 24 | rewriting). . . . . . . . . . . . . . . . . . . . [2008-07-02] | [2008-07-30] 25 | | 26 | * User authentication . . . . . . . . . . . . . . . [2008-08-07] | [2008-08-13] 27 | * Logging in logging out. . . . . . . . . . . . . . [2008-08-07] | [2008-08-13] 28 | | 29 | | 30 | * The concept of a user authoring an edit . . . . . [2008-08-07] | [2008-08-14] 31 | | 32 | * Collision prevention -- preventing an | 33 | edit on an old article from going through . . . . [2009-03-31] | not yet 34 | | 35 | * Article history . . . . . . . . . . . . . . . . . [2008-08-10] | not yet 36 | ** Ability to view old revisions of pages . . . . . [2008-08-10] | not yet 37 | ** Diffs between consecutive revisions. . . . . . . [2008-08-11] | not yet 38 | ** Diffs between arbritary revisions. . . . . . . . not yet | 39 | | 40 | * Recent changes. . . . . . . . . . . . . . . . . . [2008-07-02] | [2008-08-15] 41 | | 42 | * Images (and other files). . . . . . . . . . . . . not yet | 43 | | 44 | * Text formatting . . . . . . . . . . . . . . . . . [2008-08-23] | [2008-07-30] 45 | | 46 | * Unicode support . . . . . . . . . . . . . . . . . not yet | 47 | | 48 | * A decent default CSS layout . . . . . . . . . . . [2008-07-31] | [2008-08-14] 49 | ** Pluggable layouts. . . . . . . . . . . . . . . . [2008-11-03] | [2009-01-20] 50 | -----------------------------------------------------------------+------------ 51 | 52 | == Desirable features ======================================================== 53 | (without which the wiki is still manageable, but maybe less enjoyable) 54 | 55 | p5w | p6w 56 | -----------------------------------------------------------------+------------ 57 | * Contents (summarizing headings in the article). . not yet | 58 | | 59 | * Good merging when conflicts occur . . . . . . . . not yet | 60 | | 61 | * A plug-in system, so that formatting capabilities | 62 | can be extended by the wiki owner . . . . . . . . not yet | 63 | | 64 | * RSS/Atom feeds | 65 | ** ...for site-wide recent changes. . . . . . . . . not yet | 66 | ** ...for individual pages. . . . . . . . . . . . . not yet | 67 | ** ...for a group of pages subscribed to by a user. not yet | 68 | -----------------------------------------------------------------+------------ 69 | -------------------------------------------------------------------------------- /t/markup/minimal/06-links.t: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | use Test; 4 | plan 11; 5 | 6 | use Text::Markup::Wiki::Minimal; 7 | my $converter = Text::Markup::Wiki::Minimal.new( link_maker => &make_link); 8 | 9 | { 10 | my $input = 'An example of a [[link]]'; 11 | my $expected_output 12 | = '

An example of a link

'; 13 | my $actual_output = $converter.format($input, :link_maker(&make_link) ); 14 | 15 | is( $actual_output, $expected_output, 'link conversion works' ); 16 | } 17 | 18 | { 19 | my $input = 'An example of a [[ link ]]'; 20 | my $expected_output 21 | = '

An example of a link

'; 22 | my $actual_output = $converter.format($input, :link_maker(&make_link)); 23 | 24 | is( $actual_output, $expected_output, 'link conversion works' ); 25 | } 26 | 27 | { 28 | my $input = 'An example of a [[link]]'; 29 | my $expected_output 30 | = '

An example of a [[link]]

'; 31 | #my $converter = Text::Markup::Wiki::Minimal.new; 32 | my $actual_output = $converter.format($input); 33 | 34 | is( $actual_output, $expected_output, 'link conversion works' ); 35 | } 36 | 37 | { 38 | my $input = 'An example of a [[malformed link'; 39 | my $expected_output = '

An example of a [[malformed link

'; 40 | my $actual_output = $converter.format($input, :link_maker(&make_link)); 41 | 42 | is( $actual_output, $expected_output, 'malformed link I' ); 43 | } 44 | 45 | { 46 | my $input = 'An example of a malformed link]]'; 47 | my $expected_output = '

An example of a malformed link]]

'; 48 | my $actual_output = $converter.format($input, :link_maker(&make_link)); 49 | 50 | is( $actual_output, $expected_output, 'malformed link II' ); 51 | } 52 | 53 | { 54 | my $input = 'An example of a [[My_Page]]'; 55 | my $expected_output 56 | = '

An example of a My_Page

'; 57 | my $actual_output = $converter.format($input, :link_maker(&make_link)); 58 | 59 | is( $actual_output, $expected_output, 'My_Page' ); 60 | } 61 | 62 | { 63 | my $input = 'An example of a [[link boo]]'; 64 | my $expected_output 65 | = '

An example of a boo

'; 66 | my $actual_output = $converter.format($input, :link_maker(&make_link)); 67 | 68 | is( $actual_output, $expected_output, 'named link' ); 69 | } 70 | 71 | { 72 | my $input = 'An example of a [[http://link.org boo]]'; 73 | my $expected_output 74 | = '

An example of a boo

'; 75 | my $actual_output = $converter.format($input, :link_maker(&make_link)); 76 | 77 | is( $actual_output, $expected_output, 'named external link' ); 78 | } 79 | 80 | { 81 | my $input = 'and [[http://link.org/foo-12_0.pod foo-pod 12]]'; 82 | my $expected_output 83 | = '

and foo-pod 12

'; 84 | my $actual_output = $converter.format($input, :link_maker(&make_link)); 85 | 86 | is( $actual_output, $expected_output, 87 | 'named external link with digets and dot' ); 88 | } 89 | 90 | { 91 | my $input = 'An example of a [[http://link.org boo bar baz]]'; 92 | my $expected_output 93 | = '

An example of a boo bar baz

'; 94 | my $actual_output = $converter.format($input, :link_maker(&make_link)); 95 | 96 | is( $actual_output, $expected_output, 'named (long name) external link' ); 97 | } 98 | 99 | { 100 | my $input = 'An example of a [[mailto:forihrd@gmail.com ihrd]]'; 101 | my $expected_output 102 | = '

An example of a ihrd

'; 103 | my $actual_output = $converter.format($input, :link_maker(&make_link)); 104 | 105 | is( $actual_output, $expected_output, 'mailto' ); 106 | } 107 | 108 | sub make_link($page, $title?) { 109 | if $title { 110 | if $page ~~ m/':'/ { 111 | return "{$title}"; 112 | } else { 113 | return "{$title}"; 114 | } 115 | 116 | } else { 117 | return sprintf('%s', 118 | wiki_page_exists($page) 119 | ?? ('view', $page, '') 120 | !! ('edit', $page, ' class="nonexistent"'), 121 | $page); 122 | } 123 | } 124 | 125 | sub wiki_page_exists ($page) { 126 | if $page ~~ 'link'|'foo'|'My_Page' { 127 | return True; 128 | } 129 | 130 | return False; 131 | } 132 | 133 | # vim:ft=perl6 134 | -------------------------------------------------------------------------------- /data/modifications/404869.874449968338: -------------------------------------------------------------------------------- 1 | ["Main_Page", "Hi there. November is a wiki engine written in Perl 6, and runs on top of Rakudo. It currently does viewing/editing of pages, tags and sessions.\n\nPages are written in a simple wiki markup, and parsed using a Perl 6 grammar. This grammar is used to produce links, for example to [[Another_Page]]. A link to a [[Page_that_does_not_exist]] is shown in red, and clicking it takes you into edit mode for that page.\n\n== What is Perl? ==\n\n[[http://www.perl.org/about.html Perl]] is a dynamic programming language with tendencies towards expressivity rather than minimalism. One of its central tenets being that [[http://en.wikipedia.org/wiki/There_is_more_than_one_way_to_do_it There Is More Than One Way To Do It]], Perl accommodates a many-cultured assortment of solutions to common programming problems. Through [[http://use.perl.org/ various]] [[http://www.perlmonks.org/ fora]], a well-written [[http://perldoc.perl.org/ core documentation]], and a central repository of thousands of [[http://search.cpan.org/ modules]], Perl culture is constantly being passed on and added to.\n\n== What is Perl 6? ==\n\n\"Perl 5 was my rewrite of Perl. I want Perl 6 to be the community's rewrite of Perl and of the community.\" - Larry Wall\n\nSince the year 2000, [[http://perl.net.au/wiki/Perl_6 Perl 6]] has been in the making. The process of arriving at a full implementation of the language has taken a long time; not least because the [[http://www.parrotcode.org/ Parrot]] virtual machine and its assorted tool chain needed to be built to host the language. Even the design process itself has [[http://perlcabal.org/syn/ evolved]] and [[http://www.nntp.perl.org/group/perl.perl6.language/ matured]] during this time. Perl 6 is a fresh redesign of Perl, throwing away unfortunate design elements that have accrued - not only in Perl, but in the language design field in general - while keeping the good parts and throwing in some new gems as well.\n\n\"Our unofficial slogan is: Perl 6: second-system syndrome done right.\" - Larry Wall\n\n== Why use Perl 6? ==\n\nPeople who have experience with Perl 5 might ask themselves what they have to gain from using Perl 6. Here's what we believe are the advantages:\n\n* At the early stages of development, Perl 6 allows for rapid prototyping and fluent experimentation.\n\n* As the application matures, the [[http://perlcabal.org/syn/S12.html OO techniques]] built into Perl 6 help to organize things into component parts, with much flexibility (using classes, subtypes, roles, traits and multimethod dispatch).\n\n* When the problem domain becomes clearer, the presence of [[http://en.wikipedia.org/wiki/Hygienic_macro clean]] [[http://perlcabal.org/syn/S02.html macros]] and [[http://perlcabal.org/syn/S13.html user-defined operators]] help in specializing Perl 6 for the task at hand.\n\n* Somewhat less radical, but no less powerful, the built-in [[http://perlcabal.org/syn/S05.html grammar support]] allows you to specify domain-specific languages, with parsing and abstract syntax trees included in the deal.\n\n== Why write a wiki? ==\n\nA web site that users can contribute to without themselves being owners or administrators of the site, the wiki stands as one of the cornerstones in the Web 2.0 paradigm. There are hundreds of wiki engines out there, embracing the [[http://moinmo.in/WikiNature \"wiki nature\"]] to various degrees, written in [[http://en.wikipedia.org/wiki/Comparison_of_wiki_software many different languages]]. Although in essence very much the same, programming languages often differ in what is easy/convenient to express. We believe Perl 6 to be especially well suited for implementing a wiki engine, not only for the general reasons above, but also because the adaptability of Perl 6 goes well with the mutating requirements of a wiki platform. It will be interesting to see just how far Perl 6 can carry the wiki idea.\n\nAs one of the first large-scale applications written in Perl 6, it is also a nice show-case of what Perl 6 on Parrot can accomplish today.\n\n== Longing for Christmas? ==\n\n\"when it's ready, every day will be Christmas\" - Roger Hale () on Perl 6\n\nAre you eager to see Perl 6 being released, so you can write cool programs in it without worrying if the language is \"done\" yet? You can help make faster progress. If you show up on #perl6 \@ freenode and offer to give a helping hand, someone will greet you and give directions. No prior knowledge of Perl 6 required. Most likely, your help will consist in diving into the Synopses, finding a feature that you like, and making sure that the test suites cover it in sufficient detail. Before you know it, you'll be humming along, fudging tests, writing little Perl 6 scripts, [[mailto:rakudobug\@perl.org submitting bugs]], and generally being very happy. Scientists have proved that Perl 6 programmers are 23\% more harmonic than people in general. Become a Perl 6 hacker today!\n\nOf course, you're welcome to [[http://github.com/viklund/november/ hack on the wiki engine]], as well. Since it exercises the capabilities of Perl 6, programming the wiki helps the language implementations along, too.\n", "ihrd", 1229358500] 2 | -------------------------------------------------------------------------------- /data/modifications/0: -------------------------------------------------------------------------------- 1 | [ 2 | 'Main_Page', 3 | 'November is a wiki engine written in Perl 6. 4 | 5 | == What is Perl? == 6 | 7 | [http://www.perl.org/about.html Perl] is a dynamic programming language with tendencies towards expressivity rather than minimalism. One of its central tenets being that \'\'[http://en.wikipedia.org/wiki/There_is_more_than_one_way_to_do_it There Is More Than One Way To Do It]\'\', Perl accomodates a many-cultured assortment of solutions to common programming problems. Through [http://use.perl.org/ various] [http://www.perlmonks.org/ fora], a well-written [http://perldoc.perl.org/ core documentation], and a central repository of thousands of [http://search.cpan.org/ modules], Perl culture is constantly being passed on and added to. 8 | 9 | == What is Perl 6? == 10 | 11 | \'\'"Perl 5 was my rewrite of Perl. I want Perl 6 to be the community\'s rewrite of Perl and of the community." — Larry Wall\'\' 12 | 13 | Since the year 2000, [http://perl.net.au/wiki/Perl_6 Perl 6] has been in the making. The process of arriving at a full implementation of the language has taken a long time; not least because the [http://www.parrotcode.org/ Parrot] virtual machine and its assorted toolchain needed to be built to host the language. Even the design process itself has [http://perlcabal.org/syn/ evolved] and [http://www.nntp.perl.org/group/perl.perl6.language/ matured] during this time. Perl 6 is a fresh redesign of Perl, throwing away unfortunate design elements that have accrued — not only in Perl, but in the language design field in general — while keeping the good parts and throwing in some new gems as well. 14 | 15 | \'\'"Our unofficial slogan is: \'Perl 6: second-system syndrome done right\'. " — Larry Wall\'\' 16 | 17 | == Why use Perl 6? == 18 | 19 | People who have experience with Perl 5 might ask themselves what they have to gain from using Perl 6. Here\'s what we believe are the advantages: 20 | 21 | * At the early stages of development, Perl 6 allows for rapid prototyping and fluent experimentation. 22 | * As the application matures, the [http://perlcabal.org/syn/S12.html OO techniques] built into Perl 6 help to organize things into component parts, with much flexibility (using classes, subtypes, roles, traits and multimethod dispatch). 23 | * When the problem domain becomes clearer, the presence of [http://en.wikipedia.org/wiki/Hygienic_macro clean] [http://perlcabal.org/syn/S02.html macros] and [http://perlcabal.org/syn/S13.html user-defined operators] help in specializing Perl 6 for the task at hand. 24 | * Somewhat less radical, but no less powerful, the built-in [http://perlcabal.org/syn/S05.html grammar support] allows you to specify domain-specific languages, with parsing and abstract syntax trees included in the deal. 25 | * [http://search.cpan.org/ CPAN] is still there, so the power of Perl 5 can be leveraged in Perl 6 as well. While backwards-incompatible, Perl 6 can still talk to Perl 5 (and many other languages) through the Parrot platform. 26 | 27 | == Why write a wiki? == 28 | 29 | A web site that users can contribute to without themselves being owners or administrators of the site, the wiki stands as one of the cornerstones in the Web 2.0 paradigm. There are hundreds of wiki engines out there, embracing the [http://moinmo.in/WikiNature "wiki nature"] to various degrees, written in [http://en.wikipedia.org/wiki/Comparison_of_wiki_software many different languages]. Although in essence very much the same, programming languages often differ in what is easy/convenient to express. We believe Perl 6 to be especially well suited for implementing a wiki engine, not only for the general reasons above, but also because the adaptability of Perl 6 goes well with the mutating requirements of a wiki platform. It will be interesting to see just how far Perl 6 can carry the wiki idea. 30 | 31 | As one of the first large-scale applications written in Perl 6, it is also a nice show-case of what Perl 6 on Parrot can accomplish today. 32 | 33 | == Longing for Christmas? == 34 | 35 | \'\'"when it\'s ready, every day will be christmas" — Roger Hale () on Perl 6\'\' 36 | 37 | Are you eager to see Perl 6 being released, so you can write cool programs in it without worrying if the language is "done" yet? \'\'You\'\' can help make faster progress. If you show up on #perl6 @ freenode and offer to give a helping hand, someone will greet you and give directions. No prior knowledge of Perl 6 required. Most likely, your help will consist in diving into the Synopses, finding a feature that you like, and making sure that the test suites cover it in sufficient detail. Before you know it, you\'ll be humming along, fudging tests, writing little Perl 6 scripts, [mailto:rakudobug@perl.org submitting bugs], and generally being very happy. Scientists have proved that Perl 6 programmers are 23% more harmonic than people in general. Become a Perl 6 hacker today! 38 | 39 | Of course, you\'re welcome to [http://github.com/viklund/november/ hack on the wiki engine], as well. Since it exercises the capabilities of Perl 6, programming the wiki helps the language implementations along, too.', 40 | 'carl' 41 | ] 42 | -------------------------------------------------------------------------------- /p5w/data/modifications/1219443872: -------------------------------------------------------------------------------- 1 | [ 2 | 'Main_Page', 3 | 'November is a wiki engine written in Perl 6. 4 | 5 | == What is Perl? == 6 | 7 | [http://www.perl.org/about.html Perl] is a dynamic programming language with tendencies towards expressivity rather than minimalism. One of its central tenets being that \'\'[http://en.wikipedia.org/wiki/There_is_more_than_one_way_to_do_it There Is More Than One Way To Do It]\'\', Perl accomodates a many-cultured assortment of solutions to common programming problems. Through [http://use.perl.org/ various] [http://www.perlmonks.org/ fora], a well-written [http://perldoc.perl.org/ core documentation], and a central repository of thousands of [http://search.cpan.org/ modules], Perl culture is constantly being passed on and added to. 8 | 9 | == What is Perl 6? == 10 | 11 | \'\'"Perl 5 was my rewrite of Perl. I want Perl 6 to be the community\'s rewrite of Perl and of the community." — Larry Wall\'\' 12 | 13 | Since the year 2000, [http://perl.net.au/wiki/Perl_6 Perl 6] has been in the making. The process of arriving at a full implementation of the language has taken a long time; not least because the [http://www.parrotcode.org/ Parrot] virtual machine and its assorted toolchain needed to be built to host the language. Even the design process itself has [http://perlcabal.org/syn/ evolved] and [http://www.nntp.perl.org/group/perl.perl6.language/ matured] during this time. Perl 6 is a fresh redesign of Perl, throwing away unfortunate design elements that have accrued — not only in Perl, but in the language design field in general — while keeping the good parts and throwing in some new gems as well. 14 | 15 | \'\'"Our unofficial slogan is: \'Perl 6: second-system syndrome done right\'. " — Larry Wall\'\' 16 | 17 | == Why use Perl 6? == 18 | 19 | People who have experience with Perl 5 might ask themselves what they have to gain from using Perl 6. Here\'s what we believe are the advantages: 20 | 21 | * At the early stages of development, Perl 6 allows for rapid prototyping and fluent experimentation. 22 | * As the application matures, the [http://perlcabal.org/syn/S12.html OO techniques] built into Perl 6 help to organize things into component parts, with much flexibility (using classes, subtypes, roles, traits and multimethod dispatch). 23 | * When the problem domain becomes clearer, the presence of [http://en.wikipedia.org/wiki/Hygienic_macro clean] [http://perlcabal.org/syn/S02.html macros] and [http://perlcabal.org/syn/S13.html user-defined operators] help in specializing Perl 6 for the task at hand. 24 | * Somewhat less radical, but no less powerful, the built-in [http://perlcabal.org/syn/S05.html grammar support] allows you to specify domain-specific languages, with parsing and abstract syntax trees included in the deal. 25 | * [http://search.cpan.org/ CPAN] is still there, so the power of Perl 5 can be leveraged in Perl 6 as well. While backwards-incompatible, Perl 6 can still talk to Perl 5 (and many other languages) through the Parrot platform. 26 | 27 | == Why write a wiki? == 28 | 29 | A web site that users can contribute to without themselves being owners or administrators of the site, the wiki stands as one of the cornerstones in the Web 2.0 paradigm. There are hundreds of wiki engines out there, embracing the [http://moinmo.in/WikiNature "wiki nature"] to various degrees, written in [http://en.wikipedia.org/wiki/Comparison_of_wiki_software many different languages]. Although in essence very much the same, programming languages often differ in what is easy/convenient to express. We believe Perl 6 to be especially well suited for implementing a wiki engine, not only for the general reasons above, but also because the adaptability of Perl 6 goes well with the mutating requirements of a wiki platform. It will be interesting to see just how far Perl 6 can carry the wiki idea. 30 | 31 | As one of the first large-scale applications written in Perl 6, it is also a nice show-case of what Perl 6 on Parrot can accomplish today. 32 | 33 | == Longing for Christmas? == 34 | 35 | \'\'"when it\'s ready, every day will be christmas" — Roger Hale () on Perl 6\'\' 36 | 37 | Are you eager to see Perl 6 being released, so you can write cool programs in it without worrying if the language is "done" yet? \'\'You\'\' can help make faster progress. If you show up on #perl6 @ freenode and offer to give a helping hand, someone will greet you and give directions. No prior knowledge of Perl 6 required. Most likely, your help will consist in diving into the Synopses, finding a feature that you like, and making sure that the test suites cover it in sufficient detail. Before you know it, you\'ll be humming along, fudging tests, writing little Perl 6 scripts, [mailto:rakudobug@perl.org submitting bugs], and generally being very happy. Scientists have proved that Perl 6 programmers are 23% more harmonic than people in general. Become a Perl 6 hacker today! 38 | 39 | Of course, you\'re welcome to [http://github.com/viklund/november/ hack on the wiki engine], as well. Since it exercises the capabilities of Perl 6, programming the wiki helps the language implementations along, too.', 40 | 'carl' 41 | ] 42 | --------------------------------------------------------------------------------