use 5.010; use strict; use warnings; sub parse_file { my $fh = shift; local $/ = ''; # paragraph mode my @paragraphs; my $line_no = 0; while (my $para = <$fh>) { push @paragraphs, [ map parse_line($_, ++$line_no), split /\n/, $para]; } return \@paragraphs; } sub parse_line { my ($_, $line_no) = @_; return unless /\S/; if (/^(.*)\s\@(\w+)/) { my $line = "$1"; my $font_size = "$2"; die "Invald \@fontsize declaration in line $line_no ($font_size is not a number)\n" if $font_size =~ /\D/; return { text => $line, font_size => $font_size }; } else { return { text => $_ } } } use Data::Dumper; print Dumper parse_file(\*DATA); __DATA__ First slide Test line Second line Line with explicit font size @20