Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions lib/Plerd/Post.pm
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,15 @@ sub _build_social_meta_tags {

}

# Normalize CRLF ("Windows") and bare-CR ("classic Mac") newlines to LF, so
# source files publish cleanly and get rewritten with consistent line endings
# regardless of the editor that produced them.
sub _normalize_newlines {
my ( $text ) = @_;
$text =~ s/\r\n?/\n/g;
return $text;
}

# This next internal method does a bunch of stuff.
# It's called via Moose-trigger when the object's source_file attribute is set.
# * Read and store the file's data (body) and metadata
Expand All @@ -413,6 +422,7 @@ sub _process_source_file {
my %attributes;
my @ordered_attribute_names = qw( title time published_filename guid tags);
while ( my $line = <$fh> ) {
$line = _normalize_newlines( $line );
chomp $line;
last unless $line =~ /\S/;
my ($key, $value) = $line =~ /^\s*(\w+?)\s*:\s*(.*?)\s*$/;
Expand All @@ -428,8 +438,8 @@ sub _process_source_file {
$self->attributes( \%attributes );

my $body;
while ( <$fh> ) {
$body .= $_;
while ( my $line = <$fh> ) {
$body .= _normalize_newlines( $line );
}

close $fh;
Expand Down
65 changes: 65 additions & 0 deletions t/crlf.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use warnings;
use strict;
use Test::More;
use Path::Class::Dir;
use Path::Class::File;
use URI;

use FindBin;
use lib "$FindBin::Bin/../lib";

use_ok( 'Plerd' );
use Plerd::Init;

# Regression test for GitHub issue #25: source files that use CRLF ("Windows")
# newlines used to break publication with a misleading "not in W3C format"
# error. Plerd should accept CRLF source files, publish them cleanly, and
# normalize the rewritten source file to LF newlines.

my $blog_dir = Path::Class::Dir->new( "$FindBin::Bin/crlf_testblog" );
$blog_dir->rmtree;

Plerd::Init::initialize( $blog_dir->stringify, 0 );

my $source_file = Path::Class::File->new( $blog_dir, 'source', 'crlf-post.md' );
{
open my $fh, '>:raw', $source_file->stringify
or die "Can't write $source_file: $!";
print $fh "title: CRLF Post\r\n";
print $fh "time: 2018-03-04T12:00:00\r\n";
print $fh "tags: foo, bar\r\n";
print $fh "\r\n";
print $fh "This is the **body** of the post.\r\n";
print $fh "\r\n";
print $fh "Second paragraph here.\r\n";
close $fh;
}

my $plerd = Plerd->new(
path => $blog_dir->stringify,
title => 'Test Blog',
author_name => 'Nobody',
author_email => 'nobody@example.com',
base_uri => URI->new( 'http://blog.example.com/' ),
);

eval { $plerd->publish_all; };
is( $@, '', 'A CRLF source file publishes without error.' );

my $published = Path::Class::File->new(
$blog_dir, 'docroot', '2018-03-04-crlf-post.html'
);
ok( -e $published, 'The CRLF post produced its HTML file.' );

# The source file is rewritten in place during publication; it should no
# longer contain any carriage returns.
my $rewritten = do {
open my $fh, '<:raw', $source_file->stringify or die $!;
local $/;
<$fh>;
};
unlike( $rewritten, qr/\r/, 'Rewritten source file is free of carriage returns.' );

$blog_dir->rmtree;

done_testing();