Almost-minimal filesystem based blog.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
1.5 KiB

  1. package App::WRT::Filters;
  2. use strict;
  3. use warnings;
  4. use 5.10.0;
  5. use open ':std', ':encoding(UTF-8)';
  6. use Carp;
  7. use Encode qw(decode encode);
  8. use IPC::Cmd qw(can_run run_forked);
  9. =pod
  10. =head1 NAME
  11. App::WRT::Filters - Apply filters to markup
  12. An experimental feature.
  13. =head1 SYNOPSIS
  14. # Where $entry is the path to an entry and $markup is its content:
  15. my $filters = App::WRT::Filters->new($filter_dir);
  16. my @filter_list = qw(toc);
  17. $filters->dispatch($entry, $markup, @filter_list);
  18. =cut
  19. sub new {
  20. my $class = shift;
  21. my ($filter_dir) = @_;
  22. my %params = ( filter_dir => $filter_dir );
  23. my $self = \%params;
  24. bless $self, $class;
  25. return $self;
  26. }
  27. sub dispatch {
  28. my $self = shift;
  29. my ($entry, $markup, @filters) = @_;
  30. for my $filter (@filters)
  31. {
  32. my $new_markup = '';
  33. my $stderr = '';
  34. my $command = $self->resolve_filter($filter);
  35. local $ENV{'WRT_ENTRY'} = $entry;
  36. my $result = run_forked($command, {
  37. # The encode() here seems necessary to avoid "Wide character in print"
  38. # errors from IPC::Cmd:
  39. child_stdin => encode('UTF-8', $markup),
  40. timeout => 300,
  41. stdout_handler => sub { $new_markup .= decode('UTF-8', $_[0]); },
  42. stderr_handler => sub { $stderr .= decode('UTF-8', $_[0]); }
  43. });
  44. if (length $stderr) {
  45. carp($stderr);
  46. }
  47. $markup = $new_markup;
  48. }
  49. return $markup;
  50. }
  51. sub resolve_filter {
  52. my ($self, $filter) = @_;
  53. return $self->{filter_dir} . '/' . $filter;
  54. }
  55. 1;