Skip to content

Instantly share code, notes, and snippets.

@tksmiura
Last active January 6, 2018 08:43
Show Gist options
  • Save tksmiura/761e1b21452bed37d77ac54c201f46e4 to your computer and use it in GitHub Desktop.
Save tksmiura/761e1b21452bed37d77ac54c201f46e4 to your computer and use it in GitHub Desktop.
Create flowchart from comment

Create flowchart from comment

#!/usr/bin/perl
#flow chart
use utf8;
#use Encode;
use Class::Struct;
use Data::Dumper;
# syntax
# use "///" prefix for read flow
#
# start
# ///* function
#
# sequence
# /// a = b
#
# function call
# /// [submodule]
#
# loop
# ///{ cond > 0
#
# branch
# ///|> cond1 == false
#
# /// a = 1
# ///>
# /// a = 2
# ///>|
#
# loop end
# ///}
#
# end
# ///**
#形状パラメータ
$FontWidth = 5; # font幅(半角)
$FontWidthJ = 10; # 全角
$FontHeight = 10;
$FontSizeS = 8; # font(small)
$SeqWidth = 150; # ボックスの幅
$BoxPadding = 4; # パディング(内側の隙間)
$SeqMargin = 8; # シーケンス間のマージン
$DiaHeight = 32; # 分岐(菱側の高さ)
$SideMargin = 40; # 分岐間の横方向のマージン
$ArrowLength = 5; # 矢印の長さ
$ArrowWidth = 2; # 矢印の幅
$FuncPadding = 5; # 関数の2重線の隙間
$PageMargin = 10;
struct Node => {
type => '$', x => '$', y => '$', mid_x => '$', width => '$', height => '$',
text => '$', style => '$', blocks => '@', selectors => '@',
};
$While = 1;
$EndLoop =2;
$If = 3;
$Else = 4;
$EndIf = 5;
$Func = 6;
$Seq = 7;
$Begin = 8;
$End = 9;
$Eof = 10;
$Branch = 11;
$Loop = 12;
$DoWhile = 13;
$Debug = 0;
foreach $infile (@ARGV) {
print "flow chart input $infile \n";
open(FILE, "<$infile") || die "Can't open to $infile";
$Line = 0;
&Readline();
while ($Line == $Begin) {
# parse function block
my ($begin) = &CreateSequence($Text, $Begin);
$Outfile = $Text . ".svg";
print "create $Outfile\n";
&Readline();
my ($block) = &ParseBlock();
if ($Line != $End) {
die "syntax error $LineNum near $Line $Text in main\n";
};
&Readline();
my ($end) = &CreateSequence("", $End);
my (@work) = ( $begin, @$block, $end );
$ref_block_all = \@work;
$Debug && print Dumper($ref_block_all);
# fix position
my($width, $height) =
&Position($PageMargin,$PageMargin,$ref_block_all);
$width += $PageMargin*2;
$height += $PageMargin*2;
@block0 = @$ref_block_all;
$Debug && print Dumper(@block0);
# draw svg flow chart
&DrawFlow($Outfile, $width, $height, $ref_block_all);
}
if ($Line != $Eof) {
#$ref_block_all = &ParseBlock();
die "syntax error $LineNum near $Line $Text in main\n";
}
close(FILE);
print "complete\n";
}
exit 0;
sub ParseBlock {
$Debug && print "ParseBlock\n";
my (@block) = ();
while ($Line == $Seq || $Line == $Func ||
$Line == $If || $Line == $While) {
if ($Line == $Seq) { # 通常文
my($seq) = &CreateSequence($Text);
push(@block, $seq);
&Readline();
} elsif ($Line == $Func) {
my($seq) = &CreateSequence($Text, $Func);
push(@block, $seq);
&Readline();
} elsif ($Line eq $If) {
my($seq) = &ParseIf();
push(@block, $seq);
} elsif ($Line == $While) {
my($seq) = &ParseWhile();
push(@block, $seq);
}
}
return \@block;
}
sub ParseIf {
$Debug && print "ParseIf $Text\n";
my ($condition) = $Text;
my @ref_blocks;
my $ref_block;
my @Selectors;
push(@Selectors, $Selector);
&Readline();
$ref_block = &ParseBlock();
push(@ref_blocks, $ref_block);
while ($Line == $Else) {
push(@Selectors, $Selector);
&Readline();
$ref_block = &ParseBlock();
push(@ref_blocks, $ref_block);
}
if ($Line == $EndIf) {
&Readline();
} else {
die "syntax error $LineNum near $Line $Text in if\n";
}
return &CreateBranch($condition, \@ref_blocks, \@Selectors);
}
sub ParseWhile {
$Debug && print "ParseWhile $Text\n";
my $condition = $Text;
my $do_while = 0;
&Readline();
my ($ref_block) = &ParseBlock();
if ($Line == $EndLoop) {
if (!$condition) {
$condition = $Text;
$do_while = 1;
}
&Readline();
} else {
die "syntax error $LineNum near $Line $Text in loop\n";
}
return &CreateLoop($condition,$ref_block, $do_while);
}
#構造作成
sub CreateSequence {
my ($text,$style) = @_;
my $seq = Node->new();
my $w = 0;
my $h = 0;
my ($ch, $l, $w_max);
$w_max = $SeqWidth;
foreach $l (split /\n/, $text) {
foreach $ch (split //, $l) {
if ($ch =~ /[\x20-\x7f]/) {
$w += $FontWidth;
} elsif ($ch =~ /\n/) {
$h += $FontHeight;
} else {
$w += $FontWidthJ;
}
}
if ($w_max < $w) {
$w_max = $w;
}
$h += $FontHeight;
}
if ($h == 0) {
$h = $FontHeight;
}
$seq->type($Seq);
$seq->x(0);
$seq->y(0);
$seq->mid_x($w_max / 2);
$seq->width($w_max);
if ($style eq $Begin) {
$seq->height($h + $BoxPadding * 2 + $SeqMargin);
} elsif ($style eq $End) {
$seq->height($h + $BoxPadding * 2);
} else {
$seq->height($h + $BoxPadding * 2 + $SeqMargin * 2);
}
$seq->text($text);
$seq->style($style);
return $seq; # 参照を返す
}
sub CreateBranch {
my ($text,$ref_blocks) = @_;
my (@ref_blocks) = @$ref_blocks;
my @width, @height, @mid_x;
my $i = 0;
my $w = 0;
my $h = 0;
my $seq = Node->new();
foreach $ref_block (@ref_blocks) {
($width[$i], $height[$i], $mid_x[$i]) = &SizeOfBlock($ref_block);
$w += $width[$i];
if ($h < $height[$i]) {
$h = $height[$i];
}
$seq->blocks($i, $ref_block);
$i ++;
}
$w += $SideMargin * ($i - 1);
if ($i == 1) {
$w += $SideMargin;
}
$seq->type($Branch);
$seq->x(0);
$seq->y(0);
$seq->mid_x($mid_x[0]);
$seq->width($w);
$seq->height($h + $DiaHeight + $SeqMargin * 3);
$seq->text($text);
return $seq; # 参照を返す
}
sub CreateLoop {
my ($text, $ref_block, $do_while) = @_;
my ($width, $height, $mid_x) = &SizeOfBlock($ref_block);
my $seq = Node->new();
$seq->x(0);
$seq->y(0);
$seq->text($text);
$seq->blocks(0, $ref_block);
if (!$do_while) {
$seq->type($Loop);
$seq->mid_x($mid_x + $SideMargin);
$seq->width($width + $SideMargin * 2);
$seq->height($height + $DiaHeight + $SeqMargin * 5);
} else {
$seq->type($DoWhile);
$seq->mid_x($mid_x + $SideMargin);
$seq->width($width + $SideMargin);
$seq->height($height + $DiaHeight + $SeqMargin * 2);
}
return $seq; # 参照を返す
}
# Size
sub SizeOfBlock {
my ($ref_block) = @_;
my ($width) = $SeqWidth;
my ($height) = 0;
my ($left) = $width / 2;
my ($right) = $width / 2;
my ($ref_seq);
foreach $ref_seq (@$ref_block) {
if ($left < $ref_seq->mid_x) {
$left = $ref_seq->mid_x;
}
if ($right < $ref_seq->width - $ref_seq->mid_x) {
$right = $ref_seq->width - $ref_seq->mid_x;
}
$height += $ref_seq->height;
}
$width = $left + $right;
return ($width, $height, $left);
}
#位置を決定する
sub Position {
my ($x0,$y0,$ref_block) = @_;
my ($width, $height, $mid_x) = &SizeOfBlock($ref_block);
my ($cur_y) = $y0;
$Debug && print "Position $width, $height, $mid_x\n";
foreach $ref_seq (@$ref_block) {
$ref_seq->x($x0 + $mid_x - $ref_seq->mid_x);
$ref_seq->y($cur_y);
$cur_y += $ref_seq->height;
if ($ref_seq->type == $Loop) {
&Position($ref_seq->x + $SideMargin,
$ref_seq->y + $DiaHeight + $SeqMargin * 3,
$ref_seq->blocks(0));
} elsif ($ref_seq->type == $DoWhile) {
&Position($ref_seq->x + $SideMargin,
$ref_seq->y,
$ref_seq->blocks(0));
} elsif ($ref_seq->type == $Branch) {
my $offset_x = 0;
my $ref_block;
my $w1, $h1;
my $count = 0;
while ($ref_block = $ref_seq->blocks($count++)) {
($w1, $h1) = &Position($ref_seq->x + $offset_x,
$ref_seq->y + $DiaHeight +$SeqMargin * 2,
$ref_block); # ???
$offset_x += $w1 + $SideMargin;
}
}
}
return ($width,$height);
}
#字句解析部(行単位)
sub Readline {
my($l, $no_match);
# my $Debug = 1;
$Line = 0;
$Text = "";
$Selector = "";
$no_match = 0;
while ($Line == 0 || ($Line !=0 && $no_match == 0)) {
if (eof(FILE)) {
$Line = $Eof;
$Debug && print "Read(EOF)\n";
return;
}
$l = <FILE>;
$LineNum = $.;
if ($l =~ /\/\/\/\{\s*(.*)\s*$/) { # ///{
$Line = $While;
$Text = $1;
$Debug && print "Read($Line):$Text\n";
return;
} elsif ($l =~ /\/\/\/\}\s*(.*)\s*$/) { # ///}
$Line = $EndLoop;
$Text = $1;
$Debug && print "Read($Line):$Text\n";
return;
} elsif ($l =~ /\/\/\/\|>\s*([^\:]*)(\:(.*)|)\s*$/) { # ///|>
$Line = $If;
$Text = $1;
$Selector = $3;
$Debug && print "Read($Line):$Text\n";
return;
} elsif ($l =~ /\/\/\/>(\s+(.*)\s*|)$/) { # ///>
$Line = $Else;
$Text = "";
$Selector = $2;
$Debug && print "Read($Line): $Text\n";
return;
} elsif ($l =~ /\/\/\/>\|$/) { # ///>|
$Line = $EndIf;
$Debug && print "Read($Line)\n";
return;
} elsif ($l =~ /\/\/\/\s+\[([^\]]*)\]$/) { # /// [func]
$Line = $Func;
$Text = $1;
$Debug && print "Read($Line):$Text\n";
return;
} elsif ($l =~ /\/\/\/\*\s+([^\s]*)/) { # ///* name
$Line = $Begin;
$Text = $1;
$Debug && print "Read($Line):'$Text'\n";
return;
} elsif ($l =~ /\/\/\/\*\*/) { # ///**
$Line = $End;
$Text = $1;
$Debug && print "Read($Line):$Text\n";
return;
} elsif ($l =~ /\/\/\/\s+([^\s].*)$/) { # /// sequence
if ($Line != $Seq) {
$Line = $Seq;
$Text = $1;
} else {
$Text .= "\n$1";
}
$no_match = 0;
} else {
$no_match = 1;
}
}
$Debug && print "Read($Line):$Text\n";
return;
}
##################################################################
#SVG
sub DrawFlow {
my ($out_file, $width, $height, $ref_block) =@_;
open(OUT, ">:utf8", $out_file) || die "Can't open to $out_file\n"; # FILEを開く(utf8)
&StartPage($width, $height);
&DrawBlock($ref_block);
&EndPage();
close(OUT);
}
sub DrawBlock {
my ($ref_block) = @_;
foreach $ref_seq (@$ref_block) {
my($type) = $ref_seq->type;
if ($type == $Seq) {
$Debug && &TestBox($ref_seq->x,$ref_seq->y,
$ref_seq->width,$ref_seq->height);
&DrawSequence($ref_seq);
} elsif ($type == $Branch) {
$Debug && &TestBox($ref_seq->x,$ref_seq->y,
$ref_seq->width,$ref_seq->height);
&DrawBranch($ref_seq);
my $block;
my $count = 0;
while ($block = $ref_seq->blocks($count++)) {
&DrawBlock($block); # ???
}
} elsif ($type == $Loop) {
$Debug && &TestBox($ref_seq->x,$ref_seq->y,
$ref_seq->width,$ref_seq->height);
&DrawLoop($ref_seq);
&DrawBlock($ref_seq->blocks(0));
} elsif ($type == $DoWhile) {
$Debug && &TestBox($ref_seq->x,$ref_seq->y,
$ref_seq->width,$ref_seq->height);
&DrawDoWhile($ref_seq);
&DrawBlock($ref_seq->blocks(0));
}
}
}
sub DrawLoop {
my ($ref_seq) = @_;
my ($x,$y,$mid_x,$width,$height) = ($ref_seq->x,$ref_seq->y,
$ref_seq->mid_x,
$ref_seq->width,$ref_seq->height);
$Debug && print "DrawLoop $x, $y, $width, $height, $mid_x\n";
my ($text) = sprintf("%16.16s", $ref_seq->text);
my ($cx) = $x + $mid_x;
my ($cy) = $y + $SeqMargin * 2 + $DiaHeight / 2;
my ($ty) = $cy + $FontHeight / 2;
my ($x_out) = $x + $width;
my ($bottom_y) = $y + $height;
&Polyline($cx,$y,$cx,$y + $DiaHeight + $SeqMargin * 3);
&Diamond($cx, $y + $SeqMargin*2, $SeqWidth, $DiaHeight);
&Text($cx,$ty, $text);
&TextSmall($cx - $FontSizeS*2 ,$cy + $DiaHeight/2 + $FontSizeS, "YES");
&TextSmall($cx + $SeqWidth/2 + $FontSizeS*2 ,$cy - 2, "NO");
&Polyline($cx + $SeqWidth/2, $cy,
$x_out, $cy,
$x_out, $bottom_y - $SeqMargin,
$cx, $bottom_y - $SeqMargin,
$cx, $bottom_y);
&PolylineA($cx, $bottom_y - $SeqMargin*2,
$x, $bottom_y - $SeqMargin*2,
$x, $y + $SeqMargin,
$cx, $y + $SeqMargin);
}
sub DrawDoWhile {
my ($ref_seq) = @_;
my ($x,$y,$mid_x,$width,$height) = ($ref_seq->x,$ref_seq->y,
$ref_seq->mid_x,
$ref_seq->width,$ref_seq->height);
$Debug && print "DrawDoWhile $x, $y, $width, $height, $mid_x\n";
my ($text) = sprintf("%16.16s", $ref_seq->text);
my ($cx) = $x + $mid_x;
my ($cy) = $y + $height - $SeqMargin - $DiaHeight / 2;
my ($ty) = $cy + $FontHeight / 2;
my ($bottom_y) = $y + $height;
&Polyline($cx,$cy - $DiaHeight / 2 - $SeqMargin, $cx, $bottom_y);
&Diamond($cx, $cy - $DiaHeight / 2, $SeqWidth, $DiaHeight);
&Text($cx,$ty, $text);
&TextSmall($cx - $FontSizeS*2 ,$cy + $DiaHeight/2 + $FontSizeS, "NO");
&TextSmall($cx - $SeqWidth/2 - $FontSizeS*3 ,$cy - 2, "YES");
&PolylineA($cx - $SeqWidth/2 , $cy,
$x, $cy,
$x, $y,
$cx, $y);
}
# branch loop width{0|1}の処理が必要
sub DrawBranch {
my ($ref_seq) = @_;
my ($x,$y,$mid_x,$width,$height) = ($ref_seq->x,$ref_seq->y,
$ref_seq->mid_x,
$ref_seq->width,$ref_seq->height);
my ($text) = sprintf("%16.16s", $ref_seq->text);
my $cx = $x + $mid_x; # 中央x位置
my $cy = $y + $SeqMargin + $DiaHeight / 2; # 分岐の中央Y位置
my $ty = $cy + $FontHeight / 2; # テキスト表示位置
my $ref_block;
my $last_x;
&Polyline($cx, $y, $cx, $y + $SeqMargin); # 矩形直上の線
&Diamond($cx, $y + $SeqMargin, $SeqWidth, $DiaHeight); # 矩形
&Text($cx,$ty, $text);
&Polyline($cx, $cy + $DiaHeight/2,
$cx, $cy + $DiaHeight/2 + $SeqMargin); # 矩形直下の線
my $count = 0;
while ($ref_block = $ref_seq->blocks($count++)) {
my ($bw, $bh, $bmid_x) = &SizeOfBlock($ref_block); # ???
my $top = $$ref_block[0];
my $y;
$last_x = $top->x + $top->mid_x;
if ($count > 1) {
&Polyline($last_x, $cy, # 分岐直上の線
$last_x, $top->y);
&Polyline($last_x, $top->y + $bh, # 分岐直下の線
$last_x, $ref_seq->y + $ref_seq->height - $SeqMargin);
} else {
&Polyline($last_x, $top->y + $bh,
$last_x, $ref_seq->y + $ref_seq->height);
}
# &TextSmall($cx - $FontSizeS * 2 ,
# $cy + $SeqMargin + $DiaHeight / 2 , "YES");
# &TextSmall($cx + $SeqWidth/2 + $FontSizeS*2 ,$cy - 2, "NO");
}
$count --;
if ($count == 1) {
&TextSmall($cx - $FontSizeS*2 ,$cy + $DiaHeight/2 + $FontSizeS, "YES");
&TextSmall($cx + $SeqWidth/2 + $FontSizeS*2 ,$cy - 2, "NO");
$Debug && print "DrawBranch $x $y $width $height\n";
&PolylineA($cx + $SeqWidth/2, $cy,
$x + $width, $cy,
$x + $width, $y + $height - $SeqMargin,
$cx, $y + $height - $SeqMargin);
} else {
&Polyline($cx + $SeqWidth/2, $cy,
$last_x, $cy);
&PolylineA($last_x, $y + $height - $SeqMargin,
$cx , $y + $height - $SeqMargin);
}
}
sub Diamond {
my($cx,$y,$w,$h) = @_; # 始点は中央上
my($x2,$y2,$x3,$y3) = ($cx + $w/2, $y + $h/2, $cx - $w/2, $y + $h);
print OUT <<END_OF_DATA;
<polygon points="$cx $y, $x2 $y2, $cx $y3, $x3 $y2" fill="orangered" stroke="black" />
END_OF_DATA
}
sub DrawSequence {
my ($ref_seq) = @_;
my ($x, $y, $width, $height, $mid_x, $text, $style) =
($ref_seq->x, $ref_seq->y,
$ref_seq->width, $ref_seq->height,
$ref_seq->mid_x, $ref_seq->text,
$ref_seq->style);
my ($cx) = $x + $mid_x;
my $t;
$Debug && print "DrawSequence $x, $y, $width, $height, $mid_x, $text, $style\n";
if ($style eq $Begin) {
&Polyline($cx, $y + $height - $SeqMargin, $cx, $y + $height);
&RoundBox($x, $y, $width, $FontHeight * 1 + $BoxPadding * 2);
} elsif ($style == $End) {
&Polyline($cx, $y, $cx, $y + $SeqMargin);
$y += $SeqMargin;
&RoundBox($x, $y, $width, $FontHeight * 1 + $BoxPadding * 2);
$text = "END";
} else {
&Polyline($cx, $y, $cx, $y + $height);
$y += $SeqMargin;
if ($style == $Func) {
&BoxF($x, $y, $width, $height - $SeqMargin * 2);
} else {
&Box($x, $y, $width, $height - $SeqMargin * 2);
}
}
foreach $t (split /\n/, $text) {
&Text($cx, $y + $FontHeight * 1 + $BoxPadding, $t);
$y += $FontHeight;
}
}
#Pageの始め
sub StartPage {
my ($width, $height) = @_;
print OUT <<END_OF_DATA;
<?xml version="1.0" standalone="no"?>
<svg width="$width" height="$height" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g transform="scale(1.0)">
END_OF_DATA
}
#Pageの終わり
sub EndPage {
print OUT <<END_OF_DATA;
</g>
</svg>
END_OF_DATA
}
#描画プリミティブ
#ボックス(処理内容)
sub Box {
my($x,$y,$w,$h) = @_;
print OUT <<END_OF_DATA;
<rect x="$x" y="$y" width="$w" height="$h" fill="white" stroke="black" />
END_OF_DATA
}
#ボックス(関数呼び出し)
sub BoxF {
my($x,$y,$w,$h) = @_;
my($x1,$w1) = ($x + $FuncPadding,$w - $FuncPadding*2);
print OUT <<END_OF_DATA;
<rect x="$x" y="$y" width="$w" height="$h" fill="slateblue" stroke="black" />
<rect x="$x1" y="$y" width="$w1" height="$h" fill="slateblue" stroke="black" />
END_OF_DATA
}
#角丸のボックス(開始・終了ノード)
sub RoundBox {
my($x,$y,$w,$h) = @_;
my ($r) = $h/2;
print OUT <<END_OF_DATA;
<rect x="$x" y="$y" width="$w" height="$h" rx="$r" fill="white" stroke="black" />
END_OF_DATA
}
#文字列表示(通常サイズ)
sub Text {
my ($x, $y, $text) = @_;
my ($text2) = &XMLText($text);
print OUT <<END_OF_DATA;
<text text-anchor="middle" x="$x" y="$y" font-size="$FontSize" >
$text2
</text>
END_OF_DATA
}
#文字列表示(小サイズ)=分岐先
sub TextSmall {
my ($x, $y, $text) = @_;
my ($text2) = &XMLText($text);
print OUT <<END_OF_DATA;
<text text-anchor="middle" x="$x" y="$y" font-size="$FontSizeS" >
$text2
</text>
END_OF_DATA
}
#ライン
sub Polyline {
my(@lines) = @_;
my ($x,$y);
$x = shift(@lines);
$y = shift(@lines);
my ($points) = "$x $y";
while (@lines) {
$x = shift(@lines);
$y = shift(@lines);
$points = $points . ", $x $y";
}
print OUT <<END_OF_DATA;
<polyline points="$points" fill="none" stroke="black" />
END_OF_DATA
}
#ライン(矢印付き)
sub PolylineA {
my(@lines) = @_;
my ($x,$y,$x2,$y2,$x3,$y3);
my($num) = $#lines;
my ($dx) = $lines[$num-1] - $lines[$num-3];
my ($dy) = $lines[$num] - $lines[$num-2];
if (abs($dx) > abs($dy)) {
$x2 = ($dx > 0) ? $lines[$num-1] - $ArrowLength : $lines[$num-1] + $ArrowLength;
$y2 = $lines[$num] + $ArrowWidth;
$x3 = $x2;
$y3 = $lines[$num] - $ArrowWidth;
} else {
$x2 = $lines[$num-1] + $ArrowWidth;
$y2 = ($dy > 0) ? $lines[$num] - $ArrowLength : $lines[$num-1] + $ArrowLength;
$x3 = $lines[$num-1] - $ArrowWidth;
$y3 = $y2;
}
$x = shift(@lines);
$y = shift(@lines);
my ($points) = "$x $y";
while (@lines) {
$x = shift(@lines);
$y = shift(@lines);
$points = $points . ", $x $y";
}
print OUT <<END_OF_DATA;
<polyline points="$points" fill="none" stroke="black" />
<polygon points="$x $y, $x2, $y2, $x3 $y3" fill="black" stroke="black" />
END_OF_DATA
}
sub PolylineDebug {
my(@lines) = @_;
my ($x,$y);
$x = shift(@lines);
$y = shift(@lines);
my ($points) = "$x $y";
while (@lines) {
$x = shift(@lines);
$y = shift(@lines);
$points = $points . ", $x $y";
}
print OUT <<END_OF_DATA;
<polyline points="$points" fill="none" stroke="red" />
END_OF_DATA
print <<END_OF_DATA;
debug: <polyline points="$points" fill="none" stroke="red" />
END_OF_DATA
}
#テスト用BOX
sub TestBox {
my($x, $y, $width, $height) = @_;
print OUT <<END_OF_DATA;
<rect x="$x" y="$y" width="$width" height="$height" fill="none" stroke="red"/>
END_OF_DATA
}
#XMLの特殊文字変換
sub XMLText {
local($text) =@_;
$text =~ s/\&/\&amp\;/g; # '&' → '&amp'
$text =~ s/\</\&lt\;/g; # '<' → '&lt'
$text =~ s/\>/\&gt\;/g; # '>' → '&gt'
return ($text);
}
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
start
///* function
sequence
/// a = b
sequence multi line
/// this is a test
/// this is a test
function call
/// [submodule]
loop
///{ cond > 0
branch
///
///|> cond1
/// a = 1
///>|
branch 2
///|> cond2 == false
/// b = 1
///>
/// b = 2
///>|
branch n
///|> cond3 : 'A'
/// c = A
///> 'B'
/// c = B
///> 'C'
/// c = C
///>|
loop end
///}
end
///**
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment