#!/usr/bin/perl ###!C:/perl/bin/perl.exe # roqwiki; # Last updated: 2010-04-01 $version = '2.0'; $copyyear = '2010'; =head1 RoqWiki A wiki generator that converts ascii text files that are in Roqet Document Format into an HTML document. RoqWiki was inspired by pwyky, an Python wiki (but contains no source-code from that project). =head2 Install 0. Download RoqWiki: 1. Create a new script-writable directory on your server 2. Upload roqwiki.pl to your server and rename it to index.cgi 3. Change permissions on index.cgi to 755 4. Create a .htaccess file in the same directory with the following contents: DirectoryIndex index.cgi Options -MultiViews RewriteEngine on RewriteBase /test RewriteRule ^@[a-z]+/([A-Za-z0-9-]+)$ index.cgi [L] RewriteRule ^([A-Za-z0-9-]+)$ index.cgi [L] RewriteRule ^([A-Za-z0-9-]+)\.html$ - [L] 5. Browse to http://yourdomainname/yourdirectory/index.cgi When the index.cgi is run the first time, it will create the template files and stylesheet files for your later modification. =head2 Further Configuration If you want to remove editing from the wiki, create a file in the same directory called roqwiki.xml with the following format: 1 ../ wiki.html If your source contains comments that you don't want visible to the word, you should password-protect the created "source" directory. =head2 Roqet Document Format The format of an Roqet Document Format is as follows: - (comment) @ heading (heading) * bullet (depreciated) *** bullet (new style) *-* horizontal line command = description and [examples] (descriptive line) [code] {{link~~linkname}} {*imagelink*} [[ preformatted block (puts in
 tag block)
  ]]
  - -->import:filename to import an external file

=head2 The Template File

  RoqWiki will generate an HTML Template File, you can then modify it to
  include whatever you want (Google search for example). The template must
  contain these tags
  (*title*)
  (*body*)
  (*draftdate*)

=head1 To Do

  Add more meta pages:
    grep (search)
    help (can build into about perhaps)

=head1 ChangeLog

  2008-04-16 :: 1.0 :: Initial release some code came from roqdocbuild.pl
  2008-04-17 :: 1.1 :: Bugfixes on display, create and URI limits
  2008-04-18 :: 1.2 :: Tweaks on formatting
  2008-05-19 :: 1.3 :: Added a body div for more refined formatting
  2008-06-06 :: 1.4 :: Added build all functionality
  2008-06-13 :: 1.5 :: Cleaned up code to use template for all page builds
  2009-05-11 :: 1.6 :: Changed info tag about imports not being within pre tags
  2009-06-03 :: 1.7 :: Added new-style bullets and horizontal lines.
  2009-12-23 :: 1.8 :: Added ability to deploy a single page to another location.
  2009-12-23 :: 1.9 :: Changed parameter file to be an xml file and to deploy multiple files.
  2010-04-01 :: 2.0 :: Modified to have a metedata page instead of a generated about page.

=head1 Author

  roqet 

=head1 Copyright

  RoqWiki Perl script copyright 2009 roqet .
  RoqWiki can be distributed and modified under the terms of the
  GNU General Public License: http://www.gnu.org/copyleft/gpl.html

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
  GNU General Public License for more details.

  Updates and other scripts and software available at:
  http://www.roqet.org/software.html
   ~~~
   'l'
    -

=cut

use CGI qw/:standard/;
use File::Copy;
use XML::Simple;
&parseform;

$allowedit = 1;
$deploylocation = '../';

$paramfile = XMLin('./roqwiki.xml');
$allowedit = $paramfile->{allow_edit};
$deploylocation = $paramfile->{deploy_location};

$sourcedir = "./source/";

