Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
btreepic.C
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
111# include <cstdio>
112# include <cmath>
113# include <cstdlib>
114# include <cstring>
115# include <fstream>
116# include <iostream>
117# include <aleph.H>
118# include <tpl_dynDlist.H>
119# include <tpl_binNode.H>
120# include <tpl_binNodeUtils.H>
121# include <tpl_dynArray.H>
122# include <tpl_sort_utils.H>
123
124# include <tclap/CmdLine.h>
125
126# include "parse_utils.H"
127# include "treepic_utils.H"
128
129using namespace std;
130
131/* TODO: THREAD option to draw a parabolic thread arc between 2
132 nodes (almost ready)
133
134 TODO: AUX-KEY 20 "string" option for "string" in node 20
135
136 TODO: ARROW option to draw arrows - interface not yet defined
137
138 TODO: dick and luka option for Lukasiewicz and Dick trees, their
139 codes and drawing of Catalan paths
140
141 TODO: option for infix projection
142
143 TODO: option for font types
144
145 TODO: option to reset .btreepic file
146*/
147
148/*These are the distance values */
149long double hr = 10; // horizontal radius of the ellipse
150long double vr = 10; // vertical radius of the ellipse
151long double hd = 2 * hr; // horizontal diameter of the ellipse
152long double vd = 2 * vr; // vertical diameter of the ellipse
153long double w = 20; // horizontal separation between centers
154long double h = 35; // vertical separation between centers
155long double h_size = 110; /* horizontal length of picture */
156double v_size = 190; /* vertical length of picture */
157long double x_offset = 0; // horizontal offset for main label
158long double y_offset = 0; // vertical offset for main label
159long double x_aux_offset = 0; // horizontal offset for auxiliary label
160long double y_aux_offset = 0; // vertical offset for auxiliary label
161long double x_picture_offset = 0; // horizontal offset for drawing
162long double y_picture_offset = 0; // vertical offset for drawing
163
164
183
184
186
187
188/* A tag is a label that can be placed externally to a
189 node. This struct describes such a label */
191{
192 string tag; // the string to write
193 Tag_Option tag_option; // tag orientation in clockwise direction
194 long double x_offset;
195 long double y_offset;
196
197 Tag_Data() = default;
198
199 Tag_Data(const string & str, Tag_Option option)
200 : tag(str), tag_option(option)
201 {
202 // empty
203 }
204};
205
206
207template <class Key>
208class EepicNode; /* Necessary for extra pointers
209 inside EepicNode_Data */
210
212{
214 bool is_dashed = false;
215
216 Arc_Desc() = default;
217};
218
219
221{
223 bool is_dashed = false;
224
225 Arc_Data() = default;
226};
227
228
230{
232 bool is_dashed = false;
233
234 Thread_Desc() = default;
235};
236
237
239{
241 bool is_dashed = false;
242
243 Thread_Data() = default;
244};
245
246
248{
251};
252
253
255{
256 string str;
258 long double xoffset;
259 long double yoffset;
260
261 [[nodiscard]] bool is_left() const { return orientation == LEFT; }
262};
263
264
266{
267 int count;
268 int level;
269
270 /* x,y coordinates in pixels */
271 long double x;
272 long double y;
273
274 long double xoffset;
275 long double yoffset;
276
277 long double triangle_height;
278
279 long double rectangle_height;
280
282
285 bool shadow;
289
292
295
297
299
301
303
304public:
313
314 void reset()
315 { /* empty */
316 }
317
318 int &getCount() { return count; }
319
320 int &get_level() { return level; }
321
322 long double &get_x() { return x; }
323
324 long double &get_y() { return y; }
325
326 long double &get_triangle_height() { return triangle_height; }
327
328 long double &get_rectangle_height() { return rectangle_height; }
329
330 long double &get_xoffset() { return xoffset; }
331
332 long double &get_yoffset() { return yoffset; }
333
335
336 bool is_external() const { return external_node; }
337
338 bool is_triangle() const { return triangle_height != 0.0; }
339
340 bool is_rectangle() const { return rectangle_height != 0.0; }
341
342 string &get_key_string() { return key_string; }
343
344 string &get_aux_string() { return aux_string; }
345
347
348 bool &get_shadow() { return shadow; }
349
350 bool &get_without_node() { return without_node; }
351
352 bool &get_scratch() { return scratch; }
353
354 bool &get_with_arc() { return with_arc; }
355
356 bool &get_dash_llink() { return dash_llink; }
357
358 bool &get_dash_rlink() { return dash_rlink; }
359
361
363
365
367
369};
370
371
372# define INFIXPOS(p) ((p)->getCount())
373# define LEVEL(p) ((p)->get_level())
374# define X(p) ((p)->get_x())
375# define Y(p) ((p)->get_y())
376# define XOFFSET(p) ((p)->get_xoffset())
377# define YOFFSET(p) ((p)->get_yoffset())
378# define TRIANGLEH(p) ((p)->get_triangle_height())
379# define RECTANGLEH(p) ((p)->get_rectangle_height())
380# define EXTERNAL(p) ((p)->get_external_node())
381# define ISEXTERNAL(p) ((p)->is_external())
382# define ISTRIANGLE(p) ((p)->is_triangle())
383# define DSTRING(p) ((p)->get_distance_string())
384# define LDISTANCE(p) ((p)->get_line_distance_data())
385# define ISDISTANCE(p) ((p)->get_line_distance_data().str.empty())
386# define ISRECTANGLE(p) ((p)->is_rectangle())
387# define STRING(p) ((p)->get_key_string())
388# define AUX(p) ((p)->get_aux_string())
389# define SHADOW(p) ((p)->get_shadow())
390# define WITHOUT(p) ((p)->get_without_node())
391# define SCRATCH(p) ((p)->get_scratch())
392# define WITHARC(p) ((p)->get_with_arc())
393# define DASHLLINK(p) ((p)->get_dash_llink())
394# define DASHRLINK(p) ((p)->get_dash_rlink())
395# define TAGLIST(p) ((p)->get_tag_list())
396# define ARCLIST(p) ((p)->get_arc_list())
397# define THREADLIST(p) ((p)->get_thread_list())
398# define SUCC(p) ((p)->get_succ())
399# define PREV(p) ((p)->get_prev())
400
402
404
405
408
409/* Global states */
410int num_nodes = 0;
411
412/* logical options and input file reading states */
413bool verbose_mode = true; // Print recognized actions
414bool silent_mode = true; // Do not print tokens seen from input file
415bool latex_header = false; // wrap output with a latex header
416bool landscape = false; // latex header in landscape mode
417bool fit_mode = false; // automatic size calculation mode */
418bool draw_node_mode = true; // draw ellipses
419bool printing_key_mode = false; // print key value inside ellipse
420bool with_string_key = false; // There is a string in file as key
421bool with_string_aux = false; // There is an auxiliary string besides key
422bool threaded_trees = false; // Draw threaded tree
423bool dash_threaded_trees = false; // Draw threaded tree
424bool with_external_nodes = false; // Draw external nodes
425bool draw_nodes = true; // Draw node ellipses
426
427const char *parameters_file_name = "./.btreepic";
428
429
430inline
432{
433 ofstream output(parameters_file_name, ios::trunc);
434
435 output << hr << " " << vr << " " << hd << " " << vd << " " << w << " "
436 << h << " " << resolution << " " << h_size << " "
437 << v_size << " " << x_offset << " " << y_offset << " "
438 << x_aux_offset << " " << y_aux_offset << " "
440}
441
442
443inline
445{
446 ifstream input(parameters_file_name, ios::in);
447
448 input >> hr >> vr >> hd >> vd >> w >> h >> resolution >> h_size
451}
452
453
454DynArray<long> prefix_dynarray; // preorder traversal
455DynArray<long> infix_dynarray; // inorder traversal
456DynArray<string> key_print_dynarray; // keys as strings in inorder
457DynArray<string> aux_print_dynarray; // auxiliary strings in inorder
458DynArray<long> shadow_dynarray; /* sequential list of inorder positions
459 to shadow */
460DynArray<long> without_node_dynarray; /* sequential list of nodes
461 that are not drawn */
463DynArray<long> tag_pos_dynarray; /* inorder positions of tags */
464DynArray<long> source_arc_dynarray; /* inorder positions of source
465 of additional arcs */
466DynArray<Arc_Data> target_arc_dynarray; /* inorder positions of target
467 of additional arcs */
468DynArray<long> source_thread_dynarray; /* inorder positions of source
469 of additional threads */
470DynArray<Thread_Data> target_thread_dynarray; /* inorder positions of target
471 of additional threads */
472DynArray<long> scratch_dynarray; /* inorder positions of nodes to
473 scratch */
474DynArray<long> split_dynarray; /* inorder positions of partition
475 lines */
477 lines */
478DynArray<long> key_pos_dynarray; /* inorder positions of keys */
480
481/* particular horizontal offsets */
484
485/* particular vertical offsets */
488
489/* triangles */
492
493/* rectangles */
496
497/* rectangles with scratches at the end */
500
501/* distance lines */
504
505DynArray<long> without_arc_dynarray; // list of nodes without arc
506
507# define TERMINATE(n) (save_parameters(), exit(n))
508
509# define DYNARRAY_APPEND(array, item) (array[array.size()] = item)
510
511using namespace Aleph;
512
514
516{
518
520 tag_data.tag = load_string(input_stream); // tag string
521
523
525 print_parse_error_and_exit("Invalid tag option found");
526
527 tag_data.tag_option = token_type;
528
529 tag_data.x_offset = load_number(input_stream); // xoffset
530 tag_data.y_offset = load_number(input_stream); // yoffset
531
533}
534
545
556
568
570{
572
573 if (position >= prefix_dynarray.size())
574 PRINT_ERROR("Node position greater than number of nodes in KEY option");
575
577}
578
586
592
598
599/* this variable memorizes the maximum height in nodes of a
600 rectangle. The purpose is to readjust the vertical length of the
601 picture environment */
603
605{
607
608 const long height = load_number(input_stream);
609
610 if (height > max_num_nodes_rectangle)
612
613 if (height == 0)
614 PRINT_ERROR("Height in nodes cannot be zero");
615
617}
618
619
621{
623
624 const long height = load_number(input_stream);
625
626 if (height > max_num_nodes_rectangle)
628
629 if (height == 0)
630 PRINT_ERROR("Height in nodes cannot be zero");
631
633}
634
636{
638
639 Line_Distance_Data line_distance_data;
640
641 line_distance_data.str = load_string(input_stream);
642
644
646 PRINT_ERROR("Invalid orientation in DISTANCE option");
647
648 line_distance_data.orientation = token_type;
649 line_distance_data.xoffset = load_number(input_stream);
650 line_distance_data.yoffset = load_number(input_stream);
651
652 DYNARRAY_APPEND(distance_dynarray, line_distance_data);
653}
654
656{
657 int current_char;
658
659 char buffer[Buffer_Size];
660 char *start_address = buffer;
661 char *end_address = buffer + Buffer_Size;
662
665
667 catch (const std::out_of_range &) { return END_FILE; }
668
669 if (current_char == EOF)
670 return END_FILE;
671
673 return INVALID;
674
676 {
677 if (current_char == '-')
678 {
682 return INVALID;
683 }
684 do
685 {
688 }
690
692 return NUMBER;
693 }
694
695 if (current_char == '\"') /* string delimited by quotes */
696 while (true)
697 {
699 if (current_char == '\"')
700 {
702 return STRING;
703 }
704 if (current_char == EOF or current_char == '\n')
705 return INVALID;
706
708 }
709
710 if (current_char == '%')
711 { /* comment */
712 while (read_char_from_stream(input_stream) != '\n') { /* nothing */ }
713
714 return COMMENT;
715 }
716
717 do /* delimits string separated by whitespaces */
718 {
721 }
722 while (isgraph(current_char));
723
725
726 if (strcasecmp(buffer, "START-PREFIX") == 0 or
727 strcasecmp(buffer, "PREFIX") == 0 or
728 strcasecmp(buffer, "START-PREORDER") == 0 or
729 strcasecmp(buffer, "PREORDER") == 0)
730 return START_PREFIX;
731
732 if (strcasecmp(buffer, "START-INFIX") == 0 or
733 strcasecmp(buffer, "START-INORDER") == 0 or
734 strcasecmp(buffer, "INORDER") == 0 or
735 strcasecmp(buffer, "INFIX") == 0
736 )
737 return START_INFIX;
738
739 if (strcasecmp(buffer, "START-KEY") == 0)
740 return START_KEY;
741
742 if (strcasecmp(buffer, "START-AUX") == 0)
743 return START_AUX;
744
745 if (strcasecmp(buffer, "START-SHADOW") == 0 or
746 strcasecmp(buffer, "SHADOW") == 0)
747 return SHADOW_NODE;
748
749 if (strcasecmp(buffer, "WITHOUT-NODE") == 0)
750 return WITHOUT_NODE;
751
752 if (strcasecmp(buffer, "TAG") == 0)
753 return TAG;
754
755 if (strcasecmp(buffer, "ARC") == 0)
756 return ARC;
757
758 if (strcasecmp(buffer, "DASHED-ARC") == 0)
759 return DASHED_ARC;
760
761 if (strcasecmp(buffer, "SCRATCH") == 0)
762 return SCRATCH;
763
764 if (strcasecmp(buffer, "SPLIT") == 0)
765 return SPLIT;
766
767 if (strcasecmp(buffer, "KEY") == 0)
768 return Token_Type::KEY;
769
770 if (strcasecmp(buffer, "XOFFSET") == 0)
771 return XOFFSET;
772
773 if (strcasecmp(buffer, "YOFFSET") == 0)
774 return YOFFSET;
775
776 if (strcasecmp(buffer, "TRIANGLE") == 0)
777 return TRIANGLE;
778
779 if (strcasecmp(buffer, "TRIANGLEH") == 0)
780 return TRIANGLEH;
781
782 if (strcasecmp(buffer, "WITHOUT-ARC") == 0)
783 return WITHOUT_ARC;
784
785 if (strcasecmp(buffer, "RECTANGLE") == 0)
786 return RECTANGLE;
787
788 if (strcasecmp(buffer, "PARRECTANGLE") == 0)
789 return PARRECTANGLE;
790
791 if (strcasecmp(buffer, "DISTANCE") == 0)
792 return DISTANCE;
793
794 if (strcasecmp(buffer, "THREAD") == 0)
795 return THREAD;
796
797 if (strcasecmp(buffer, "L") == 0)
798 return LEFT;
799
800 if (strcasecmp(buffer, "R") == 0)
801 return RIGHT;
802
803 if (strcasecmp(buffer, "N") == 0)
804 return NORTH;
805
806 if (strcasecmp(buffer, "S") == 0)
807 return SOUTH;
808
809 if (strcasecmp(buffer, "E") == 0)
810 return EAST;
811
812 if (strcasecmp(buffer, "W") == 0)
813 return WEST;
814
815 if (strcasecmp(buffer, "NE") == 0)
816 return NORTH_EAST;
817
818 if (strcasecmp(buffer, "NW") == 0)
819 return NORTH_WEST;
820
821 if (strcasecmp(buffer, "SE") == 0)
822 return SOUTH_EAST;
823
824 if (strcasecmp(buffer, "SW") == 0)
825 return SOUTH_WEST;
826
827 return STRING;
828}
829
831{
832 PREFIX, /* Mandatory phase */
833 INFIX, /* The rest of the phases are optional */
834 KEYS, /* Reading of main key values */
835 AUX, /* Reading of auxiliary key values */
836 SHADOW, /* Shadow node */
837 WITHOUT /* Do not draw ellipse */
839
840void assign_key(EepicNode<long> *p, int, const int position)
841{
842 STRING(p) = key_print_dynarray[position];
843}
844
845void assign_aux(EepicNode<long> *p, int, const int position)
846{
847 AUX(p) = aux_print_dynarray[position];
848}
849
850void assign_shadow(EepicNode<long> *p, int, const int position)
851{
853 0, shadow_dynarray.size() - 1) >= 0)
854 {
855 SHADOW(p) = true;
856 WITHOUT(p) = false;
857 }
858}
859
860void reassign_key(EepicNode<long> *p, int, const int position)
861{
862 const int found_index =
864 0, key_pos_dynarray.size() - 1);
865 if (found_index >= 0)
867}
868
869void assign_without_node(EepicNode<long> *p, int, const int position)
870{
872 0, without_node_dynarray.size() - 1) >= 0)
873 WITHOUT(p) = true;
874}
875
876void assign_tag(EepicNode<long> *p, int, const int position)
877{
878 int low_index = 0;
879 int found_index;
880
881 do /* searches all occurrences of node_index value in
882 tag_pos_dynarray */
883 {
886 tag_pos_dynarray.size() - 1);
887 if (found_index >= 0)
889
891 }
892 while (found_index >= 0);
893}
894
895/*
896 searches the i-th infix node assuming that each node has an
897 INFIX_POS field that stores its infix position. Assumes that the
898 empty tree is nullptr -no sentinel null-
899*/
900template <class Node>
901inline
902Node * select(Node *root, const int & i)
903{
904 while (root != nullptr)
905 {
906 if (INFIXPOS(root) == i)
907 return root;
908
909 if (i < INFIXPOS(root))
910 root = LLINK(root);
911 else
912 root = RLINK(root);
913 }
914 return nullptr;
915}
916
917/* traverses the tree in preorder and assigns the arcs stored in the
918 arrays source_arc_dynarray and target_arc_dynarray */
919inline
921{
922 if (p == nullptr)
923 return;
924
925 int low_index = 0;
926 int found_index;
927
928 do /* searches all occurrences of node_index value in
929 source_arc_dynarray */
930 {
934 if (found_index >= 0)
935 {
938 arc_desc.is_dashed = arc_data.is_dashed;
939 arc_desc.target_node = select(root, arc_data.target_node);
940 ARCLIST(p).append(arc_desc);
941 }
942
944 }
945 while (found_index >= 0);
946
947 do /* searches all occurrences of node_index value in
948 source_thread_dynarray */
949 {
953 if (found_index >= 0)
954 {
957 thread_desc.is_dashed = thread_data.is_dashed;
958 thread_desc.target_node = select(root, thread_data.target_node);
959 THREADLIST(p).append(thread_desc);
960 }
961
963 }
964 while (found_index >= 0);
965
968}
969
971{
972 if (EepicNode<long> *& l = LLINK(p); l == nullptr)
973 {
974 l = new EepicNode<long>;
975 EXTERNAL(l) = true;
976 }
977 else
979
980 if (EepicNode<long> *& r = RLINK(p); r == nullptr)
981 {
982 r = new EepicNode<long>;
983 EXTERNAL(r) = true;
984 }
985 else
987}
988
989void assign_scratch(EepicNode<long> *p, int, const int position)
990{
992 0, scratch_dynarray.size() - 1) >= 0)
993 SCRATCH(p) = true;
994}
995
996void assign_xoffset(EepicNode<long> *p, int, const int position)
997{
998 const int found_index =
1000 0, pos_xoffset_dynarray.size() - 1);
1001 if (found_index >= 0)
1003}
1004
1005void assign_yoffset(EepicNode<long> *p, int, const int position)
1006{
1007 const int found_index =
1009 0, pos_yoffset_dynarray.size() - 1);
1010 if (found_index >= 0)
1012}
1013
1014void assign_triangle(EepicNode<long> *p, int, const int position)
1015{
1016 const int found_index =
1018 0, pos_triangle_dynarray.size() - 1);
1019 if (found_index >= 0)
1020 {
1021 if (not (LLINK(p) == nullptr and RLINK(p) == nullptr))
1022 PRINT_ERROR("Triagle on %d th node is not a leaf", INFIXPOS(p));
1023
1025 }
1026}
1027
1028void assign_rectangle(EepicNode<long> *p, int, const int position)
1029{
1030 const int found_index =
1032 0, pos_rectangle_dynarray.size() - 1);
1033 if (found_index >= 0)
1034 {
1035 if (not (LLINK(p) == nullptr and RLINK(p) == nullptr))
1036 PRINT_ERROR("Rectangle on %d th node is not a leaf", INFIXPOS(p));
1037
1039 }
1040}
1041
1042void assign_parrectangle(EepicNode<long> *p, int, const int position)
1043{
1044 const int found_index =
1047 if (found_index >= 0)
1048 {
1049 if (not (LLINK(p) == nullptr and RLINK(p) == nullptr))
1050 PRINT_ERROR("Rectangle on %d th node is not a leaf", INFIXPOS(p));
1051
1053 SCRATCH(p) = true;
1054 }
1055}
1056
1057void assign_distance(EepicNode<long> *p, int, const int position)
1058{
1059 const int found_index =
1061 0, pos_distance_dynarray.size() - 1);
1062 if (found_index >= 0)
1063 {
1064 Line_Distance_Data line_distance_data = distance_dynarray[found_index];
1065 if (line_distance_data.orientation == LEFT and LLINK(p) != nullptr)
1066 PRINT_ERROR("Distance line on %d th node has a left branch",
1067 INFIXPOS(p));
1068 if (line_distance_data.orientation == RIGHT and RLINK(p) != nullptr)
1069 PRINT_ERROR("Distance line on %d th node has a right branch",
1070 INFIXPOS(p));
1071
1072 LDISTANCE(p) = line_distance_data;
1073 }
1074}
1075
1076void assign_without_arc(EepicNode<long> *p, int, const int position)
1077{
1078 const int found_index =
1080 0, without_arc_dynarray.size() - 1);
1081 if (found_index >= 0)
1082 WITHARC(p) = false;
1083}
1084
1085/*
1086 Assigns infix position to each node. It is used with inOrderRec
1087 routine, and it must be ensured that node_index is initialized to zero
1088 before calling inOrderRec
1089*/
1090void assign_pos_and_level(EepicNode<long> *p, const int level, const int position)
1091{
1092 INFIXPOS(p) = position;
1093 X(p) = hr + position * w;
1094 LEVEL(p) = level;
1095 Y(p) = level * h + vr;
1096}
1097
1098inline
1100{
1101 if (EepicNode<long> *prev = LLINK(p); prev != nullptr)
1102 {
1103 while (RLINK(prev) != nullptr)
1104 prev = RLINK(prev);
1105
1106 SUCC(prev) = p;
1107
1108 thread_tree(LLINK(p));
1109 }
1110
1111 if (EepicNode<long> *succ = RLINK(p); succ != nullptr)
1112 {
1113 while (LLINK(succ) != nullptr)
1114 succ = LLINK(succ);
1115
1116 PREV(succ) = p;
1117
1118 thread_tree(RLINK(p));
1119 }
1120}
1121
1122void file_to_dynarrays(const char *file_name)
1123{
1124 try
1125 {
1126 ifstream input_stream(file_name, ios::in);
1127
1128 if (not input_stream)
1129 AH_ERROR("%s file does not exist", input_file_name.c_str());
1130
1132
1133 while (true)
1134 {
1136
1138 cout << token_instance << " ";
1139
1140 switch (token_type)
1141 {
1142 case INVALID: PRINT_ERROR("Found an invalid token");
1143 case END_FILE:
1144 return;
1145
1146 case COMMENT: break;
1147
1148 case STRING:
1149 switch (parsing_state)
1150 {
1151 case KEYS:
1153 break;
1154 case AUX:
1156 break;
1157 default: PRINT_ERROR("Found an string in invalid mode (%ld)",
1159 }
1160 break;
1161
1162 case NUMBER:
1163 switch (parsing_state)
1164 {
1165 case PREFIX:
1168 atoi(token_instance.c_str()));
1169 break;
1170 case INFIX:
1172 atoi(token_instance.c_str()));
1173 break;
1174 case KEYS:
1176 break;
1177 case AUX:
1179 break;
1180 case SHADOW:
1182 atoi(token_instance.c_str()));
1183 break;
1184 case WITHOUT:
1186 atoi(token_instance.c_str()));
1187 break;
1188 default: AH_ERROR("Found an integer in invalid mode (%ld)",
1190 }
1191 break;
1192
1193 case START_PREFIX:
1195 break;
1196
1197 case START_INFIX:
1199 break;
1200
1201 case START_KEY:
1203 if (key_print_dynarray.size() > 0)
1205 with_string_key = true;
1206 printing_key_mode = true;
1207 break;
1208
1209 case START_AUX:
1211 with_string_aux = true;
1212 break;
1213
1214 case SHADOW_NODE:
1216 break;
1217
1218 case WITHOUT_NODE:
1220 break;
1221
1222 case TAG:
1224 break;
1225
1226 case ARC:
1227 case DASHED_ARC:
1229 break;
1230
1231 case THREAD:
1233 break;
1234
1235 case SCRATCH:
1237 break;
1238
1239 case SPLIT:
1241 break;
1242
1243 case Token_Type::KEY:
1245 break;
1246
1247 case XOFFSET:
1250 break;
1251
1252 case YOFFSET:
1255 break;
1256
1257 case TRIANGLE:
1259 break;
1260
1261 case TRIANGLEH:
1263 break;
1264
1265 case RECTANGLE:
1267 break;
1268
1269 case PARRECTANGLE:
1271 break;
1272
1273 case DISTANCE:
1275 break;
1276
1277 case WITHOUT_ARC:
1279 break;
1280
1281 default:
1282 PRINT_ERROR("Internal error: invalid token type (%ld)",
1283 token_type);
1284 }
1285 }
1286 }
1287 catch (exception & e)
1288 {
1289 PRINT_ERROR(e.what());
1290 }
1291}
1292
1294{
1295 if (TAGLIST(p).is_empty())
1296 return false;
1297
1299 tag_itor.has_curr(); tag_itor.next())
1300 {
1301 if (const Tag_Data & tag_data = tag_itor.get_curr();
1302 tag_data.tag_option == NORTH or
1303 tag_data.tag_option == NORTH_EAST or
1304 tag_data.tag_option == NORTH_WEST)
1305 return true;
1306 }
1307
1308 return false;
1309}
1310
1312{
1314
1315 if (TAGLIST(p).is_empty())
1316 return false;
1317
1319 tag_itor.has_curr(); tag_itor.next())
1320 {
1321 if (const Tag_Data & tag_data = tag_itor.get_curr();
1322 tag_data.tag_option == EAST or
1323 tag_data.tag_option == NORTH_EAST or
1324 tag_data.tag_option == SOUTH_EAST)
1325 return true;
1326 }
1327
1328 return false;
1329}
1330
1332{
1334
1335 if (TAGLIST(p).is_empty())
1336 return false;
1337
1339 tag_itor.has_curr(); tag_itor.next())
1340 {
1341 if (const Tag_Data & tag_data = tag_itor.get_curr();
1342 tag_data.tag_option == WEST or
1343 tag_data.tag_option == NORTH_WEST or
1344 tag_data.tag_option == SOUTH_WEST)
1345 return true;
1346 }
1347
1348 return false;
1349}
1350
1352 const size_t & level)
1353{
1356
1357 for (DynDlist<EepicNode<long> *>::Iterator it(deepest_nodes);
1358 it.has_curr(); it.next())
1359 {
1360 EepicNode<long> *p = it.get_curr();
1361
1362 if (TAGLIST(p).is_empty())
1363 continue;
1364
1366 tag_itor.has_curr(); tag_itor.next())
1367 {
1368 if (Tag_Data & tag_data = tag_itor.get_curr(); tag_data.tag_option == SOUTH or
1369 tag_data.tag_option == SOUTH_EAST or
1370 tag_data.tag_option == SOUTH_WEST)
1371 return true;
1372 }
1373 }
1374
1375 return false;
1376}
1377
1378void adjust_size_by_tags(EepicNode<long> *root, const size_t & height)
1379{
1380 const long double r = std::max(hr, vr) + 2.0 / resolution; // 2mm
1381
1382 if (north_offset(root))
1383 v_size += r;
1384
1385 if (south_offset(root, height - 1))
1386 v_size += r;
1387
1388 if (east_offset(root))
1389 h_size += r;
1390
1391 if (west_offset(root))
1392 h_size += r;
1393}
1394
1395inline
1397{
1398 const int height = computeHeightRec(p);
1399
1400 h_size = (num_nodes - 1) * w + hd;
1401 v_size = (height - 1) * h + vd;
1402
1405
1406 if (height_triangle_dynarray.size() > 0)
1407 {
1408 const float max_triangle_height =
1410 height_triangle_dynarray.size())];
1412 }
1413
1414 // if (split_string_dynarray.size() > 0)
1415 // v_size += 4.0/resolution;
1416
1417 adjust_size_by_tags(p, height);
1418}
1419
1420inline
1422{
1423 const int height = computeHeightRec(p);
1424
1425 resolution = 1;
1426
1427 w = h_size / (num_nodes + 1);
1428 h = v_size / (height + 1);
1429 hr = w / 4;
1430 hd = 2 * hr;
1431 vr = h / 4;
1432 vd = 2 * vr;
1433}
1434
1436{
1437 try
1438 {
1440
1441 EepicNode<long> *root = nullptr;
1442
1443 /* initial construction of the tree according to input traversals */
1444 if (infix_dynarray.size() == 0)
1446 (prefix_dynarray, 0, num_nodes - 1); /* only preorder traversal */
1447 else
1448 { /* input with two traversals */
1449 if (infix_dynarray.size() != num_nodes)
1450 AH_ERROR("Sizes of traversals differ");
1451
1452 root =
1454 infix_dynarray, 0, num_nodes - 1);
1456 }
1457
1458 if (with_string_key)
1459 {
1461 AH_ERROR("Number of keys is different from tree size");
1462
1464 }
1465 else
1467
1468 if (with_string_aux)
1469 {
1471 AH_ERROR("Number of auxiliary keys is different from tree size");
1472
1474 }
1475
1478
1479 /* assign infix positions to each node */
1481
1483 {
1484 if (not with_string_key)
1485 fill_type = "black";
1486
1488
1489 return root; /* with external nodes only shape is drawn */
1490 }
1491
1494
1495 if (without_node_dynarray.size() > 0)
1496 {
1499 }
1500
1501 if (shadow_dynarray.size() > 0)
1502 {
1505 }
1506
1507 if (tag_pos_dynarray.size() > 0)
1508 {
1511 tag_data_dynarray.cut();
1512 }
1513
1514 if (not fit_mode)
1516 else
1518
1519 if (source_arc_dynarray.size() > 0)
1520 {
1523 target_arc_dynarray.cut();
1524 }
1525
1526 if (scratch_dynarray.size() > 0)
1527 {
1530 }
1531
1532 if (key_pos_dynarray.size() > 0)
1533 {
1537 }
1538
1539 if (pos_xoffset_dynarray.size() > 0)
1540 {
1543 xoffset_dynarray.cut();
1544 }
1545
1546 if (pos_yoffset_dynarray.size() > 0)
1547 {
1550 yoffset_dynarray.cut();
1551 }
1552
1553 if (pos_triangle_dynarray.size() > 0)
1554 {
1558 }
1559
1560 if (pos_rectangle_dynarray.size() > 0)
1561 {
1565 }
1566
1568 {
1572 }
1573
1574 if (pos_distance_dynarray.size() > 0)
1575 {
1578 distance_dynarray.cut();
1579 }
1580
1581 if (without_arc_dynarray.size() > 0)
1582 {
1585 }
1586
1589
1590 return root;
1591 }
1592 catch (exception & e)
1593 {
1594 AH_ERROR("%s", e.what());
1595 }
1596
1597 return nullptr; /* never reached */
1598}
1599
1601{
1602 time_t t;
1603 time(&t);
1604 output << endl
1605 << "% This LaTeX picture is a binary tree automatically" << endl
1606 << "% generated by btreepic program" << endl
1607 << endl
1608 << "% Copyright (C) 2007, 2006, 2005, 2004, 2003, 2002" << endl
1609 << "% UNIVERSITY of LOS ANDES (ULA)" << endl
1610 << "% Merida - REPUBLICAf1727 BOLIVARIANA DE VENEZUELA" << endl
1611 << "% Center of Studies in Microelectronics & Distributed Systems"
1612 << " (CEMISID)" << endl
1613 << "% ULA Computer Science Department" << endl
1614 << endl
1615 << "% Leandro Leon - lrleon@ula.ve" << endl
1616 << endl
1617 << "% You must use curves, epic and eepic latex packages" << endl
1618 << "% in your LaTeX application" << endl
1619 << endl
1620 << "% curves Copyright by I.L. Maclaine-cross" << endl
1621 << "% epic Copyright by Sunil Podar" << endl
1622 << "% eepic Copyright by Conrad Kwok" << endl
1623 << "% LaTeX is a collection of TeX macros created by Leslie Lamport"
1624 << endl
1625 << "% TeX was created by Donald Knuth" << endl
1626 << endl
1627 << "% command line: " << endl
1628 << "% " << command_line << endl
1629 << endl
1630 << "% input file: " << input_file_name << endl
1631 << "% output file: " << output_file_name << endl
1632 << endl
1633 << "% Creation date: " << ctime(&t) << endl
1634 << endl;
1635
1636 if (latex_header)
1637 output << "%%%%%%%%%%%%%%%% LATEX Header generated with -a option" << endl
1638 << "\\documentclass[11pt]{article}" << endl
1639 << (landscape ? "\\usepackage[landscape]{geometry}" : "") << endl
1640 << endl
1641 << (dash_threaded_trees ? "\\usepackage{curves}" : "") << endl
1642 << "\\usepackage{epic}" << endl
1643 << "\\usepackage{eepic}" << endl
1644 << "\\usepackage{amssymb}" << endl
1645 << endl
1646 << "\\begin{document}" << endl
1647 << "\\begin{center}" << endl;
1648
1649 output << endl
1650 << "% Resolution is " << resolution << "mm" << endl
1651 << "% Change resolution with -l option" << endl
1652 << "\\setlength{\\unitlength}{" << resolution << "mm}" << endl
1653 << "\\filltype{" << fill_type << "}" << endl
1654 << (dash_threaded_trees ? "\\curvedashes[0.17mm]{1,5,3}\n" : "")
1655 << endl
1656 << "\\begin{picture}(" << h_size << "," << v_size << ")"
1657 << "(" << x_picture_offset << "," << y_picture_offset << ")" << endl;
1658}
1659
1661{
1662 output << endl
1663 << endl
1664 << "\\end{picture}" << endl;
1665
1666 if (latex_header)
1667 output << endl
1668 << "\\end{center}" << endl
1669 << "\\end{document}" << endl;
1670}
1671
1673{
1674 if (p == nullptr)
1675 return;
1676
1677 long double x = X(p);
1678 long double y = Y(p);
1679
1680 /* Print node header comment */
1681 output << endl
1682 << endl
1683 << "% Node at infix position " << INFIXPOS(p)
1684 << " with key " << STRING(p);
1685
1686 /* draw node */
1687 if (ISEXTERNAL(p)) /* line corresponding to external node */
1688 output << endl
1689 << "% External node" << endl
1690 << "\\path(" << x - hr << "," << YPIC(y) << ")("
1691 << x + hr << "," << YPIC(y) << ")" << endl;
1692 else if (ISTRIANGLE(p)) /* draw triangle */
1693 output << endl
1694 << "% Triangle" << endl
1695 << "\\path(" << x << "," << YPIC(y) << ")("
1696 << x - hd << "," << YPIC(y + TRIANGLEH(p)) << ")("
1697 << x + hd << "," << YPIC(y + TRIANGLEH(p)) << ")("
1698 << x << "," << YPIC(y) << ")";
1699 else if (ISRECTANGLE(p)) /* draw rectangle */
1700 {
1701 long double x1 = X(p) - hr;
1702 long double x2 = X(p) + hr;
1703 long double y1, y2;
1704
1705 if (SCRATCH(p))
1706 {
1707 y1 = Y(p);
1708 y2 = Y(p) + RECTANGLEH(p) - vd;
1709
1710 output << endl
1711 << "% Partial Rectangle" << endl
1712 << "\\path(" << x1 << "," << YPIC(y1) << ")("
1713 << x2 << "," << YPIC(y1) << ")("
1714 << x2 << "," << YPIC(y2) << ")("
1715 << x1 << "," << YPIC(y2) << ")("
1716 << x1 << "," << YPIC(y1) << ")";
1717
1718 y1 = Y(p) + RECTANGLEH(p) - vd;
1719 y2 = Y(p) + RECTANGLEH(p);
1720
1721 output << endl
1722 << "\\dashline{" << dash_len << "}("
1723 << x1 << "," << YPIC(y1) << ")("
1724 << x1 << "," << YPIC(y2) << ")("
1725 << x2 << "," << YPIC(y2) << ")("
1726 << x2 << "," << YPIC(y1) << ")" << endl
1727 << "\\path(" << x1 << "," << YPIC(y1) << ")("
1728 << x2 << "," << YPIC(y2) << ")" << endl
1729 << "\\path(" << x2 << "," << YPIC(y1) << ")("
1730 << x1 << "," << YPIC(y2) << ")";
1731 }
1732 else
1733 {
1734 y1 = Y(p);
1735 y2 = y1 + RECTANGLEH(p);
1736
1737 output << endl
1738 << "% Rectangle" << endl
1739 << "\\path(" << x1 << "," << YPIC(y1) << ")("
1740 << x2 << "," << YPIC(y1) << ")("
1741 << x2 << "," << YPIC(y2) << ")("
1742 << x1 << "," << YPIC(y2) << ")("
1743 << x1 << "," << YPIC(y1) << ")";
1744 }
1745 }
1746 else if (draw_nodes and not WITHOUT(p)) /* internal node ellipse */
1747 output << endl
1748 << "% Elippse" << endl
1749 << "\\put(" << x << "," << YPIC(y) << ")"
1750 << (SHADOW(p) ? "{\\ellipse*{" : "{\\ellipse{") << hd
1751 << "}{" << vd << "}}";
1752 else if (SHADOW(p))
1753 output << endl
1754 << "% Elippse" << endl
1755 << "\\put(" << x << "," << YPIC(y) << "){\\ellipse*{" << hd
1756 << "}{" << vd << "}}";
1757
1758 /* print distance line if applicable */
1759 if (ISDISTANCE(p))
1760 {
1761 output << endl
1762 << "% Distance line";
1763 long double xof = 2.0 / resolution; /* 2 mm separation from node */
1764 long double yplus = 1.0 / resolution; /* line extra length */
1765 long double yof = 3.5 / resolution; /* 3.0 mm space for letters */
1766 long double line_len = 0;
1768 long double xd = 0;
1769
1770 if (ISRECTANGLE(p))
1771 {
1772 xd = ldd.is_left() ? -(hr + xof) : (hr + xof);
1773 line_len = (RECTANGLEH(p) - yof) / 2;
1774 }
1775 else if (ISTRIANGLE(p))
1776 {
1777 xd = ldd.is_left() ? -(w / 2 + xof) : (w / 2 + xof);
1778 line_len = (TRIANGLEH(p) - yof) / 2;
1779 }
1780 else
1781 PRINT_ERROR("Distance line on %d th complete node", INFIXPOS(p));
1782
1783 long double xl = x + xd;
1784 long double gap_len = 2.0 / resolution;
1785 long double dy = sin_45 * gap_len;
1786 long double yf1 = y + line_len;
1787 long double yf2 = y + yof + 2 * line_len;
1788 output << endl
1789 << "\\path(" << xl << "," << YPIC(y - yplus) << ")("
1790 << xl << "," << YPIC(y + line_len) << ")" << endl
1791 << "\\path(" << xl << "," << YPIC(yf1 + yof) << ")("
1792 << xl << "," << YPIC(yf2 + yplus) << ")" << endl
1793 << "\\path(" << xl - gap_len / 2 << "," << YPIC(y) << ")("
1794 << xl + gap_len / 2 << "," << YPIC(y) << ")" << endl
1795 << "\\path(" << xl - gap_len / 2 << "," << YPIC(yf2 + yplus)
1796 << ")" << endl
1797 << "\\path(" << xl - gap_len / 2 << "," << YPIC(yf2) << ")("
1798 << xl + gap_len / 2 << "," << YPIC(yf2) << ")" << endl
1799 << "\\path(" << xl - gap_len / 2 << "," << YPIC(y + dy) << ")("
1800 << xl + gap_len / 2 << "," << YPIC(y - dy) << ")" << endl
1801 << "\\path(" << xl - gap_len / 2 << "," << YPIC(yf2 + dy) << ")("
1802 << xl + gap_len / 2 << "," << YPIC(yf2 - dy) << ")";
1803
1804 long double string_gap = 2.0 / resolution;
1805 long double str_offset = ldd.is_left() ?
1806 string_width(ldd.str) + string_gap :
1807 -string_gap;
1808 put_string(output, xl - str_offset + ldd.xoffset,
1809 y + line_len + yof + ldd.yoffset,
1810 "String of line distance", ldd.str);
1811 }
1812
1813 /* print node content */
1815 {
1816 long double dx = center_string(STRING(p), hd);
1817 long double dy = font_height() / 2.0;
1818 long double dy_triangle = not ISTRIANGLE(p) ? 0 : TRIANGLEH(p) / 4;
1819 long double dy_rectangle = 0;
1820
1821 if (ISRECTANGLE(p))
1822 dy_rectangle =
1823 (SCRATCH(p) ? (RECTANGLEH(p) - vd) : RECTANGLEH(p)) / 2 + vr;
1824
1825 if (not with_string_aux) /* print only key */
1826 put_string(output, x + x_offset + XOFFSET(p) - dx,
1827 y + dy + y_offset + YOFFSET(p) +
1829 "Key text= " + STRING(p), STRING(p));
1830 else
1831 { /* nodes contain two fields: key and auxiliary string */
1832 long double dxa = center_string(AUX(p), hd);
1833 long double dyk = 1.2 / resolution; // 1.2 mm above line
1834 long double dya = 2 / resolution; // 3 mm below line
1835
1836 /* place key */
1837 put_string(output, x + x_offset + XOFFSET(p) - dx,
1838 y + dy + y_offset + YOFFSET(p) + TRIANGLEH(p) -
1839 dy_triangle +
1841 "Key text= " + STRING(p), STRING(p));
1842
1843 /* dividing line of node between main and auxiliary string */
1844 if (not (ISTRIANGLE(p) or ISRECTANGLE(p)))
1845 output << endl
1846 << "\\path(" << x - hr << "," << YPIC(y) << ")("
1847 << x + hr << "," << YPIC(y) << ")";
1848
1849 /* place auxiliary key */
1851 y + dy + y_aux_offset + dya + TRIANGLEH(p) - dy_triangle +
1853 "Auxiliar string= " + AUX(p), AUX(p));
1854 }
1855 }
1856
1857 /* print node tags */
1858 if (not TAGLIST(p).is_empty())
1859 {
1860 long double tx, ty; /* tag coordinates */
1862 long double r = std::max(hr, vr) + 2.0 / resolution; // 2mm
1863 long double dr = sin_45 * r; /* radius r at 45 degrees */
1864 long double x_font_size = 2.0 / resolution;
1865 long double y_font_size = 2.5 / resolution;
1866 string comment;
1867
1869 itor.has_curr(); itor.next())
1870 {
1871 tag_data = itor.get_curr();
1872
1873 switch (tag_data.tag_option)
1874 {
1875 case NORTH:
1876 comment = "North tag: ";
1877 tx = x - x_font_size / 2 + tag_data.x_offset;
1878 ty = y - r + tag_data.y_offset;
1879
1880 break;
1881 case SOUTH:
1882 comment = "South tag: ";
1883 tx = x - x_font_size / 2 + tag_data.x_offset;
1884 ty = y + r + y_font_size / 2 + tag_data.y_offset;
1885 break;
1886 case EAST:
1887 comment = "East tag: ";
1888 tx = x + r + tag_data.x_offset;
1889 ty = y + y_font_size / 2 + tag_data.y_offset;
1890 break;
1891 case WEST:
1892 comment = "West tag: ";
1893 tx = x - r - x_font_size + tag_data.x_offset -
1895 ty = y + y_font_size / 2 + tag_data.y_offset;
1896 break;
1897 case NORTH_EAST:
1898 comment = "Northeast tag: ";
1899 tx = x + dr + x_font_size / 2 + tag_data.x_offset;
1900 ty = y - dr + y_font_size / 2 + tag_data.y_offset;
1901 break;
1902 case NORTH_WEST:
1903 comment = "Northwest tag: ";
1904 tx = x - dr - x_font_size / 2 + tag_data.x_offset -
1906 ty = y - dr + y_font_size / 2 + tag_data.y_offset;
1907 break;
1908 case SOUTH_EAST:
1909 comment = "Southeast tag: ";
1910 tx = x + dr + x_font_size / 2 + tag_data.x_offset;
1911 ty = y + dr + y_font_size / 2 + tag_data.y_offset;
1912 break;
1913 case SOUTH_WEST:
1914 comment = "Southwest tag: ";
1915 tx = x - dr - x_font_size / 2 + tag_data.x_offset -
1917 ty = y + dr + y_font_size / 2 + tag_data.y_offset;
1918 break;
1919 default:
1920 PRINT_ERROR("Internal error: unexpected tag option");
1921 }
1923 }
1924 }
1925
1926 if (SCRATCH(p) and not ISRECTANGLE(p))
1927 {
1928 long double r = std::max(hr, vr) + 2.0 / resolution; // 2mm
1929 long double dr = sin_45 * r; /* radius r at 45 degrees */
1930 output << endl
1931 << "% Scratching" << endl
1932 << "\\path(" << x - dr << "," << YPIC(y - dr) << ")"
1933 << "(" << x + dr << "," << YPIC(y + dr) << ")"
1934 << "\\path(" << x + dr << "," << YPIC(y - dr) << ")"
1935 << "(" << x - dr << "," << YPIC(y + dr) << ")";
1936 }
1937
1938 EepicNode<long> *l = LLINK(p);
1939 EepicNode<long> *r = RLINK(p);
1940
1941 /* draw additional node arcs */
1942 for (DynDlist<Arc_Desc>::Iterator itor(ARCLIST(p)); itor.has_curr();
1943 itor.next())
1944 {
1945 Arc_Desc arc_desc = itor.get_curr();
1946
1947 if (arc_desc.target_node == l)
1948 { /* the arc will be drawn when processing left link */
1949 DASHLLINK(p) = arc_desc.is_dashed ? true : false;
1950 continue;
1951 }
1952
1953 if (arc_desc.target_node == r)
1954 { /* the arc will be drawn when processing right link */
1955 DASHRLINK(p) = arc_desc.is_dashed ? true : false;
1956 continue;
1957 }
1958
1959 long double tx = X(arc_desc.target_node);
1960 long double ty = Y(arc_desc.target_node);
1961 long double dx, dy;
1963 long double src_x, src_y, tgt_x, tgt_y;
1964
1965 /* determine arc x points according to node positions */
1966 if (x > tx)
1967 {
1968 src_x = x - dx;
1969 tgt_x = tx + dx;
1970 }
1971 else
1972 {
1973 src_x = x + dx;
1974 tgt_x = tx - dx;
1975 }
1976
1977 /* determine arc y points according to node positions */
1978 if (y > ty)
1979 {
1980 src_y = y - dy;
1981 tgt_y = ty + dy;
1982 }
1983 else
1984 {
1985 src_y = y + dy;
1986 tgt_y = ty - dy;
1987 }
1988
1989 if (ISTRIANGLE(arc_desc.target_node) or
1990 ISRECTANGLE(arc_desc.target_node))
1991 { // if triangle or rectangle, arc goes to triangle tip
1992 tgt_x = tx;
1993 tgt_y = ty;
1994 }
1995
1996 output << endl
1997 << "% Additional arc to infix node "
1998 << INFIXPOS(arc_desc.target_node)
1999 << " with key " << STRING(arc_desc.target_node)
2000 << endl;
2001
2003 arc_desc.is_dashed, with_arrow);
2004 }
2005
2006 /* processing of left child arc or thread */
2007 if (l != nullptr and WITHARC(l))
2008 { /* draw arc to left child */
2009 long double lx = X(l);
2010 long double ly = Y(l);
2011 long double dx, dy;
2013 output << endl
2014 << "% Arc to left infix node " << INFIXPOS(l)
2015 << " with key " << STRING(l) << endl;
2016
2018 draw_arc(output, x - dx, y + dy, lx, ly, DASHLLINK(p), with_arrow);
2019 else
2020 draw_arc(output, x - dx, y + dy, lx + dx, ly - dy,
2021 DASHLLINK(p), with_arrow);
2022 }
2023 else if (PREV(p) != nullptr and not ISTRIANGLE(p) and not ISRECTANGLE(p))
2024 { /* draw thread to predecessor */
2025 EepicNode<long> *prev = PREV(p);
2026 long double px = X(prev);
2027 long double py = Y(prev);
2028 long double dx, dy;
2030 output << endl
2031 << "% Thread to predecessor infix node " << INFIXPOS(prev)
2032 << " with key " << STRING(prev) << endl;
2034 output << "\\curve(" << x - dx << "," << YPIC(y + dy) << ","
2035 << px + dx << "," << YPIC(y + h) << ","
2036 << px + dx << "," << YPIC(py + dy) << ")";
2037 else
2038 output << "\\spline(" << x - dx << "," << YPIC(y + dy) << ")("
2039 << px << "," << YPIC(y + h) << ")("
2040 << px + dx << "," << YPIC(py + dy) << ")";
2041 }
2042
2043 /* processing of right child arc or thread */
2044 if (r != nullptr and WITHARC(r))
2045 { /* draw arc to right child */
2046 long double rx = X(r);
2047 long double ry = Y(r);
2048 long double dx, dy;
2050 output << endl
2051 << "% Arc to right infix node " << INFIXPOS(r)
2052 << " with key " << STRING(r) << endl;
2053
2054 if (ISEXTERNAL(r) or ISTRIANGLE(r) or ISRECTANGLE(r))
2055 draw_arc(output, x + dx, y + dy, rx, ry, DASHRLINK(p), with_arrow);
2056 else
2057 draw_arc(output, x + dx, y + dy, rx - dx, ry - dy,
2058 DASHRLINK(p), with_arrow);
2059 }
2060 else if (SUCC(p) != nullptr and not ISTRIANGLE(p) and not ISRECTANGLE(p))
2061 { /* draw thread to successor */
2062 EepicNode<long> *succ = SUCC(p);
2063 long double px = X(succ);
2064 long double py = Y(succ);
2065 long double dx, dy;
2067 output << endl
2068 << "% Thread to successor infix node " << INFIXPOS(succ)
2069 << " with key " << STRING(succ) << endl;
2071 output << "\\curve(" << x + dx << "," << YPIC(y + dy) << ","
2072 << px - dx << "," << YPIC(y + h) << ","
2073 << px - dx << "," << YPIC(py + dy) << ")";
2074 else
2075 output << "\\spline(" << x + dx << "," << YPIC(y + dy) << ")("
2076 << px << "," << YPIC(y + h) << ")("
2077 << px - dx << "," << YPIC(py + dy) << ")";
2078 }
2079
2080 generate_tree(output, l); /* process left tree branch */
2081 generate_tree(output, r); /* process right tree branch */
2082}
2083
2084inline
2086{
2088 PRINT_ERROR("Number of split points is greater than total of nodes");
2089
2090 for (int i = 0; i < split_dynarray.size(); i++)
2091 {
2092 int pos = split_dynarray[i];
2093 if (pos >= num_nodes - 1)
2094 PRINT_ERROR("Split position (%d) out of range", pos);
2095
2096 EepicNode<long> *src = select(root, pos);
2097
2098 const long double x = X(src);
2099 const long double line_space = 1.0 / resolution; // 1mm
2100 const long double line_len = v_size - 4 * line_space + vd / 2.0;
2101 long double dash_len = 1 / resolution; // 1mm
2102
2103 output << endl
2104 << "% Split line at node " << INFIXPOS(src)
2105 << " with key " << STRING(src) << endl
2106 << "\\dashline{" << dash_len << "}(" << x << ","
2107 << YPIC(line_space) << ")"
2108 << "(" << x << "," << YPIC(line_space + line_len) << ")";
2109
2111
2112 if (const int upper_len = split_data.upper_string.size(); upper_len > 0)
2113 {
2114 const long double upper_size =
2115 upper_len * (2.0 / resolution); // 2.0mm per letter
2116 const long double dx = upper_size / 2.0;
2117 output << endl
2118 << "\\put(" << x - dx << "," << YPIC(line_space) << ")"
2119 << "{" << font_wrapper << split_data.upper_string << "}}"
2120 << endl;
2121 }
2122
2123 if (const int lower_len = split_data.lower_string.size(); lower_len > 0)
2124 {
2125 const long double lower_size =
2126 lower_len * (2.0 / resolution); // 2.0mm per letter
2127 const long double dx = lower_size / 2.0;
2128 const long double font_height = 3.0 / resolution;
2129 output << endl
2130 << "\\put(" << x - dx << ","
2131 << YPIC(line_space + line_len + font_height) << ")"
2132 << "{" << font_wrapper << split_data.lower_string << "}}"
2133 << endl;
2134 }
2135 }
2136}
2137
2139 "btreepic 1.9.6\n"
2140 "ALEPH drawer for binary trees\n"
2141 "Copyright (C) 2007 UNIVERSITY of LOS ANDES (ULA)\n"
2142 "Merida - REPUBLICA BOLIVARIANA DE VENEZUELA\n"
2143 "Center of Studies in Microelectronics & Distributed Systems (CEMISID)\n"
2144 "ULA Computer Science Department\n"
2145 "This is free software; There is NO warranty; not even for MERCHANTABILITY\n"
2146 "or FITNESS FOR A PARTICULAR PURPOSE\n"
2147 "\n";
2148
2149static auto hello =
2150 "\n"
2151 "ALEPH drawer for binary trees\n"
2152 "Copyright (C) 2007, 2006, 2005, 2004, 2003, 2002 University of Los Andes (ULA)\n"
2153 "Merida - REPUBLICA BOLIVARIANA DE VENEZUELA\n"
2154 "Center of Studies in Microelectronics & Distributed Systems (CEMISID)\n"
2155 "ULA Computer Science Department\n"
2156 "This is free software; There is NO warranty; not even for MERCHANTABILITY\n"
2157 "or FITNESS FOR A PARTICULAR PURPOSE\n"
2158 "\n";
2159
2160static constexpr char license_text[] =
2161 "Aleph drawer for binary trees. License & Copyright Note\n"
2162 "Copyright (C) 2007, 2006, 2005, 2004, 2003, 2002\n"
2163 "UNIVERSITY of LOS ANDES (ULA)\n"
2164 "Merida - VENEZUELA\n"
2165 "Center of Studies in Microelectronics & Distributed Systems (CEMISID)\n"
2166 "ULA Computer Science Department\n"
2167 "This is free software; There is NO warranty; not even for MERCHANTABILITY\n"
2168 "or FITNESS FOR A PARTICULAR PURPOSE\n"
2169 "\n"
2170 " PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE AND ITS \n"
2171 " DOCUMENTATION IS HEREBY GRANTED, PROVIDED THAT BOTH THE COPYRIGHT \n"
2172 " NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES OF THE \n"
2173 " SOFTWARE, DERIVATIVE WORKS OR MODIFIED VERSIONS, AND ANY PORTIONS \n"
2174 " THEREOF, AND THAT BOTH NOTICES APPEAR IN SUPPORTING DOCUMENTATION. \n"
2175 "\n"
2176 " This program is distributed in the hope that it will be useful,\n"
2177 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
2178 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \n"
2179 "\n"
2180 " ULA requests users of this software to return to \n"
2181 " Proyecto Aleph - CEMISID Software\n"
2182 " Nucleo Universitario La Hechicera. Ed Ingenieria\n"
2183 " 3er piso, ala Este \n"
2184 " Universidad de Los Andes \n"
2185 " Merida 5101 - REPUBLICA BOLIVARIANA DE VENEZUELA \n"
2186 "\n"
2187 " or to lrleon@ula.ve \n"
2188 "\n"
2189 " any improvements or extensions that they make and grant Universidad \n"
2190 " de Los Andes (ULA) the full rights to redistribute these changes. \n"
2191 "\n"
2192 " This program was granted by: \n"
2193 " - Consejo de Desarrollo Cientifico, Humanistico, Tecnico de la ULA\n"
2194 " (CDCHT)\n";
2195
2196
2197inline
2199{
2200 cout
2201 << "Horizontal radius -x = " << hr << endl
2202 << "Vertical radius -y = " << vr << endl
2203 << "Horizontal diameter = " << hd << endl
2204 << "Vertical diameter = " << vd << endl
2205 << "Horizontal separation -w = " << w << endl
2206 << "Vertical separation -h = " << h << endl
2207 << "Resolution in mm -l = " << resolution << endl
2208 << "Horizontal size -z = " << h_size << endl
2209 << "Vertical size -u = " << v_size << endl
2210 << "Horizontal offset for key -X = " << x_offset << endl
2211 << "Vertical offset for key -Y = " << y_offset << endl
2212 << "Horizontal offset for aux tag -W = " << x_aux_offset << endl
2213 << "Vertical offset for aux tag -H = " << y_aux_offset << endl
2214 << "Horizontal offset for picture -O = " << x_picture_offset << endl
2215 << "Vertical offset for picture -P = " << y_picture_offset << endl;
2216}
2217
2218int main(int argc, char *argv[])
2219{
2221
2223
2224 try
2225 {
2226 TCLAP::CmdLine cmd(argp_program_version, ' ', "1.9.6", false);
2227
2228 TCLAP::ValueArg<double> radiusArg("r", "radius", "fit radius for circles", false, 0.0, "double");
2229 TCLAP::ValueArg<double> widthArg("w", "width", "horizontal separation", false, w, "double");
2230 TCLAP::ValueArg<double> heightArg("h", "height", "vertical separation", false, h, "double");
2231 TCLAP::ValueArg<double> hRadiusArg("x", "h-radius", "horizontal radius (ellipse)", false, hr, "double");
2232 TCLAP::ValueArg<double> vRadiusArg("y", "v-radius", "vertical radius (ellipse)", false, vr, "double");
2233 TCLAP::ValueArg<double> resolArg("l", "resol", "resolution in mm", false, resolution, "double");
2234 TCLAP::SwitchArg latexArg("a", "latex", "add latex header", false);
2235 TCLAP::SwitchArg landscapeArg("p", "landscape", "latex landscape mode", false);
2236 TCLAP::SwitchArg withKeyArg("k", "with-key", "printing keys", false);
2237 TCLAP::SwitchArg tinyKeysArg("K", "tiny-keys", "printing keys with tiny font", false);
2238 TCLAP::SwitchArg fitArg("t", "fit", "fit in rectangle", false);
2239 TCLAP::ValueArg<double> horizontalArg("z", "horizontal", "specify horizontal width for fitting", false, h_size,
2240 "double");
2241 TCLAP::ValueArg<double> verticalArg("u", "vertical", "specify vertical height for fitting", false, v_size,
2242 "double");
2243 TCLAP::SwitchArg minRadiusArg("n", "min-radius", "radious is minimum", false);
2244 TCLAP::SwitchArg withoutNodeArg("N", "without-node", "no draw node; only arcs", false);
2245 TCLAP::ValueArg<double> keyXOffsetArg("X", "key-x-offset", "horizontal offset for keys", false, x_offset,
2246 "double");
2247 TCLAP::ValueArg<double> keyYOffsetArg("Y", "key-y-offset", "vertical offset for keys", false, y_offset, "double");
2248 TCLAP::ValueArg<double> auxYOffsetArg("H", "aux-y-offset", "vertical offset for auxiliary string", false,
2249 y_aux_offset, "double");
2250 TCLAP::ValueArg<double> auxXOffsetArg("W", "aux-x-offset", "horizontal offset for auxiliary string", false,
2251 x_aux_offset, "double");
2252 TCLAP::ValueArg<string> inputFileArg("i", "input-file", "input file", false, "", "string");
2253 TCLAP::ValueArg<string> inputFileAliasArg("f", "file", "input file (alias)", false, "", "string");
2254 TCLAP::ValueArg<string> outputFileArg("o", "output", "output file", false, "", "string");
2255 TCLAP::SwitchArg licenseArg("C", "license", "print license", false);
2256 TCLAP::ValueArg<double> xPictureOffsetArg("O", "x-picture-offset", "horizontal global picture offset", false,
2257 x_picture_offset, "double");
2258 TCLAP::ValueArg<double> yPictureOffsetArg("P", "y-picture-offset", "vertical global picture offset", false,
2259 y_picture_offset, "double");
2260 TCLAP::SwitchArg printArg("R", "print", "print current parameters", false);
2261 TCLAP::SwitchArg verboseArg("v", "verbose", "verbose mode", false);
2262 TCLAP::SwitchArg unsilentArg("s", "unsilent", "unsilent mode - print tokens", false);
2263 TCLAP::SwitchArg versionArg("V", "version", "Print version information and then exit", false);
2264 TCLAP::SwitchArg blackFillArg("B", "black-fill", "Fill black ellipses", false);
2265 TCLAP::SwitchArg shadeFillArg("S", "shade-fill", "Fill shade ellipses", false);
2266 TCLAP::SwitchArg threadedArg("D", "threaded", "draw dotted threads instead nullptr pointers", false);
2267 TCLAP::SwitchArg threadedNoDashArg("T", "threaded-no-dash", "draw contiguous threads instead nullptr pointers",
2268 false);
2269 TCLAP::SwitchArg externalNodesArg("e", "external-nodes", "draw external nodes", false);
2270 TCLAP::ValueArg<double> arrowLenArg("L", "arrow-len", "arrow lenght", false, arrow_lenght, "double");
2271 TCLAP::ValueArg<double> arrowWidthArg("I", "arrow-width", "arrow width", false, arrow_width, "double");
2272 TCLAP::SwitchArg arrowsArg("A", "arrows", "draw arcs with arrows", false);
2273 TCLAP::SwitchArg verticalFlipArg("F", "vertical-flip", "Flip tree respect y axe", false);
2274 TCLAP::SwitchArg helpArg("", "help", "Print this help message", false);
2275
2276 cmd.add(radiusArg);
2277 cmd.add(widthArg);
2278 cmd.add(heightArg);
2279 cmd.add(hRadiusArg);
2280 cmd.add(vRadiusArg);
2281 cmd.add(resolArg);
2282 cmd.add(latexArg);
2283 cmd.add(landscapeArg);
2284 cmd.add(withKeyArg);
2285 cmd.add(tinyKeysArg);
2286 cmd.add(fitArg);
2287 cmd.add(horizontalArg);
2288 cmd.add(verticalArg);
2289 cmd.add(minRadiusArg);
2290 cmd.add(withoutNodeArg);
2291 cmd.add(keyXOffsetArg);
2292 cmd.add(keyYOffsetArg);
2293 cmd.add(auxYOffsetArg);
2294 cmd.add(auxXOffsetArg);
2295 cmd.add(inputFileArg);
2297 cmd.add(outputFileArg);
2298 cmd.add(licenseArg);
2301 cmd.add(printArg);
2302 cmd.add(verboseArg);
2303 cmd.add(unsilentArg);
2304 cmd.add(versionArg);
2305 cmd.add(blackFillArg);
2306 cmd.add(shadeFillArg);
2307 cmd.add(threadedArg);
2309 cmd.add(externalNodesArg);
2310 cmd.add(arrowLenArg);
2311 cmd.add(arrowWidthArg);
2312 cmd.add(arrowsArg);
2313 cmd.add(verticalFlipArg);
2314 cmd.add(helpArg);
2315
2316 cmd.parse(argc, argv);
2317
2318 if (helpArg.getValue())
2319 {
2320 cmd.getOutput()->usage(cmd);
2321 TERMINATE(0);
2322 }
2323
2324 if (versionArg.getValue())
2325 {
2327 TERMINATE(0);
2328 }
2329
2330 if (licenseArg.getValue())
2331 {
2332 cout << license_text;
2333 TERMINATE(0);
2334 }
2335
2336 if (radiusArg.isSet())
2337 {
2338 hr = vr = radiusArg.getValue();
2339 hd = vd = 2 * hr;
2340 }
2341 if (widthArg.isSet()) w = widthArg.getValue();
2342 if (heightArg.isSet()) h = heightArg.getValue();
2343 if (hRadiusArg.isSet())
2344 {
2345 hr = hRadiusArg.getValue();
2346 hd = 2 * hr;
2347 }
2348 if (vRadiusArg.isSet())
2349 {
2350 vr = vRadiusArg.getValue();
2351 vd = 2 * vr;
2352 }
2353 if (resolArg.isSet())
2354 {
2355 resolution = resolArg.getValue();
2356 if (resolution > 10) cout << "Warning: resolution too big" << endl;
2357 }
2358 if (latexArg.getValue()) latex_header = true;
2359 if (landscapeArg.getValue())
2360 {
2361 latex_header = true;
2362 landscape = true;
2363 }
2364 if (withKeyArg.getValue()) printing_key_mode = true;
2365 if (tinyKeysArg.getValue()) tiny_keys = true;
2366 if (fitArg.getValue()) fit_mode = true;
2367 if (horizontalArg.isSet()) h_size = horizontalArg.getValue();
2368 if (verticalArg.isSet()) v_size = verticalArg.getValue();
2369 if (minRadiusArg.getValue())
2370 {
2371 hr = vr = resolution / 2;
2372 hd = vd = resolution;
2373 }
2374 if (withoutNodeArg.getValue()) draw_nodes = false;
2375 if (keyXOffsetArg.isSet()) x_offset = keyXOffsetArg.getValue();
2376 if (keyYOffsetArg.isSet()) y_offset = keyYOffsetArg.getValue();
2377 if (auxYOffsetArg.isSet()) y_aux_offset = auxYOffsetArg.getValue();
2378 if (auxXOffsetArg.isSet()) x_aux_offset = auxXOffsetArg.getValue();
2379
2380 if (inputFileArg.isSet()) input_file_name = inputFileArg.getValue();
2381 else if (inputFileAliasArg.isSet()) input_file_name = inputFileAliasArg.getValue();
2382
2383 if (outputFileArg.isSet()) output_file_name = outputFileArg.getValue();
2384
2385 if (xPictureOffsetArg.isSet()) x_picture_offset = xPictureOffsetArg.getValue();
2386 if (yPictureOffsetArg.isSet()) y_picture_offset = yPictureOffsetArg.getValue();
2387
2388 if (printArg.getValue())
2389 {
2392 TERMINATE(0);
2393 }
2394
2395 if (unsilentArg.getValue()) silent_mode = false;
2396
2397 if (blackFillArg.getValue()) fill_type = "black";
2398 if (shadeFillArg.getValue()) fill_type = "shade";
2399
2400 if (threadedArg.getValue()) dash_threaded_trees = true;
2401 if (threadedNoDashArg.getValue()) threaded_trees = true;
2402
2403 if (externalNodesArg.getValue()) with_external_nodes = true;
2404
2405 if (arrowLenArg.isSet())
2406 {
2407 with_arrow = true;
2408 arrow_lenght = arrowLenArg.getValue();
2409 }
2410 if (arrowWidthArg.isSet())
2411 {
2412 with_arrow = true;
2413 arrow_width = arrowWidthArg.getValue();
2414 }
2415 if (arrowsArg.getValue()) with_arrow = true;
2416
2417 if (verticalFlipArg.getValue()) flip_y = true;
2418 }
2419 catch (TCLAP::ArgException & e)
2420 {
2421 cerr << "error: " << e.error() << " for arg " << e.argId() << endl;
2422 return 1;
2423 }
2424
2425 if (input_file_name.empty())
2426 AH_ERROR("Input file not given");
2427
2428 cout << hello;
2429
2431
2433
2434 if (output_file_name.empty())
2435 {
2437 if (const int pos = input_file_name.rfind("."); pos != string::npos)
2439 string(input_file_name).replace(pos, input_file_name.size() - pos,
2440 string(""));
2441 output_file_name = output_file_name + (tiny_keys ? ".eepicaux" : ".eepic");
2442 }
2443
2444 cout << "input from " << input_file_name << " file " << endl
2445 << "output sent to " << output_file_name << " file " << endl << endl;
2446
2447 ofstream output(output_file_name.c_str(), ios::out);
2452 output.close();
2453
2455}
#define AH_ERROR(format, args...)
Print an error message (always enabled).
Definition ahDefs.H:271
int main()
Core header for the Aleph-w library.
WeightedDigraph::Node Node
DynArray< Thread_Data > target_thread_dynarray
Definition btreepic.C:470
void assign_pos_and_level(EepicNode< long > *p, const int level, const int position)
Definition btreepic.C:1090
void save_parameters()
Definition btreepic.C:431
Parsing_State
Definition btreepic.C:831
@ INFIX
Definition btreepic.C:833
@ KEYS
Definition btreepic.C:834
@ PREFIX
Definition btreepic.C:832
void thread_tree(EepicNode< long > *p)
Definition btreepic.C:1099
bool draw_node_mode
Definition btreepic.C:418
const char * parameters_file_name
Definition btreepic.C:427
void assign_rectangle(EepicNode< long > *p, int, const int position)
Definition btreepic.C:1028
void assign_tag(EepicNode< long > *p, int, const int position)
Definition btreepic.C:876
bool fit_mode
Definition btreepic.C:417
bool west_offset(EepicNode< long > *root)
Definition btreepic.C:1331
Token_Type get_token(ifstream &input_stream)
Definition btreepic.C:655
Node * select(Node *root, const int &i)
Definition btreepic.C:902
void load_tag_option(ifstream &input_stream)
Definition btreepic.C:515
bool landscape
Definition btreepic.C:416
void file_to_dynarrays(const char *file_name)
Definition btreepic.C:1122
DynArray< long > key_pos_dynarray
Definition btreepic.C:478
DynArray< long > shadow_dynarray
Definition btreepic.C:458
#define DASHLLINK(p)
Definition btreepic.C:393
void assign_xoffset(EepicNode< long > *p, int, const int position)
Definition btreepic.C:996
#define ISRECTANGLE(p)
Definition btreepic.C:386
bool south_offset(EepicNode< long > *root, const size_t &level)
Definition btreepic.C:1351
void load_thread_option(ifstream &input_stream)
Definition btreepic.C:546
DynArray< long > pos_parrectangle_dynarray
Definition btreepic.C:499
void assign_distance(EepicNode< long > *p, int, const int position)
Definition btreepic.C:1057
bool with_external_nodes
Definition btreepic.C:424
#define SHADOW(p)
Definition btreepic.C:389
Token_Type
Definition btreepic.C:166
@ START_KEY
Definition btreepic.C:167
@ START_AUX
Definition btreepic.C:168
@ NUMBER
Definition btreepic.C:167
@ ARC
Definition btreepic.C:168
@ KEY
Definition btreepic.C:169
@ DISTANCE
Definition btreepic.C:171
@ TRIANGLE
Definition btreepic.C:169
@ START_PREFIX
Definition btreepic.C:167
@ PARRECTANGLE
Definition btreepic.C:170
@ SPLIT
Definition btreepic.C:169
@ SOUTH
Definition btreepic.C:174
@ SOUTH_WEST
Definition btreepic.C:180
@ DASHED_ARC
Definition btreepic.C:168
@ END_FILE
Definition btreepic.C:181
@ COMMENT
Definition btreepic.C:170
@ TAG
Definition btreepic.C:168
@ EAST
Definition btreepic.C:175
@ NORTH_WEST
Definition btreepic.C:178
@ WITHOUT_NODE
Definition btreepic.C:168
@ THREAD
Definition btreepic.C:171
@ NORTH
Definition btreepic.C:173
@ NORTH_EAST
Definition btreepic.C:177
@ SHADOW_NODE
Definition btreepic.C:168
@ SOUTH_EAST
Definition btreepic.C:179
@ LEFT
Definition btreepic.C:171
@ RECTANGLE
Definition btreepic.C:170
@ WEST
Definition btreepic.C:176
@ RIGHT
Definition btreepic.C:171
@ INVALID
Definition btreepic.C:181
@ WITHOUT_ARC
Definition btreepic.C:170
@ START_INFIX
Definition btreepic.C:167
void assign_external_nodes(EepicNode< long > *p)
Definition btreepic.C:970
DynArray< long > pos_xoffset_dynarray
Definition btreepic.C:482
DynArray< long > tag_pos_dynarray
Definition btreepic.C:463
#define ARCLIST(p)
Definition btreepic.C:396
void load_parrectangle_option(ifstream &input_stream)
Definition btreepic.C:620
void adjust_size_by_tags(EepicNode< long > *root, const size_t &height)
Definition btreepic.C:1378
void assign_key(EepicNode< long > *p, int, const int position)
Definition btreepic.C:840
void generate_split_lines(ofstream &output, EepicNode< long > *root)
Definition btreepic.C:2085
long double y_offset
Definition btreepic.C:158
#define Y(p)
Definition btreepic.C:375
#define ISEXTERNAL(p)
Definition btreepic.C:381
long double h_size
Definition btreepic.C:155
#define PREV(p)
Definition btreepic.C:399
DynArray< long > infix_dynarray
Definition btreepic.C:455
void assign_aux(EepicNode< long > *p, int, const int position)
Definition btreepic.C:845
void generate_epilogue(ofstream &output)
Definition btreepic.C:1660
DynArray< long > without_node_dynarray
Definition btreepic.C:460
static constexpr char license_text[]
Definition btreepic.C:2160
long double hr
Definition btreepic.C:149
#define YOFFSET(p)
Definition btreepic.C:377
long double vr
Definition btreepic.C:150
DynArray< long > pos_distance_dynarray
Definition btreepic.C:502
#define X(p)
Definition btreepic.C:374
#define WITHOUT(p)
Definition btreepic.C:390
string output_file_name
Definition btreepic.C:407
long double x_aux_offset
Definition btreepic.C:159
void assign_arcs(EepicNode< long > *root, EepicNode< long > *p)
Definition btreepic.C:920
bool latex_header
Definition btreepic.C:415
void load_arc_option(ifstream &input_stream, const Token_Type &token_type)
Definition btreepic.C:535
long double x_picture_offset
Definition btreepic.C:161
DynArray< long double > xoffset_dynarray
Definition btreepic.C:483
void load_offset_option(ifstream &input_stream, DynArray< long > &positions, DynArray< long double > &offsets)
Definition btreepic.C:579
const char * argp_program_version
Definition btreepic.C:2138
DynArray< Line_Distance_Data > distance_dynarray
Definition btreepic.C:503
#define XOFFSET(p)
Definition btreepic.C:376
static auto hello
Definition btreepic.C:2149
void read_parameters()
Definition btreepic.C:444
#define LEVEL(p)
Definition btreepic.C:373
bool verbose_mode
Definition btreepic.C:413
DynArray< long double > height_parrectangle_dynarray
Definition btreepic.C:498
DynArray< string > key_print_dynarray
Definition btreepic.C:456
long double vd
Definition btreepic.C:152
double v_size
Definition btreepic.C:156
DynArray< Arc_Data > target_arc_dynarray
Definition btreepic.C:466
void assign_yoffset(EepicNode< long > *p, int, const int position)
Definition btreepic.C:1005
#define TAGLIST(p)
Definition btreepic.C:395
#define TRIANGLEH(p)
Definition btreepic.C:378
bool printing_key_mode
Definition btreepic.C:419
void assign_triangle(EepicNode< long > *p, int, const int position)
Definition btreepic.C:1014
DynArray< long double > height_rectangle_dynarray
Definition btreepic.C:494
void compute_picture_size(EepicNode< long > *p)
Definition btreepic.C:1421
DynArray< long > pos_rectangle_dynarray
Definition btreepic.C:495
bool dash_threaded_trees
Definition btreepic.C:423
void assign_without_node(EepicNode< long > *p, int, const int position)
Definition btreepic.C:869
void load_split_option(ifstream &input_stream)
Definition btreepic.C:557
DynArray< long double > height_triangle_dynarray
Definition btreepic.C:491
bool silent_mode
Definition btreepic.C:414
void load_distance_option(ifstream &input_stream)
Definition btreepic.C:635
void assign_shadow(EepicNode< long > *p, int, const int position)
Definition btreepic.C:850
EepicNode< long > * build_tree()
Definition btreepic.C:1435
DynArray< long > scratch_dynarray
Definition btreepic.C:472
DynArray< string > aux_print_dynarray
Definition btreepic.C:457
#define LDISTANCE(p)
Definition btreepic.C:384
void reassign_key(EepicNode< long > *p, int, const int position)
Definition btreepic.C:860
#define WITHARC(p)
Definition btreepic.C:392
bool draw_nodes
Definition btreepic.C:425
long double hd
Definition btreepic.C:151
long double x_offset
Definition btreepic.C:157
#define RECTANGLEH(p)
Definition btreepic.C:379
DynArray< long > prefix_dynarray
Definition btreepic.C:454
DynArray< string > key_string_dynarray
Definition btreepic.C:479
string input_file_name
Definition btreepic.C:406
void assign_without_arc(EepicNode< long > *p, int, const int position)
Definition btreepic.C:1076
DynArray< long > without_arc_dynarray
Definition btreepic.C:505
bool with_string_key
Definition btreepic.C:420
#define ISDISTANCE(p)
Definition btreepic.C:385
void load_rectangle_option(ifstream &input_stream)
Definition btreepic.C:604
void assign_parrectangle(EepicNode< long > *p, int, const int position)
Definition btreepic.C:1042
long double h
Definition btreepic.C:154
#define DYNARRAY_APPEND(array, item)
Definition btreepic.C:509
string command_line
Definition btreepic.C:403
#define SUCC(p)
Definition btreepic.C:398
DynArray< long double > yoffset_dynarray
Definition btreepic.C:487
void print_parameters()
Definition btreepic.C:2198
DynArray< long > pos_yoffset_dynarray
Definition btreepic.C:486
#define ISTRIANGLE(p)
Definition btreepic.C:382
DynArray< long > pos_triangle_dynarray
Definition btreepic.C:490
void set_picture_size(EepicNode< long > *p)
Definition btreepic.C:1396
DynArray< Tag_Data > tag_data_dynarray
Definition btreepic.C:462
void assign_scratch(EepicNode< long > *p, int, const int position)
Definition btreepic.C:989
#define EXTERNAL(p)
Definition btreepic.C:380
long double y_picture_offset
Definition btreepic.C:162
#define STRING(p)
Definition btreepic.C:387
long double w
Definition btreepic.C:153
void generate_prologue(ofstream &output)
Definition btreepic.C:1600
#define TERMINATE(n)
Definition btreepic.C:507
void load_triangle_option(ifstream &input_stream)
Definition btreepic.C:593
#define AUX(p)
Definition btreepic.C:388
bool threaded_trees
Definition btreepic.C:422
int num_nodes
Definition btreepic.C:410
#define DASHRLINK(p)
Definition btreepic.C:394
bool north_offset(EepicNode< long > *p)
Definition btreepic.C:1293
DynArray< long > source_arc_dynarray
Definition btreepic.C:464
DynArray< long > source_thread_dynarray
Definition btreepic.C:468
void load_triangleh_option(ifstream &input_stream)
Definition btreepic.C:587
Token_Type Tag_Option
Definition btreepic.C:185
bool with_string_aux
Definition btreepic.C:421
int max_num_nodes_rectangle
Definition btreepic.C:602
void generate_tree(ofstream &output, EepicNode< long > *p)
Definition btreepic.C:1672
DynArray< Split_Data > split_string_dynarray
Definition btreepic.C:476
void load_key_option(ifstream &input_stream)
Definition btreepic.C:569
#define THREADLIST(p)
Definition btreepic.C:397
#define SCRATCH(p)
Definition btreepic.C:391
DynArray< long > split_dynarray
Definition btreepic.C:474
bool east_offset(EepicNode< long > *root)
Definition btreepic.C:1311
long double y_aux_offset
Definition btreepic.C:160
#define INFIXPOS(p)
Definition btreepic.C:372
void cut(const size_t new_dim=0)
Cut the array to a new dimension; that is, it reduces the dimension of array and frees the remaining ...
size_t size() const noexcept
Return the current dimension of array.
Iterator dynamic list.
Dynamic doubly linked list with O(1) size and bidirectional access.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
string aux_string
Definition btreepic.C:284
DynDlist< Tag_Data > tag_list
Definition btreepic.C:298
bool without_node
Definition btreepic.C:286
long double xoffset
Definition btreepic.C:274
Line_Distance_Data & get_line_distance_data()
Definition btreepic.C:346
bool & get_external_node()
Definition btreepic.C:334
DynDlist< Thread_Desc > thread_list
Definition btreepic.C:302
long double & get_yoffset()
Definition btreepic.C:332
EepicNode< long > * prev
Definition btreepic.C:293
bool is_triangle() const
Definition btreepic.C:338
long double & get_xoffset()
Definition btreepic.C:330
int & get_level()
Definition btreepic.C:320
string & get_key_string()
Definition btreepic.C:342
bool & get_dash_llink()
Definition btreepic.C:356
Line_Distance_Data line_distance_data
Definition btreepic.C:296
long double & get_y()
Definition btreepic.C:324
bool & get_dash_rlink()
Definition btreepic.C:358
DynDlist< Arc_Desc > & get_arc_list()
Definition btreepic.C:366
long double triangle_height
Definition btreepic.C:277
long double yoffset
Definition btreepic.C:275
bool & get_scratch()
Definition btreepic.C:352
long double rectangle_height
Definition btreepic.C:279
long double y
Definition btreepic.C:272
bool is_rectangle() const
Definition btreepic.C:340
EepicNode< long > * succ
Definition btreepic.C:294
bool & get_without_node()
Definition btreepic.C:350
string key_string
Definition btreepic.C:283
int & getCount()
Definition btreepic.C:318
bool external_node
Definition btreepic.C:281
string & get_aux_string()
Definition btreepic.C:344
bool is_external() const
Definition btreepic.C:336
DynDlist< Arc_Desc > arc_list
Definition btreepic.C:300
EepicNode< long > *& get_prev()
Definition btreepic.C:360
DynDlist< Tag_Data > & get_tag_list()
Definition btreepic.C:364
long double & get_triangle_height()
Definition btreepic.C:326
DynDlist< Thread_Desc > & get_thread_list()
Definition btreepic.C:368
bool & get_shadow()
Definition btreepic.C:348
long double & get_rectangle_height()
Definition btreepic.C:328
long double & get_x()
Definition btreepic.C:322
EepicNode< long > *& get_succ()
Definition btreepic.C:362
long double x
Definition btreepic.C:271
bool & get_with_arc()
Definition btreepic.C:354
bool tiny_keys
Global flag to enable tiny font size for keys/labels.
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_y1_function > > y1(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4103
__gmp_expr< T, __gmp_binary_expr< __gmp_expr< T, U >, unsigned long int, __gmp_root_function > > root(const __gmp_expr< T, U > &expr, unsigned long int l)
Definition gmpfrxx.h:4060
int preOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Traverse recursively in preorder a binary tree.
DynDlist< Node * > compute_nodes_in_level(Node *root, const int &level)
Count the number of nodes in a specific tree level.
Node * find_min(Node *root) noexcept
Return the minimum key contained in a binary search tree.
constexpr Node *& RLINK(Node *p) noexcept
Return the right tree of p.
int inOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Traverse recursively inorder a binary tree.
#define DECLARE_BINNODE(Name, height, Control_Data)
Specify tree node for a binary tree.
constexpr Node *& LLINK(Node *p) noexcept
Return a pointer to left subtree.
size_t computeHeightRec(Node *root) noexcept
Compute recursively the height of root
Node * find_max(Node *root) noexcept
Return the maximum key contained in a binary search tree.
static mpfr_t y
Definition mpfr_mul_d.c:3
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
long search_max(T *a, const long l, const long r, const Compare &cmp=Compare())
Returns the maximum element of the array a between l and r.
void init_token_scanning()
Initialize token scanning by recording current position.
void close_token_scanning(const char *buffer, char *&start_addr, const char *end_addr)
Finalize token scanning by null-terminating and saving the token.
int read_char_from_stream(std::ifstream &input_stream)
Read a single character from an input stream with position tracking.
void print_parse_error_and_exit(const std::string &str)
Print a parse error message and terminate the program.
std::string token_instance
The most recently scanned token.
void put_char_in_buffer(char *&start_addr, const char *end_addr, int c)
Append a character to a buffer with bounds checking.
std::string command_line_to_string(int argc, char *argv[])
Convert command line arguments to a single string.
void skip_white_spaces(std::ifstream &input_stream)
Skip whitespace characters in the input stream.
constexpr size_t Buffer_Size
Default buffer size for token parsing.
std::string load_string(std::ifstream &input_stream)
Load a string from the input stream.
DynList< T > maps(const C &c, Op op)
Classic map operation.
long load_number(std::ifstream &input_stream)
Load an integer number from the input stream.
STL namespace.
Token_Type Tag_Option
Definition ntreepic.C:237
Comprehensive parsing utilities for text processing and compiler construction.
#define PRINT_ERROR(str, args...)
Macro for printing detailed parse errors.
Arc_Data()=default
bool is_dashed
Definition btreepic.C:223
long target_node
Definition btreepic.C:222
bool is_dashed
Definition btreepic.C:214
EepicNode< long > * target_node
Definition btreepic.C:213
Arc_Desc()=default
long double xoffset
Definition btreepic.C:258
long double yoffset
Definition btreepic.C:259
Token_Type orientation
Definition btreepic.C:257
bool is_left() const
Definition btreepic.C:261
string lower_string
Definition btreepic.C:250
string upper_string
Definition btreepic.C:249
long double x_offset
Definition btreepic.C:194
string tag
Definition btreepic.C:192
Tag_Option tag_option
Definition btreepic.C:193
Tag_Data(const string &str, Tag_Option option)
Definition btreepic.C:199
long double y_offset
Definition btreepic.C:195
Tag_Data()=default
Thread_Data()=default
bool is_dashed
Definition btreepic.C:241
long target_node
Definition btreepic.C:240
bool is_dashed
Definition btreepic.C:232
Thread_Desc()=default
EepicNode< long > * target_node
Definition btreepic.C:231
Utility functions for binary tree operations.
Basic binary tree node definitions.
Lazy and scalable dynamic array implementation.
Dynamic doubly linked list implementation.
Comprehensive sorting algorithms and search utilities for Aleph-w.
DynList< int > l
Tree picture generation utilities.
void intersection_ellipse_line(long double lx0, long double ly0, long double lx1, long double ly1, long double a, long double b, long double &dx, long double &dy)
const char *const font_wrapper
long double resolution
void put_string(std::ofstream &output, const long double &x, const long double &y, const std::string &comment, const std::string &str)
long double string_width(const std::string &str)
long double arrow_lenght
bool with_arrow
bool flip_y
long double dash_len
void draw_arc(std::ofstream &output, long double src_x, long double src_y, long double tgt_x, long double tgt_y, bool is_dashed, bool with_arrow, bool thick=true)
long double arrow_width
const char * fill_type
long double font_height()
long double YPIC(long double y)
long double center_string(const std::string &str, long double window_size)
const long double sin_45
ofstream output
Definition writeHeap.C:213