{"thread":{"id":"7075","subject":"Amusement: ASCII Art generator","startedAt":"2007-03-04T01:44:00Z","lastAt":"2007-03-04T01:49:26Z","messageCount":2,"participants":["Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"36222","messageId":"Pine.LNX.4.63.0703040240190.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7075","inReplyTo":null,"subject":"Amusement: ASCII Art generator","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-04T01:44:00Z","receivedAt":"2007-03-04T01:44:00Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\na few days ago, I posted an ASCII representation of a commit graph. This \nwas really tedious, so I wrote a simple script to generate it (and also to \nprove that I am not making everything a builtin). It takes revision range \narguments, so if you call it with '-25 229ed74' on the git repository, you \nwill get this:\n\nA---C-----F---------------------Q---------------Y\n   /     /                     /               /\n  B   D-E   G-------K-------O-P---R---T-U-V-W-X\n                           /         ,-----'\n              H-I-J---L-M-N---------S\n\nNow, without further ado, the script.\n\n-- snipsnap --\n#!/usr/bin/perl\n\nif ($#ARGV < 1) {\n\tprint STDERR \"Usage: $ARGV0 <revision range>\\n\";\n\texit(1);\n}\n\nopen INPUT, 'git rev-list --parents ' . join(' ', @ARGV) . '|';\n\n%commits=();\n@list=();\n\nsub add_parents ($$) {\n\tmy $parents = $_[0];\n\tmy $y = $_[1];\n\tforeach my $parent (split / /,$parents) {\n\t\tif ($commits->{$parent} == undef) {\n\t\t\t$commits->{$parent} = {\n\t\t\t\t'y' => $y++,\n\t\t\t\t'sha1' => $parent\n\t\t\t};\n\t\t} else {\n\t\t\tif ($commits->{$parent}->{y} < $y) {\n\t\t\t\t$commits->{$parent}->{y} = $y++;\n\t\t\t} else {\n\t\t\t\t$y = $commits->{$parent}->{y} + 1;\n\t\t\t}\n\t\t}\n\t}\n}\n\n# expects output of `rev-list --parents --topo-order`\n$i = 0;\nwhile (<INPUT>) {\n\tif (/^([0-9a-f]{40}) ?(.*)$/) {\n\t\t$sha1 = $1;\n\t\t$parents = $2;\n\t\tif ($commits->{$sha1} == undef) {\n\t\t\t$commits->{$sha1} = {\n\t\t\t\t'y' => 0,\n\t\t\t\t'sha1' => $sha1,\n\t\t\t};\n\t\t} else {\n\t\t\t$commits->{$sha1}->{index} = $#list;\n\t\t}\n\t\t$commits->{$sha1}->{parents} = $parents;\n\t\t$list[$i] = $commits->{$sha1};\n\t\t$commits->{$sha1}->{index} = $i++;\n\t\tadd_parents($parents, $commits->{$sha1}->{y});\n\t}\n}\nclose INPUT;\n\nif ($#list >= 26) {\n\tprint STDERR \"Cannot draw more than 26 revs.\";\n\texit(1);\n}\n\n# make labels\n$height = 0;\nfor ($i = 0; $i <= $#list; $i++) {\n\t$list[$i]->{x} = $#list - $i;\n\t$list[$i]->{label} = chr(0x41 + $list[$i]->{x});\n\tif ($height < $list[$i]->{y}) {\n\t\t$height = $list[$i]->{y};\n\t}\n}\n\n# make a canvas\n$width = $#list * 2 + 1;\n$height = $height * 2 + 1;\n@canvas = ();\nfor ($i = 0; $i < $height; $i++) {\n\t$canvas[$i] = ' ' x $width . \"\\n\";\n}\n\nsub set_cell ($$$) {\n\tmy $x = $_[0];\n\tmy $y = $_[1];\n\tmy $c = $_[2];\n\t$canvas[$y] = substr($canvas[$y], 0, $x) . $c .\n\t\tsubstr($canvas[$y], $x + 1);\n}\n\nsub get_cell ($$) {\n\tmy $x = $_[0];\n\tmy $y = $_[1];\n\treturn substr($canvas[$y], $x, 1);\n}\n\nsub msg($) {\n\tmy $info = $_[0];\n\treturn $info->{label} . \": \" . $info->{x} . \", \" . $info->{y};\n}\n\nsub draw_line ($$) {\n\tmy $commit1 = $_[0];\n\tmy $commit2 = $_[1];\n\tmy $x1 = $commit1->{x};\n\tmy $y1 = $commit1->{y};\n\tmy $x2 = $commit2->{x};\n\tmy $y2 = $commit2->{y};\n\tif ($y1 == $y2) {\n\t\tfor (my $i = $x1 * 2 - 1; $i > $x2 * 2; $i--) {\n\t\t\tset_cell($i, $y1 * 2, \"-\");\n\t\t}\n\t} else {\n\t\tmy $is_straight = 0;\n\t\tmy $factor = ($y2 - $y1) / ($x1 - $x2);\n\t\tmy $i;\n\t\tif ($x1 - $x2 == $y2 - $y1) {\n\t\t\t$is_straight = 1;\n\t\t\tfor ($i = $x1 * 2 - 1; $i > $x2 * 2; $i -= 2) {\n\t\t\t\tmy $y = $y1 * 2 + ($x1 * 2 - $i) * $factor;\n\t\t\t\tmy $c = get_cell($i, int($y));\n\t\t\t\tif ($c ne ' ' && $c ne '-') {\n\t\t\t\t\t$is_straight = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ($is_straight) {\n\t\t\tfor ($i = $x1 * 2 - 1; $i > $x2 * 2; $i--) {\n\t\t\t\tmy $y = $y1 * 2 + ($x1 * 2 - $i) * $factor;\n\t\t\t\tmy $c = (get_cell($i, int($y)) ne ' ') ?\n\t\t\t\t\t'+' : '/';\n\t\t\t\tset_cell($i, int($y), $c);\n\t\t\t}\n\t\t} else {\n\t\t\tset_cell($x1 * 2 - 1, $y1 * 2 + 1, '\\'');\n\t\t\tfor ($i = $x1 * 2 - 2; $i > $x2 * 2 + 1; $i--) {\n\t\t\t\tset_cell($i, $y1 * 2 + 1, '-');\n\t\t\t}\n\t\t\tset_cell($x2 * 2 + 1, $y1 * 2 + 1, ',');\n\t\t\tfor ($i = $y1 * 2 + 2; $i < $y2 * 2; $i++) {\n\t\t\t\tmy $c = (get_cell($x2 * 2, $i) ne ' ') ?\n\t\t\t\t\t'+' : '|';\n\t\t\t\tset_cell($x2 * 2, $i, $c);\n\t\t\t}\n\t\t}\n\t}\n}\n\n# draw it\nfor ($i = 0; $i <= $#list; $i++) {\n\t$info = $list[$i];\n\t$x = $info->{x} * 2;\n\t$y = $info->{y} * 2;\n\tset_cell ($x, $y, $info->{label});\n\tforeach my $parent (split / /,$info->{parents}) {\n\t\tif ($commits->{$parent}->{index} != undef) {\n\t\t\tdraw_line($info, $commits->{$parent});\n\t\t}\n\t}\n}\n\nprint @canvas;\n"},{"id":"36223","messageId":"Pine.LNX.4.63.0703040245540.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7075","inReplyTo":"Pine.LNX.4.63.0703040240190.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Amusement: ASCII Art generator","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-04T01:49:26Z","receivedAt":"2007-03-04T01:49:26Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 4 Mar 2007, Johannes Schindelin wrote:\n\n> Hi,\n> \n> a few days ago, I posted an ASCII representation of a commit graph. This \n> was really tedious, so I wrote a simple script to generate it (and also to \n> prove that I am not making everything a builtin). It takes revision range \n> arguments, so if you call it with '-25 229ed74' on the git repository, you \n> will get this:\n> \n> A---C-----F---------------------Q---------------Y\n>    /     /                     /               /\n>   B   D-E   G-------K-------O-P---R---T-U-V-W-X\n>                            /         ,-----'\n>               H-I-J---L-M-N---------S\n\nSidenote: this script is really dumb, and checks collisions only \noccasionally, but it works sometimes. Obviously, I chose an example where \nit works :-)\n\nCiao,\nDscho\n"}]}