#! /usr/bin/perl -w

# Copyright (C) 2005–2023  Alex Schroeder <alex@gnu.org>
#
# 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 3 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.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

package OddMuse;
use HTML::WikiConverter;
use MIME::Base64;
use Encode;
no warnings 'redefine';
no warnings 'once';
our $RunCGI = 0;
do './wiki.pl' or die "Cannot load ./wiki.pl";
Init();

my $wc = new HTML::WikiConverter(
  dialect => 'Markdown',
  escape_entities => 0,
  wiki_uri => '/view/',
  base_uri => "$ScriptName/",
  link_style => 'inline',
  image_style => 'inline',
  md_extra => 1);

sub nop { }
*PrintJournal = \&nop;
*SearchTitleAndBody = \&nop;
*HTML::WikiConverter::Markdown::_link = \&_link;

sub _link {
    my ( $self, $node, $rules ) = @_;

    my $url   = $self->_abs2rel( $node->attr('href') || '' );
    my $text  = $self->get_elem_contents($node);
    my $title = $node->attr('title') || '';

    return sprintf "[%s](%s \"%s\")", $text, $url, $title if $title;
    return sprintf "[%s](%s)", $text, $url;
}

sub main {
  my ($md_dir, $re) = @_;
  $md_dir ||= 'markdown';
  mkdir($md_dir) or die "Cannot create $md_dir directory: $!"
      unless -d $md_dir;
  my @pages = AllPagesList();
  @pages = grep(/$re/, @pages) if $re;
  for my $id (@pages) {
    next if $id =~ /$CommentsPrefix/;
    OpenPage($id);
    my ($type) = TextIsFile($Page{text});
    if ($type) {
      my $ext = $StaticMimeTypes{$type};
      print STDERR "$ext $id\n";
      my ($data) = $Page{text} =~ /^[^\n]*\n(.*)/s;
      open(my $OUT, '>', encode_utf8("$md_dir/$id.$ext")) or die "Cannot write $OpenPageName: $!";
      print $OUT MIME::Base64::decode($data);
      close($OUT);
    } else {
      print STDERR "md $id\n";
      my $html = ToString(\&PrintPageHtml);
      my %escapes;
      my $key = 1;
      my $ESC = "\x1b";
      # escape SVG
      $html =~ s/(<svg.*?>.*?<\/svg>)/$escapes{$key} = $1; $ESC . ($key++) . ";"/seg;
      # convert to Markdown
      my $md = "# " . NormalToFree($id) . "\n\n" . decode_utf8($wc->html2wiki(encode_utf8($html)));
      # restore escapes
      $md =~ s/$ESC(\d+);/$escapes{$1}/ge;
      # fix tags
      $md =~ s/\[([^]]*)\]\(\.\.\/wiki\?action=tag;id=(?:%23)?(\S+) "Tag"\)/[$1](\/search?q=%23$2)/g;
      # fix images
      $md =~ s/\[!\[([^]]*)\]\($ScriptName\/download\/(\S+) "\1"\)\]\(\2\)/img($1, $2)/ge;
      # fix tables
      $md =~ s/\n\n(\|.*)/"\n\n" . table($1)/ge;
      WriteStringToFile("$md_dir/$id.md", $md);
    }
  }
}

sub table {
  my $str = shift;
  my $sep = $str;
  $sep =~ s/[^|]+/:--:/g;
  return "$str\n$sep";
}

sub img {
  my ($title, $id) = @_;
  my ($type) = PageIsUploadedFile($id);
  print STDERR "? $id\n" unless $type;
  my $ext = $StaticMimeTypes{$type};
  return "![$title]($id.$ext)";
}

use Getopt::Long;
my $dir;
my $re;
my $help;
GetOptions ("dir=s"    => \$dir,
	    "re=s"     => \$re,
	    "help"     => \$help);

if ($help) {
  print qq{Usage: $0 [DIR]

Writes the raw wiki text into markdown text files. It expects the wiki code
('wiki.pl') to be in the current directory. The data directory is either set by
the WikiDataDir environment variable (case sensitive!) or the current directory
is used.

--dir designates an output directory. By default this is 'markdown' in the
  current directory.

--re designates a regular expression matching the pages to be write.

Example: $0 --dir md
}
} else {
  main($dir, $re);
}