Skip to content

Commit

Permalink
Disable hard line breaks using two spaces in the default syntax.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkende committed Apr 10, 2024
1 parent 82cc7a2 commit 0ee304d
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 5 deletions.
5 changes: 5 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
Revision history for pmarkdown and the Markdown::Perl module.

1.03 - ??

- Disable hard line breaks using two spaces in our default syntax because they
are invisible in the source file.

1.02 - 2024-04-06

- Improvement to the support of the original markdown syntax. This is probably
Expand Down
20 changes: 17 additions & 3 deletions lib/Markdown/Perl.pm
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,30 @@ sub convert { ## no critic (RequireArgUnpacking)
my $md = \(shift @_); # Taking a reference to avoid copying the input. is it useful?
$this->SUPER::set_options(local_options => @_);

my $parser = Markdown::Perl::BlockParser->new($this, $md);

# TODO: introduce an HtmlRenderer object that carries the $linkrefs states
# around (instead of having to pass it in all the calls).
my ($linkrefs, $blocks) = $parser->process();
my ($blocks, $linkrefs) = $this->_parse($md);
my $out = $this->_emit_html(0, 'root', $linkrefs, @{$blocks});
$this->{local_options} = {};
return $out;
}

# This is an internal call for now because the structure of the parse tree is
# not defined.
# Note that while convert() takes care not to copy the md argument, this is not
# the case of this method, however, it can receive a scalar ref instead of a
# scalar, to avoid the copy.
# TODO: create a BlockTree class and document it, then make this be public.
sub _parse {
my ($this, $md_or_ref) = &_get_this_and_args; ## no critic (ProhibitAmpersandSigils)
my $md = ref($md_or_ref) ? $md_or_ref : \$md_or_ref;

my $parser = Markdown::Perl::BlockParser->new($this, $md);
my ($linkrefs, $blocks) = $parser->process();
return ($blocks, $linkrefs) if wantarray;
return $blocks;
}

sub _render_inlines {
my ($this, $linkrefs, @lines) = @_;
return Markdown::Perl::Inlines::render($this, $linkrefs, @lines);
Expand Down
2 changes: 2 additions & 0 deletions lib/Markdown/Perl/BlockParser.pm
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,8 @@ sub _do_fenced_code_block {
sub _do_html_block {
my ($this) = @_;
# HTML blocks can interrupt a paragraph.
# TODO: add an option so that they don’t interrupt a paragraph (make it be
# the default?).
# TODO: PERF: test that $l =~ m/^ {0,3}</ to short circuit all these regex.
my $html_end_condition;
if ($l =~ m/ ^\ {0,3} < (?:pre|script|style|textarea) (?:\ |\t|>|$) /x) {
Expand Down
8 changes: 7 additions & 1 deletion lib/Markdown/Perl/Inlines.pm
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,13 @@ sub process_whitespaces {
next unless $n->{type} eq 'text';
# TODO: add tests for the fact that we don’t want hard break at the end of a
# paragraph.
my @hard_breaks = split(/(?: {2,}|\\)\n(?=.) */s, $n->{content}, -1);
my $re;
if ($that->get_two_spaces_hard_line_breaks) {
$re = qr/(?: {2,}|\\)\n(?=.) */s;
} else {
$re = qr/\\\n(?=.) */s;
}
my @hard_breaks = split($re, $n->{content}, -1);
for (my $j = 0; $j < @hard_breaks; $j++) {
# $hard_breaks[$j] = '' unless defined($hard_breaks[$j]);
$hard_breaks[$j] =~ s/^ +// if !$not_root && $i == 0 && $j == 0;
Expand Down
13 changes: 13 additions & 0 deletions lib/Markdown/Perl/Options.pm
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,19 @@ _make_option(

=pod
=head3 B<two_spaces_hard_line_breaks> I<(boolean, default: false)>
Controls if a hard line break can be generated by ending a line with two spaces.
=cut

_make_option(
two_spaces_hard_line_breaks => 0,
_boolean,
(markdown => 1, cmark => 1, github => 1));

=pod
=head2 Options controlling the rendering of inline elements
=head3 B<html_escaped_characters> I<(character_class)>
Expand Down
2 changes: 1 addition & 1 deletion t/202-basic-inline-rendering.t
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ is(run("abc\n"), "<p>abc</p>\n", 'line2');
is(run(" abc "), "<p>abc</p>\n", 'line3');

is(run("abc\ndef\n"), "<p>abc\ndef</p>\n", 'soft_break');
is(run("abc \ndef\n"), "<p>abc<br />\ndef</p>\n", 'hard_break1');
is(run("abc \ndef\n", two_spaces_hard_line_breaks => 1), "<p>abc<br />\ndef</p>\n", 'hard_break1');
is(run("abc\ndef \n"), "<p>abc\ndef</p>\n", 'hard_break2');
is(run("abc\\\ndef"), "<p>abc<br />\ndef</p>\n", 'hard_break3');
is(run("abc\\\\\ndef"), "<p>abc\\\ndef</p>\n", 'hard_break4');
Expand Down
15 changes: 15 additions & 0 deletions t/400-opt-two_spaces_hard_line_breaks.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use strict;
use warnings;
use utf8;

use Markdown::Perl 'convert';
use Test2::V0;

is(convert("foo\nbar", two_spaces_hard_line_breaks => 0), "<p>foo\nbar</p>\n", 'soft_opt_off');
is(convert("foo\nbar", two_spaces_hard_line_breaks => 1), "<p>foo\nbar</p>\n", 'soft_opt_on');
is(convert("foo\\\nbar", two_spaces_hard_line_breaks => 0), "<p>foo<br />\nbar</p>\n", 'hard_with_backslash_opt_off');
is(convert("foo\\\nbar", two_spaces_hard_line_breaks => 1), "<p>foo<br />\nbar</p>\n", 'hard_with_backslash_opt_on');
is(convert("foo \nbar", two_spaces_hard_line_breaks => 0), "<p>foo\nbar</p>\n", 'hard_with_spaces_opt_off');
is(convert("foo \nbar", two_spaces_hard_line_breaks => 1), "<p>foo<br />\nbar</p>\n", 'hard_with_spaces_opt_on');

done_testing;

0 comments on commit 0ee304d

Please sign in to comment.