]> git.sur5r.net Git - i3/i3/blob - contrib/dump-asy.pl
5af4c72f313763a7fb6a459ba59cada1d273d2c2
[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     save => undef,
19     help => 0,
20 );
21 my $result = GetOptions(
22     "gv!" => \$options{gv},
23     "save=s" => \$options{save},
24     "help|?" => \$options{help},
25 );
26
27 pod2usage(-verbose => 2, -exitcode => 0) if $options{help};
28
29 # prerequisites check so we can be specific about failures caused
30 # by not having these tools in the path
31 can_run('asy') or die 'Please install asymptote';
32 can_run('gv') or die 'Please install gv' unless !$options{gv};
33
34 my $i3 = i3();
35
36 my $tree = $i3->get_tree->recv;
37
38 my $tmp = File::Temp->new(UNLINK => 0, SUFFIX => '.asy');
39
40 say $tmp "import drawtree;";
41
42 say $tmp "treeLevelStep = 2cm;";
43
44 sub dump_node {
45         my ($n, $parent) = @_;
46
47     my $o = ($n->{orientation} eq 'none' ? "u" : ($n->{orientation} eq 'horizontal' ? "h" : "v"));
48     my $w = (defined($n->{window}) ? $n->{window} : "N");
49     my $na = ($n->{name} or ($n->{type} eq "floating_con" ? "[Floating con]" : "[Empty]"));
50     $na =~ s/#/\\#/g;
51     $na =~ s/\$/\\\$/g;
52     $na =~ s/&/\\&/g;
53     $na =~ s/_/\\_/g;
54     $na =~ s/~/\\textasciitilde{}/g;
55     my $type = 'leaf';
56     if (!defined($n->{window})) {
57         $type = $n->{layout};
58     }
59     my $marks = $n->{marks} ? ' [' . join('][', @{$n->{marks}}) . ']' : '';
60     my $name = qq|``$na'' ($type)$marks|;
61
62     print $tmp "TreeNode n" . $n->{id} . " = makeNode(";
63
64     print $tmp "n" . $parent->{id} . ", " if defined($parent);
65     print $tmp "\"" . $name . "\");\n";
66
67     dump_node($_, $n) for @{$n->{nodes}};
68     dump_node($_, $n) for @{$n->{floating_nodes}};
69 }
70
71 sub find_node_with_name {
72     my ($node, $name) = @_;
73
74     return $node if ($node->{name} eq $name);
75     for my $child (@{$node->{nodes}}) {
76         my $res = find_node_with_name($child, $name);
77         return $res if defined($res);
78     }
79     return undef;
80 }
81
82 my $start = shift;
83 my $root;
84 if ($start) {
85     # Find the specified node in the tree
86     $root = find_node_with_name($tree, $start);
87 } else {
88     $root = $tree;
89 }
90 dump_node($root);
91 say $tmp "draw(n" . $root->{id} . ", (0, 0));";
92
93 close($tmp);
94 my $rep = "$tmp";
95 $rep =~ s/asy$/eps/;
96 if ($options{gv}) {
97     my $tmp_dir = dirname($rep);
98     $options{save} = File::Spec->rel2abs($options{save}) if $options{save};
99     chdir($tmp_dir);
100 } else {
101     $rep = basename($rep);  # Output in current dir.
102 }
103 system("asy $tmp");  # Create the .eps file.
104 system("gv --scale=-1000 --noresize --widgetless $rep") if $options{gv};
105 if ($options{save}) {
106     system("mv $rep ${options{save}}");
107 } elsif ($options{gv}) {
108     system("rm $rep");
109 }
110 system("rm $tmp");
111
112 __END__
113
114 =head1 NAME
115
116 dump-asy.pl - Render the layout tree using asymptote
117
118 =head1 SYNOPSIS
119
120 dump-asy.pl [workspace]
121
122 =head1 EXAMPLE
123
124 Render the entire tree, run:
125
126   ./dump-asy.pl
127
128 Render the tree starting from the node with the specified name, run:
129
130   ./dump-asy.pl 'name'
131
132 Render the entire tree, save in file 'file.eps' and show using gv, run:
133
134   ./dump-asy.pl --save file.eps
135
136 =head1 OPTIONS
137
138 =over 8
139
140 =item B<--gv>
141
142 =item B<--no-gv>
143
144 Enable or disable showing the result through gv. If disabled, an .eps file will
145 be saved in the current working directory. Enabled by default.
146
147 =item B<--save>
148
149 Save result using the specified file-name. If omitted, no file will be saved
150 when using '--gv' or a random name will be used when using '--no-gv'.
151
152 =back