捕获并执行多行代码并将结果合并到raku中

Sum*_*nal 5 regex replace perl6 capturing-group raku

这是一个降价文件example.md我有:

## New language

Raku is a new language different from Perl.

## what does it offer
+ Object-oriented programming including generics, roles and multiple dispatch
+ Functional programming primitives, lazy and eager list evaluation, junctions, autothreading and hyperoperators (vector operators)
+ Parallelism, concurrency, and asynchrony including multi-core support
+ Definable grammars for pattern matching and generalized string processing
+ Optional and gradual typing



This code will be evaluated.


```{raku evaluate=TRUE}
4/5
```



Rakudo is a compiler for raku programming language. Install it and you're all set to run raku programs!

This code will be evaluated.

```{raku evaluate=TRUE}
say "this is promising";
say $*CWD;
```



This code will **not** be evaluated.


```{raku evaluate=FALSE}
say "Hello world";
```
Run Code Online (Sandbox Code Playgroud)

我想将其转换为example.md,如下所示,其中包含代码和输出。

## New language

Raku is a new language different from Perl.

## what does it offer
+ Object-oriented programming including generics, roles and multiple dispatch
+ Functional programming primitives, lazy and eager list evaluation, junctions, autothreading and hyperoperators (vector operators)
+ Parallelism, concurrency, and asynchrony including multi-core support
+ Definable grammars for pattern matching and generalized string processing
+ Optional and gradual typing



This code will be evaluated.

Code:
```{raku evaluate=TRUE}
4/5
```

Output:
```
0.8
```

Rakudo is a compiler for raku programming language. Install it and you're all set to run raku programs!

This code will be evaluated.

Code:
```{raku evaluate=TRUE}
say "this is promising";
say $*CWD;
```

Output:
```
this is promising
"C:\Users\suman".IO
```

This code will **not** be evaluated.

Code:
```{raku evaluate=FALSE}
say "Hello world";
```
Run Code Online (Sandbox Code Playgroud)

我要完成的是:

  • 捕捉代码之间backticks{raku evaluate}backticks
  • 如果评估为TRUE,则执行代码
  • 插入代码并输出回文档中

我试图做的是:

  1. 捕获多行代码并评估表达式
my $array= 'example.md'.IO.slurp;

#multiline capture code chunk and evaluate separately
if $array~~/\`\`\`\{raku (.*)\}(.*)\`\`\`/ {
    #the first capture $0 will be evaluate
    if $0~~"TRUE"{
        #execute second capture which is code chunk which is captured in $1
        }else {
       # don't execute code
        };
};
Run Code Online (Sandbox Code Playgroud)
  1. 创建一个temp.p6文件,并从上方将代码块$ 1写入其中
my $fh="temp.p6".IO.spurt: $1;
Run Code Online (Sandbox Code Playgroud)
  1. 如果$ 0为TRUE,则执行块
my $output= q:x/raku temp.p6/ if $0==TRUE
Run Code Online (Sandbox Code Playgroud)
  1. 在我们创建中间example_new.md时,将所有这些都集成到最终的example.md中
my $fh-out = open "example_new.md", :w; # Create a new file

# Print out next file, line by line
for "$file.tex".IO.lines -> $line {

    # write output of code to example_new.md

}
$fh-out.close;

# copy
my $io = IO::Path.new("example_new.md");
$io.copy("example.md");

# clean up
unlink("example.md");

# move
$io.rename("example.md");

Run Code Online (Sandbox Code Playgroud)

我被困在第一步。有什么帮助吗?

mor*_*itz 6

有两种执行代码并捕获输出的方式:

  • 您可以将其写入临时文件并用于my $result = qqx{perl6 $filename}生成单独的进程
  • 您可以使用EVAL,在同一解释器中执行代码,并使用IO :: Capture :: Simple捕获STDOUT:
my $re = regex {
    ^^ # logical newline
    '```{perl6 evaluate=' (TRUE|FALSE) '}'
    $<code>=(.*?)
    '```'
}

for $input.match(:global, $re) -> $match {
    if $match[0] eq 'TRUE' {
        use IO::Capture::Simple;
        my $result = capture_stdout {
            use MONKEY-SEE-NO-EVAL;
            EVAL $match<code>;
        }
        # use $result now
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您只需要从切换matchsubst并从要替换的那个块中返回值,就可以完成。

我希望这可以使您知道如何进行。


rai*_*iph 5

完成“我想完成的事情”的代码

您可以使用glot.io对数据运行此代码

use v6;

constant $ticks = '```';

my regex Search {
  $ticks '{perl6 evaluate=' $<evaluate>=(TRUE|FALSE) '}'
  $<code>=[<!before $ticks> .]*
  $ticks
}

sub Replace ($/) {
  "Code:\n" ~ $ticks ~ $<code> ~ $ticks ~
    ($<evaluate> eq 'TRUE'
      ?? "\n\n" ~ 'Output:' ~ "\n" ~ $ticks ~ "\n" ~ Evaluate($<code>) ~ $ticks
      !! '');
}

sub Evaluate ($code) {
  my $out; my $*OUT = $*OUT but role { method print (*@args) { $out ~= @args } }
  use MONKEY; my $eval-result = EVAL $code;
  $out // $eval-result ~ "\n"
}

spurt
  'example_new.md',
  slurp('example.md')
    .subst: &Search, &Replace, :g;
Run Code Online (Sandbox Code Playgroud)

说明

从底部开始,然后向上工作:

  • .subst方法替换其主语字符串中需要替换的部分,并返回修改后的字符串。.subst的第一个参数是匹配器;它可以是字符串,也可以是正则表达式&Search-1.subst第二个参数是替换项;这也可以是字符串,也可以是Callable- &Replace。如果是,Callable则将.subst来自匹配器的匹配作为匹配对象2作为第一个参数传递给Callable。该:g副词引导.subst做搜索/替换反复尽可能多的比赛,因为有在调用者的字符串。

  • slurp从文件一次生成一个字符串。不需要open,使用手柄close等。在这种情况下,其结果成为上述.subst说明的主题。

  • spurt相反,从字符串一次生成一个文件,在这种情况下是slurp(...).subst...操作的结果。

  • Evaluate例程生成一个字符串,该字符串是评估传递给它的代码字符串的输出。为了获取评估结果,它会临时修改P6的STDOUT变量$*OUT,在编写代码之前将prints(因此也将says等)重定向到内部变量。如果结果是d ,则返回;如果不是,则返回的结果(由强制为字符串)。(在第二种情况下添加了换行符,但没有在第一种情况下添加换行符,因为考虑到示例中的“指定”方式,这是获得正确显示结果所必需的。)$outEVALEVALprint$outEVAL~

  • Replace例程从Code正则表达式的调用中传递了一个match对象。它使用$<code>捕获来重建代码段(不带评估位)。如果$<evaluate>捕获了,'TRUE'那么它还将Output:使用Evaluate上面解释的例程附加一个新鲜的部分,以产生代码的输出。

  • Code正则表达式匹配代码段。它捕获TRUEFALSE设置与评估指令到一个名为捕获$<evaluate>和代码到一个名为捕获$<code>

脚注

1要传递例程(正则表达式是例程)而不是调用例程,必须使用符号(&foo)而不是(foo)编写该例程。

2即使匹配器只是一个字符串,它也会这样做!