]> git.sur5r.net Git - i3/i3/blob - contrib/dump-asy.pl
866cf8e0361979ca652cb82c1451956215f9c5d0
[i3/i3] / contrib / dump-asy.pl
1 #!/usr/bin/env perl
2 # vim:ts=4:sw=4:expandtab
3
4 use strict;
5 use warnings;
6 use Data::Dumper;
7 use Getopt::Long;
8 use Pod::Usage;
9 use AnyEvent::I3;
10 use File::Temp;
11 use File::Spec;
12 use File::Basename;
13 use v5.10;
14 use IPC::Cmd qw[can_run];
15
16 my %options = (
17     gv => 1,
18     help => 0,
19 );
20 my $result = GetOptions(
21     "gv!" => \$options{gv},
22     "help|?" => \$options{help},
23 );
24
25 pod2usage(-verbose => 2, -exitcode => 0) if $options{help};
26
27 # prerequisites check so we can be specific about failures caused
28 # by not having these tools in the path
29 can_run('asy') or die 'Please install asymptote';
30 can_run('gv') or die 'Please install gv' unless !$options{gv};
31
32 my $i3 = i3();
33
34 my $tree = $i3->get_tree->recv;
35
36 my $tmp = File::Temp->new(UNLINK => 0, SUFFIX => '.asy');
37
38 say $tmp "import drawtree;";
39
40 say $tmp "treeLevelStep = 2cm;";
41
42 sub dump_node {
43         my ($n, $parent) = @_;
44
45     my $o = ($n->{orientation} eq 'none' ? "u" : ($n->{orientation} eq 'horizontal' ? "h" : "v"));
46     my $w = (defined($n->{window}) ? $n->{window} : "N");
47     my $na = ($n->{name} or "[Empty]");
48     $na =~ s/#/\\#/g;
49     $na =~ s/\$/\\\$/g;
50     $na =~ s/&/\\&/g;
51     $na =~ s/_/\\_/g;
52     $na =~ s/~/\\textasciitilde{}/g;
53     my $type = 'leaf';
54     if (!defined($n->{window})) {
55         $type = $n->{layout};
56     }
57     my $name = qq|``$na'' ($type)|;
58
59     print $tmp "TreeNode n" . $n->{id} . " = makeNode(";
60
61     print $tmp "n" . $parent->{id} . ", " if defined($parent);
62     print $tmp "\"" . $name . "\");\n";
63
64         dump_node($_, $n) for @{$n->{nodes}};
65 }
66
67 sub find_node_with_name {
68     my ($node, $name) = @_;
69
70     return $node if ($node->{name} eq $name);
71     for my $child (@{$node->{nodes}}) {
72         my $res = find_node_with_name($child, $name);
73         return $res if defined($res);
74     }
75     return undef;
76 }
77
78 my $start = shift;
79 my $root;
80 if ($start) {
81     # Find the specified node in the tree
82     $root = find_node_with_name($tree, $start);
83 } else {
84     $root = $tree;
85 }
86 dump_node($root);
87 say $tmp "draw(n" . $root->{id} . ", (0, 0));";
88
89 close($tmp);
90 my $rep = "$tmp";
91 $rep =~ s/asy$/eps/;
92 if ($options{gv}) {
93     my $tmp_dir = dirname($rep);
94     chdir($tmp_dir);
95 }
96 system("asy $tmp");  # Create the .eps file.
97 system("gv --scale=-1000 --noresize --widgetless $rep && rm $rep") if $options{gv};
98 system("rm $tmp");
99
100 __END__
101
102 =head1 NAME
103
104 dump-asy.pl - Render the layout tree using asymptote
105
106 =head1 SYNOPSIS
107
108 dump-asy.pl [workspace]
109
110 =head1 EXAMPLE
111
112 Render the entire tree, run:
113
114   ./dump-asy.pl
115
116 Render the tree starting from the node with the specified name, run:
117
118   ./dump-asy.pl 'name'
119
120 =head1 OPTIONS
121
122 =over 8
123
124 =item B<--gv>
125
126 =item B<--no-gv>
127
128 Enable or disable showing the result through gv. If disabled, an .eps file will
129 be saved in the current working directory. Enabled by default.
130
131 =back