diff --git a/Changes b/Changes new file mode 100644 index 0000000..8401c9f --- /dev/null +++ b/Changes @@ -0,0 +1,7 @@ +Revision history for pmarkdown and the Markdown::Perl module. + +1.00 - 2024-03-31 + + - Initial release with full support for the CommonMark spec, the GitHub + Flavored Markdown extentions, and partial support for original Markdown + syntax. diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP index 4d2af49..16cc7e5 100644 --- a/MANIFEST.SKIP +++ b/MANIFEST.SKIP @@ -36,3 +36,5 @@ ^nytprof.out$ ^nytprof/ ^build/ +^.*\.code-workspace$ +^README\.md$ diff --git a/Makefile.PL b/Makefile.PL index e2a3cf4..ba60dae 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -14,7 +14,7 @@ WriteMakefile( DISTNAME => 'Markdown-Perl', AUTHOR => q{Mathias Kende }, VERSION_FROM => 'lib/Markdown/Perl.pm', - ABSTRACT => q{Very configurable Markdown processor written in pure Perl}, + ABSTRACT => q{Very configurable Markdown processor written in pure Perl, supporting the CommonMark spec and many extensions}, LICENSE => 'mit', EXE_FILES => ['script/pmarkdown',], MIN_PERL_VERSION => '5.026', diff --git a/README.md b/README.md index 06f113b..e2729b5 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,28 @@ # pmarkdown -Configurable Markdown processor. +Very configurable Markdown processor supporting the CommonMark spec and many +extensions. ## Main features -This software supports the entire `CommonMark` spec syntax, with some addition. +This software supports the entire +[`CommonMark` spec](https://spec.commonmark.org/0.31.2/) syntax, as well as all +[GitHub Flavored Markdown (gfm) extensions](https://github.github.com/gfm/) and +some more custom extensions. + +It is based on the [Markdown::Perl](https://metacpan.org/pod/Markdown::Perl) +library that can be used in standalone Perl program. + +## Usage + +Using `pmarkdown` is as simple as running the following command: + +```shell +pmarkdown < input.md > output.html +``` + +You can read about all the command line options in the +[`pmarkdown` documentation](https://metacpan.org/pod/pmarkdown). ## Installation @@ -19,7 +37,7 @@ To install `pmarkdown` you need Perl (which is already installed on most Linux distributions) and you need the `cpanm` Perl package manager. You can usually get both with one of these commands: -``` +```shell # On Debian, Ubuntu, Mint, etc. sudo apt-get install perl cpanminus @@ -29,7 +47,7 @@ sudo yum install perl perl-App-cpanminus Then run the following to install `pmarkdown`: -``` +```shell cpanm --notest App::pmarkdown ``` @@ -39,7 +57,7 @@ To install `pmarkdown` you need Perl (which is already installed on most Linux distributions) and you need the `cpanm` Perl package manager. You can usually get both with one of these commands: -``` +```shell # On Debian, Ubuntu, Mint, etc. sudo apt-get install perl cpanminus @@ -50,7 +68,7 @@ sudo yum install perl perl-App-cpanminus Then run the following command to install `pmarkdown` (note that you do not need to initialize the git submodules): -``` +```shell git clone https://github.com/mkende/pmarkdown.git cd pmarkdown cpanm --notest --with-configure --installdeps . diff --git a/dist_setup.conf b/dist_setup.conf index eb0588f..c546e00 100644 --- a/dist_setup.conf +++ b/dist_setup.conf @@ -2,7 +2,10 @@ { name => 'Markdown::Perl', - abstract => 'Very configurable Markdown processor written in pure Perl', + # We have two abstract, the Perl one here (used also in all the POD files). + # And there is a less Perl-centric one in the README.md file and in the + # configuration of the GitHub repository. + abstract => 'Very configurable Markdown processor written in pure Perl, supporting the CommonMark spec and many extensions', exe_files => ['script/pmarkdown'], min_perl_version => '5.026', diff --git a/lib/Markdown/Perl.pm b/lib/Markdown/Perl.pm index dd77c3f..ad50221 100644 --- a/lib/Markdown/Perl.pm +++ b/lib/Markdown/Perl.pm @@ -192,30 +192,35 @@ __END__ =head1 NAME -Markdown::Perl – Very configurable Markdown processor written in pure Perl +Markdown::Perl – Very configurable Markdown processor written in pure Perl, +supporting the CommonMark spec and many extensions. =head1 SYNOPSIS -This is the library underlying the L tool. - -=head1 DESCRIPTION +This is the library underlying the L tool. It can be used in an +object-oriented style: use Markdown::Perl; my $converter = Markdown::Perl->new([mode => $mode], %options); my $html = $converter->convert($markdown); -Or you can use the library functionally: +Or the library can be used functionally: use Markdown::Perl 'convert'; Markdown::Perl::set_options([mode => $mode], %options); my $html = convert($markdown); -=head1 METHODS +=head1 DESCRIPTION =head2 new my $pmarkdown = Markdown::Perl->new([mode => $mode], %options); +Creates a C object that can be used to convert Markdown data +into HTML. Note that you don’t have to create an instance of this class to use +this module. The methods of this class can also be used like package functions +and they will operate on an implicit default instance of the class. + See the L page for the documentation of existing modes. See the L documentation for all the existing options. @@ -226,21 +231,40 @@ See the L documentation for all the existing options. Markdown::Perl::set_options(%option); Sets the options of the current object or, for the functional version, the -options used by functional calls to C. The options set through the +options used by functional calls to convert(). The options set through the functional version do B apply to any objects created through a call to -C. +new(). See the L documentation for all the existing options. =head2 set_mode -See the L page for the documentation of existing modes. + $pmarkdown->set_mode($mode); + Markdown::Perl::set_mode($mode); + +Specifies a I for the current object or, for the functional version, the +mode used by functional calls to convert(). A mode is a set of configuration +options working together, typically to replicate the semantics of another +existing Markdown processor. See the L documentation for a list +of available modes. + +When a mode is applied, it sets specific values for some options but any value +for these options set through the set_options() will take precedence, even if +set_options() is called before set_mode(). The mode set through the functional +version does B apply to any objects created through a call to new(). =head2 convert + my $html = $pmarkdown->convert($md); + my $html = Markdown::Perl::convert($md); + +Converts the given $md string into HTML. The input string must be a decoded +Unicode string (or an ASCII string) and the output is similarly a decoded +Unicode string. + =head1 AUTHOR -Mathias Kende +Mathias Kende =head1 COPYRIGHT AND LICENSE @@ -272,6 +296,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =item L another pure Perl implementation, implementing the original Markdown syntax from L. +=item L a wrapper around the official CommonMark C library. + =back =cut diff --git a/lib/Markdown/Perl/InlineTree.pm b/lib/Markdown/Perl/InlineTree.pm index eea8637..1466bf9 100644 --- a/lib/Markdown/Perl/InlineTree.pm +++ b/lib/Markdown/Perl/InlineTree.pm @@ -32,10 +32,10 @@ Markdown::Perl::InlineTree A tree structure meant to represent the inline elements of a Markdown paragraph. -This package is internal to the implementation of L and -L and its documentation should be useful only if you are hacking -them. Otherwise please refer to the L and L -documentation. +This package is internal to the implementation of L and its +documentation should be useful only if you are trying to modify the library. + +Otherwise please refer to the L and L documentation. =head1 DESCRIPTION diff --git a/lib/Markdown/Perl/Options.pm b/lib/Markdown/Perl/Options.pm index a12ce2e..4b42410 100644 --- a/lib/Markdown/Perl/Options.pm +++ b/lib/Markdown/Perl/Options.pm @@ -31,9 +31,13 @@ documentation to know how to set and use these options. =head1 MODES -Bundle of options can be set together using I. +In addition to setting individual options, you can set bundle of options +together using I. See the L documentation for a list +of available modes. And see the documentation for L or +L to learn how to set a mode. -TODO +Note that all options are applied I of the selected mode. Even if the +options are passed before the mode, the mode will not override the options. =head1 OPTIONS @@ -638,4 +642,12 @@ _make_option( github => 'loose', )); +=pod + +=head1 SEE ALSO + +L, L + +=cut + 1; diff --git a/script/pmarkdown b/script/pmarkdown index a58f712..50e68df 100644 --- a/script/pmarkdown +++ b/script/pmarkdown @@ -43,15 +43,18 @@ __DATA__ =head1 NAME -pmarkdown – Very configurable Markdown processor written in pure Perl +pmarkdown – Very configurable Markdown processor written in pure Perl, +supporting the CommonMark spec and many extensions. =head1 SYNOPSIS - pmarkdown < file_in.md > file_out.html_fragment + pmarkdown [-o key=value] ... < in_file.md > out_file.html_fragment =head1 DESCRIPTION -B +Currently C can only read a single input from its standard input and +will write its output on the standard output. Both are assumed to be encoded in +UTF-8. If needed, See the L for installation instructions. @@ -71,7 +74,10 @@ Show the complete man page of the program. =item B<--list-options> Show the documentation of all the existing options of the Markdown processor. -These options can be passed with the C<-o> flag. +This is the same content that can be found on the L +page. + +These options can be passed to the program with the C<--options> flag. =item B<--version>, B<-v> @@ -90,7 +96,7 @@ for these options set through the C<--option> flag will take precedence. =item B<--option> I, B<-o> Specify the value for one particular option. The C<--option> flag can be passed -multiple times. If an option is specified multiple times, the last one takes +multiple times. If an option is specified multiple times, the last value takes precedence. The options are described in the L page. You can see @@ -99,27 +105,43 @@ it with the C command. When specifying an option value, boolean options should be passed as either C<0>, C<1>, C, or C. +Note that all options are applied I of the selected mode. Even if the +options are passed before the B<--mode> flag, the mode will not override options +set through B<--option>. + =back =head1 MODES -TODO: fill this section. - =over 8 -=item B The default mode if no other mode is specified using the -default value for all the options (as per their documentation). +=item B + +The default mode if no other mode is specified. This mode uses the default value +for all the options (as per their documentation). Note that, in practice, setting the mode to B will I the mode currently set, which means that no warning will be emitted if this mode is overridden afterward (as opposed to what happens when any other mode is being overridden, including by the default mode). -=item B L +=item B + +This mode implements the full +L. + +=item B + +This mode implements the +L variant of the +CommonMark spec. + +=item B -=item B L +This mode implements the +L. -=item B L +Note that this mode is not 100% similar to the original F script. =back diff --git a/t/901-github-test-suite.t b/t/901-github-test-suite.t index a834c24..a8028b5 100644 --- a/t/901-github-test-suite.t +++ b/t/901-github-test-suite.t @@ -8,33 +8,35 @@ use lib "${FindBin::Bin}/lib"; use CmarkTest; use Test2::V0; -my %opt = (todo => [], # We are implementing the entire spec, except for the bug below. - # These are bugs in the GitHub spec, not in our implementation. All - # of these have been tested to be buggy in the real cmark-gfm - # implementation. - bugs => [ - # The spec says that some HTML tags are forbidden in the output, - # but it still has examples with these tags. - 140 .. 142, 145, 147, - # Some things that are not cmark autolinks are matched by the - # extended autolinks syntax (but the cmark part of the spec is not - # updated for it). - 616, 619, 620, - # The spec says that only http: and https: scheme can be used - # for extended autolinks. But this example uses ftp:. - 628, - # While the spec says nothing of it, the cmark-gfm implementation - # removes a tag inside another strong tag (but not if there - # is another tag in between). For now we don’t implement this - # undocumented behavior. - 398, 426, 434 .. 436, 473 .. 475, 477, - ], - json_file => "${FindBin::Bin}/data/github.tests.json", - test_url => 'https://github.github.com/gfm/#example-%d', - spec_tool => "${FindBin::Bin}/../third_party/commonmark-spec/test/spec_tests.py", - spec => "${FindBin::Bin}/../third_party/cmark-gfm/test/spec.txt", - spec_name => 'GitHub', - mode => 'github'); +my %opt = ( + # We are implementing the entire spec, except for the bugs below. + todo => [], + # These are bugs in the GitHub spec, not in our implementation. All + # of these have been tested to be buggy in the real cmark-gfm + # implementation. + bugs => [ + # The spec says that some HTML tags are forbidden in the output, + # but it still has examples with these tags. + 140 .. 142, 145, 147, + # Some things that are not cmark autolinks are matched by the + # extended autolinks syntax (but the cmark part of the spec is not + # updated for it). + 616, 619, 620, + # The spec says that only http: and https: scheme can be used + # for extended autolinks. But this example uses ftp:. + 628, + # While the spec says nothing of it, the cmark-gfm implementation + # removes a tag inside another strong tag (but not if there + # is another tag in between). For now we don’t implement this + # undocumented behavior. + 398, 426, 434 .. 436, 473 .. 475, 477, + ], + json_file => "${FindBin::Bin}/data/github.tests.json", + test_url => 'https://github.github.com/gfm/#example-%d', + spec_tool => "${FindBin::Bin}/../third_party/commonmark-spec/test/spec_tests.py", + spec => "${FindBin::Bin}/../third_party/cmark-gfm/test/spec.txt", + spec_name => 'GitHub', + mode => 'github'); while ($_ = shift) { $opt{test_num} = shift @ARGV if /^-n$/;