- #!/usr/bin/perl
- use v5.36;
- use strict;
- use utf8;
- =head1 NAME
- hedgedoc2quarto - convert HedgeDoc content to Quarto
- =head1 VERSION
- Version 0.0.1
- =head1 SYNOPSIS
- hedgedoc2quarto INFILE OUTFILE
- hedgedoc2quarto < INFILE > OUTFILE
- =head1 DESCRIPTION
- B<hedgedoc2quarto> reformats text content
- from HedgeDoc- to Quarto-flavored Markdown,
- and adapts embedded diagram code.
- Both HedgeDoc and Quarto uses Markdown,
- but different flavors,
- and whereas both handle (different subsets of) Mermaid diagrams,
- Quarto also (through plugins) handles PlantUML diagrams.
- =cut
- # slurp INFILE if passed as first argument, or else STDIN
- my ( $infile, $outfile, $bogus ) = @ARGV;
- die 'Too many arguments: expected INFILE and OUTFILE' if $bogus;
- @ARGV = ($infile) if $infile;
- my $content = do { local $/ = undef; <> };
- # TODO: integrate with subroutine handler below
- $content =~ s/^
- (?'fence'[``~]{3,})\s*
- \Kgraphviz\n
- (?'code'.*?\n)
- \k'fence'
- $/{dot}\n\/\/| fig-width: 100\%\n$+{code}$+{fence}/gsmx;
- $content =~ s/^
- (?'fence'[``~]{3,})\s*
- \Kmermaid\n
- (?'type'gantt)\n
- (?'code'.*?\n)
- \k'fence'
- $/
- # FIXME: implement option to choose output diagram language
- # "{mermaid}\n\%\%| fig-width: 100\%\n"
- # . &mmd2mmd( $+{type}, $+{code} )
- "{.plantuml}\n\%\%| fig-width: 100\%\n"
- . &mmd2puml( $+{type}, $+{code} )
- . $+{fence}
- /gsmex;
- if ($outfile) {
- open( FH, '>', $outfile ) or die $!;
- print FH $content;
- }
- else {
- print $content;
- }
- sub mmd2mmd ( $type, $code )
- {
- # strip special comment marker '%%QUARTO%%'
- $code =~ s/^\s*+\K%%QUARTO%%//gm;
- return "$type\n$code";
- }
- sub mmd2puml ( $type, $code )
- {
- my @newcode;
- # strip special comment marker '%%QUARTO%%'
- $code =~ s/^\s*+\K%%QUARTO%%//gm;
- open my $fh, '<', \$code or die $!;
- while (<$fh>) {
- /^\s*+$/
- and push @newcode, ''
- and next;
- /^(\s*+)%%PLANTUML%%\K.*/
- and push @newcode, "$1$&"
- and next;
- # convert comments markers
- /^(\s*+)(?:[%]{2,}(?'comment'\s*+))?+\K.*/;
- my $indent = defined( $+{comment} ) ? "$1'$2" : $1;
- $_ = $&;
- /^title\s/i
- and push @newcode, "${indent}$_"
- and next;
- /^excludes\s+weekends\b/i
- and push @newcode, "${indent}saturday are closed"
- and push @newcode, "${indent}sunday are closed"
- and next;
- /^weekday\s+\K(?:mon|tues|wednes|thurs|fri|satur|sun)day\b/i
- and push @newcode, "${indent}weeks start on $&"
- and next;
- /^(?:date|axis)Format\s/i
- and push @newcode, "${indent}'UNSUPPORTED: $_"
- and next;
- /^todayMarker\s+(off|on)\b/i
- and push @newcode, "${indent}'UNSUPPORTED' $_"
- and next;
- /^section\s+\K\S+(?:\s+\S+)*/i
- and push @newcode, "${indent}-- $& --"
- and next;
- if (/^tickInterval\s+(?'tickAmount'\d+)(?'tickUnit'millisecond|second|minute|hour|day|week|month)\s*$/i
- )
- {
- push @newcode, "${indent}projectscale daily"
- and next
- if $+{tickAmount} eq 1
- and $+{tickUnit} eq 'day';
- push @newcode, "${indent}projectscale weekly" and next
- if $+{tickAmount} eq 1 and $+{tickUnit} eq 'week'
- or $+{tickAmount} eq 7 and $+{tickUnit} eq 'day';
- push @newcode, "${indent}projectscale monthly"
- and next
- if $+{tickAmount} eq 1
- and $+{tickUnit} eq 'month';
- push @newcode, "${indent}projectscale quarterly"
- and next
- if $+{tickAmount} eq 3
- and $+{tickUnit} eq 'month';
|