if (!$key) {
  ( $val1, $val2, $val3 ) = split( /\//, $ENV{'SCRIPT_URL'} );
  $key = $val3;
  #print "Content-type:text/html\n\n";
  #print "$val1, $val2, $val3\n\n";
  #print "";
}

if (!$key) {
  &indexcheck;  
}
elsif ($key eq 'create') {
  # create a new .txt file and 
  # generate a new .html file
  open(OUTSOURCE,">$sourcedir" . "$value.txt") || die "error opening $sourcedir" . "$value.txt: $!\n";
  print OUTSOURCE '-= ' . $value . ' =-' . "\n\n";
  &getnotes;
  print OUTSOURCE $notes;
  print OUTSOURCE '@ New Page' . "\n";
  print OUTSOURCE '----------' . "\n";
  print OUTSOURCE 'ready for your modifications.' . "\n";
  close OUTSOURCE;
  print "Content-type:text/html\n\n";
  undef (@body);
  push (@body, '
' . "\n"); push (@body, '' . "\n"); push (@body, '' . "\n"); push (@body, '
' . "\n"); &readtemplate; $titleval = 'Editing ' . $value . ' Page'; foreach $item (@templatefile) { $item =~ s/\(\*title\*\)/$titleval/g; if ($item =~ /\(\*body\*\)/) { #$item =~ s/\(\*body\*\)/@body/g; # need to do this as the above line caused a preceeding space $item =~ s/\(\*body\*\)//g; foreach $bit (@body) { print "$bit"; } } $item =~ s/\(\*draftdate\*\)//g; if ( $item =~ '
' ) { print '
A roqwiki Edit page
' . "\n"; } else { print "$item"; } } } elsif ($key eq 'filename') { # display page print "Content-type:text/html\n\n"; print "query: " . $ENV{'SCRIPT_URI'}; print "value: $value"; print ""; } elsif (substr($key,0,6) eq 'update') { # save changes and display page again here ( $val1, $sourcename ) = split( /\-\-/, $key ); open(OUTSOURCE,">$sourcedir" . "$sourcename.txt") || die "error opening $sourcedir" . "$sourcename.txt: $!\n"; print OUTSOURCE $value; close OUTSOURCE; &generatehtml($sourcename); &displaypage($sourcename); } elsif ($key eq 'edit') { # display source code in edit box print "Content-type:text/html\n\n"; undef (@body); push (@body, '
' . "\n"); push (@body, '' . "\n"); push (@body, '' . "\n"); push (@body, '
' . "\n"); &readtemplate; $titleval = 'Editing ' . $value . ' Page'; foreach $item (@templatefile) { $item =~ s/\(\*title\*\)/$titleval/g; if ($item =~ /\(\*body\*\)/) { #$item =~ s/\(\*body\*\)/@body/g; # need to do this as the above line caused a preceeding space $item =~ s/\(\*body\*\)//g; foreach $bit (@body) { print "$bit"; } } $item =~ s/\(\*draftdate\*\)//g; if ( $item =~ '
' ) { print '
A roqwiki Edit page
' . "\n"; } else { print "$item"; } } } elsif ($key eq 'deploy') { # copy page to deploy location print "Content-type:text/html\n\n"; undef (@body2); push (@body2, '

Deploy Wiki Page

' . "\n"); push (@body2, "
    \n"); push (@body2, "
\n"); copy("$value.html", $deploylocation) or warn "$value.html cannot be copied."; push (@body2, "$value has been deployed to $deploylocation\n"); &readtemplate; foreach $item (@templatefile) { $item =~ s/\(\*title\*\)/Deploy Complete/g; if ($item =~ /\(\*body\*\)/) { #$item =~ s/\(\*body\*\)/@body/g; # need to do this as the above line caused a preceeding space $item =~ s/\(\*body\*\)//g; foreach $bit (@body2) { print "$bit"; } } if ( $item =~ '
' ) { print '
A roqwiki Metadata page
' . "\n"; } else { print "$item"; } } } elsif ($key eq 'doclist') { # list all wiki pages print "Content-type:text/html\n\n"; undef (@body); push (@body, '

List of Wiki Pages

' . "\n"); push (@body, "\n"); push (@body, "

Total: $filecount pages.<\/b><\/p>\n"); &readtemplate; foreach $item (@templatefile) { $item =~ s/\(\*title\*\)/RoqWiki List of Pages/g; $item =~ s/\(\*body\*\)/@body/g; if ( $item =~ '

' ) { print '
A roqwiki Metadata page
' . "\n"; } else { print "$item"; } } } elsif ($key eq 'buildall') { # build all wiki pages print "Content-type:text/html\n\n"; undef (@body2); push (@body2, '

Rebuilding All Wiki Pages

' . "\n"); push (@body2, "\n"); push (@body2, "

Rebuilt $filecount pages.<\/b><\/p>\n"); &readtemplate; foreach $item (@templatefile) { $item =~ s/\(\*title\*\)/RoqWiki Build All Pages/g; if ($item =~ /\(\*body\*\)/) { #$item =~ s/\(\*body\*\)/@body/g; # need to do this as the above line caused a preceeding space $item =~ s/\(\*body\*\)//g; foreach $bit (@body2) { print "$bit"; } } if ( $item =~ '

' ) { print '
A roqwiki Metadata page
' . "\n"; } else { print "$item"; } } } elsif ($key eq 'deployall') { # deploy all wiki pages print "Content-type:text/html\n\n"; undef (@body2); push (@body2, '

Deploying All Wiki Pages

' . "\n"); push (@body2, "\n"); push (@body2, "

Deployed $filecount pages.<\/b><\/p>\n"); &readtemplate; foreach $item (@templatefile) { $item =~ s/\(\*title\*\)/RoqWiki Deploy All Pages/g; if ($item =~ /\(\*body\*\)/) { #$item =~ s/\(\*body\*\)/@body/g; # need to do this as the above line caused a preceeding space $item =~ s/\(\*body\*\)//g; foreach $bit (@body2) { print "$bit"; } } if ( $item =~ '

' ) { print '
A roqwiki Metadata page
' . "\n"; } else { print "$item"; } } } elsif ($key eq 'about') { # wiki general info print "Content-type:text/html\n\n"; undef (@body2); push (@body2, '

About RoqWiki

' . "\n"); push (@body2, '

This is the RoqWiki wiki application. The latest version is available here

' . "\n"); push (@body2, '
  • Wiki Metadata' . "\n"); push (@body2, '

    View all Wiki Pages

    ' . "\n"); push (@body2, '

    Rebuild ALL Wiki Pages

    ' . "\n"); push (@body2, '

    Deploy ALL Wiki Pages

    ' . "\n"); &readtemplate; foreach $item (@templatefile) { $item =~ s/\(\*title\*\)/About RoqWiki/g; $item =~ s/\(\*body\*\)/@body2/g; if ( $item =~ '
    ' ) { print '
    A roqwiki Metadata page
    ' . "\n"; } else { print "$item"; } } } elsif (-f "./source/$key.txt") { # display actual page here &displaypage($key); } else { print "Content-type:text/html\n\n"; undef (@body); if ( $allowedit ) { push (@body, "\This page has not yet been created \Create it?\<\/a\>\<\/p\>"); } else { push (@body, "\This page has not yet been created.\<\/p\>"); } &readtemplate; foreach $item (@templatefile) { $item =~ s/\(\*title\*\)/New Roqwiki Page/g; $item =~ s/\(\*body\*\)/@body/g; $item =~ s/\(\*draftdate\*\)//g; if ( $item =~ '
    ' ) { print ' ' . "\n"; } else { print "$item"; } } } ############### # # # subroutines # # # ############### sub parseform { if( $ENV{'REQUEST_METHOD'} eq 'GET' ) { @pairs = split( /&/, $ENV{'QUERY_STRING'} ); } elsif( $ENV{'REQUEST_METHOD'} eq 'POST' ) { read( STDIN, $buffer, $ENV{'CONTENT_LENGTH'} ); @pairs = split( /&/, $buffer ); if( $ENV{'QUERY_STRING'} ) { @getpairs = split( /&/, $ENV{'QUERY_STRING'} ); push( @pairs, @getpairs ); } } else { print "Content-type:text/html\n\n"; print "Unrecognized Method - Use GET or POST."; } foreach $pair( @pairs ) { ( $key, $value ) = split( /=/, $pair ); $key =~ tr/+/ /; $value =~ tr/+/ /; $key =~ s/%(..)/pack("c", hex($1))/eg; $value =~ s/%(..)/pack("c", hex($1))/eg; $value =~ s///g; # ignore SSI if( $formdata{$key} ){$formdata{$key} .= ", $value";} else{ $formdata{$key} = $value; } } } sub displaypage { local($pagename) = @_; print "Content-type:text/html\n\n"; open INFILE, "./$pagename.html" or die "error opening $pagename.html: $!\n"; @infile = ; close INFILE; #$outdate = &draftdate('draft'); $edit = ''; foreach $inline (@infile) { if ( $inline =~ '
    ' ) { if ( $allowedit ) { $edit = 'Edit this page?' . ' Deploy this page?'; } $inline =~ s/\<\!\-\-\(\*edit\*\)\-\-\>/$edit/g; print "$inline"; } else { print "$inline"; } } } sub indexcheck { # if index page doesn't exist, create and display it here &createfiles; print "Content-type:text/html\n\n"; open INFILE, "./index.html" or die "error opening index.html: $!\n"; @infile = ; close INFILE; foreach $inline (@infile) { print "$inline"; } } sub readtemplate { open TEMPLATE, "$sourcedir" . "wiki_template.html" or die "error opening $sourcedir" . "wiki_template.html: $!\n"; @templatefile =