Skip to content
Snippets Groups Projects
gen.pl 1.67 KiB
Newer Older
  • Learn to ignore specific revisions
  • Philip Kaluđerčić's avatar
    Philip Kaluđerčić committed
    #!/usr/bin/env perl
    
    use 5.012;
    use strict;
    use warnings;
    
    use JSON;
    use IPC::Open2;
    
    my @markdown = qw/cmark --smart --safe/;
    
    my $question;
    my $single_choice;
    my $source;
    my $media;
    my %last_option;
    my @options;
    my @questions = ();
    
    sub md {    # pipe through $markdown
      my ($input) = @_;
      my $pid = open2(\*OUT, \*IN, @markdown)
        or die "open2() failed $!";
      print IN $input;
      close(IN);
      waitpid($pid, 0);
    
      return do { local $/; <OUT> };
    }
    
    sub add {
      return unless %last_option;
    
      if (defined $last_option{"comment"}) {
        $last_option{"comment"} = md($last_option{"comment"});
      }
      
      push(@options, {%last_option});
    }
    
    while (<>) {
      chomp;
      if (/^.$/) {
        add();
    
        die "end of block without a question at line $.\n"
          unless defined $question;
    
        my %ent =
          (
           "question" => md($question),
           "options"  => [@options],
           "multiple" => ($single_choice eq "0" ? \0 : \1)
          );
        $ent{"source"} = $source if defined $source;
        $ent{"media"}  = $media  if defined $media;
    
        push(@questions, { %ent });
        undef $question;
        undef $single_choice;
        undef $source;
        undef $media;
        undef %last_option;
        undef @options;
      } elsif (/^([01])(.*?)(?:\(([^()]*)\))?$/) {
        $single_choice = $1;
    
        $question = $2;
        chomp $question;
    
        $source = $3;
        chomp $source if $source;
      } elsif (/^@(.*)/) {
        $media = $1;
        chomp $media;
      } elsif (/^([-+?])\s*(.*)/) {
        add();
        %last_option =
          (
           "option"  => $2,
           "correct" => $1 eq "+" ? JSON::true : $1 eq "-" ? JSON::false : JSON::null
          );
      } elsif (/^.+$/) {		# non-empty line
        $last_option{"comment"} .= "$_\n";
      }
    }
    
    say (to_json @questions);