-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathmark-down-toc-generator.php
More file actions
162 lines (127 loc) · 6.92 KB
/
mark-down-toc-generator.php
File metadata and controls
162 lines (127 loc) · 6.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<?php
require_once './vendor/autoload.php';
use \VersatileCollections\ObjectsCollection;
use \VersatileCollections\StringsCollection;
$class = new \ReflectionClass(\VersatileCollections\CollectionInterface::class);
$class_name_parts = explode('\\', $class->getName());
$class_name_without_namespace = array_pop($class_name_parts);
// get an array of \ReflectionMethod objects for the public methods in
// \VersatileCollections\CollectionInterface
$interface_public_methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);
// Create a collection of \ReflectionMethod objects
$interface_methods_collection =
ObjectsCollection::makeNew($interface_public_methods);
// A callback that accepts a $collection of strings (in this case method names)
// and generates a mark down table with 3 columns from the collection.
$generateMarkDownTableFromStringCollectionOfMethodNames = function($collection) use ($class_name_without_namespace) {
// We want to generate a markdown table with three columns
// let's calculate the maximum amount of items for each column.
$max_col_length = ceil( $collection->count() / 3 );
// Split the collection of all method names in to 3 collections
// each having at most $max_col_length items
$collection_of_3_columns = $collection->getCollectionsOfSizeN($max_col_length);
// extract the 3 collections
$collection_of_1st_col_items = $collection_of_3_columns->getAndRemoveFirstItem();
$collection_of_2nd_col_items = $collection_of_3_columns->getAndRemoveFirstItem();
$collection_of_3rd_col_items = $collection_of_3_columns->getAndRemoveFirstItem();
$max_width_calculator = function ($carry, $item) {
// because each mark down table cell will
// potentially contain a link in the format below:
// "[{$item}](#{$item})"
// we need to calculate the length of $item multiplied by 2
// plus the following extra characters `[`, `]`, `(`, `#` and `)`
// plus two extra spaces (which is how we get the number 7 we are
// adding)
$current_item_length = ((strlen($item) * 2) + 7);
return $carry > $current_item_length
? $carry : $current_item_length;
};
$max_width_of_1st_column = $collection_of_1st_col_items->reduce(
$max_width_calculator,
-1 // Initial value of $carry (a negative length, which no string can possibly have)
) + strlen(''.$class_name_without_namespace);
$max_width_of_2nd_column = $collection_of_2nd_col_items->reduce(
$max_width_calculator,
-1 // start with a negative length, which no string can possibly have
) + strlen(''.$class_name_without_namespace);
$max_width_of_3rd_column = $collection_of_3rd_col_items->reduce(
$max_width_calculator,
-1 // start with a negative length, which no string can possibly have
) + strlen(''.$class_name_without_namespace);
$mark_down_table = ''.PHP_EOL;
// generate table headers
$mark_down_table .= '|'. str_repeat(' ', $max_width_of_1st_column);// column 1
$mark_down_table .= '|'. str_repeat(' ', $max_width_of_2nd_column);// column 2
$mark_down_table .= '|'. str_repeat(' ', $max_width_of_3rd_column);// column 3
$mark_down_table .= '|'. PHP_EOL; // end row
$mark_down_table .= '|---'. str_repeat(' ', $max_width_of_1st_column - 3);// column 1
$mark_down_table .= '|---'. str_repeat(' ', $max_width_of_2nd_column - 3);// column 2
$mark_down_table .= '|---'. str_repeat(' ', $max_width_of_3rd_column - 3);// column 3
$mark_down_table .= '|'. PHP_EOL; // end row
$generate_cell_content = function($current_method_name, $max_width_of_column)use($class_name_without_namespace) {
$toc_link_for_column =
"[{$current_method_name}](#{$class_name_without_namespace}-{$current_method_name})";
$num_spaces_at_cell_end =
($max_width_of_column - strlen($toc_link_for_column));
return '|'. $toc_link_for_column
.
(
( $num_spaces_at_cell_end > 0 )
? str_repeat(' ', $num_spaces_at_cell_end ) : ''
);
};
// loop through the three column collections in parallel
$collection_of_1st_col_items->each(
function($key, $_1st_column_method_name)
use(
&$mark_down_table, // by Ref because we want changes to affect original variable
$generate_cell_content,
$max_width_of_1st_column, $max_width_of_2nd_column,
$max_width_of_3rd_column, $collection_of_2nd_col_items,
$collection_of_3rd_col_items
) {
// generate next cell for 1st column
$mark_down_table .= $generate_cell_content(
$_1st_column_method_name,
$max_width_of_1st_column
);
// generate next cell for 2nd column
$mark_down_table .= $generate_cell_content(
$collection_of_2nd_col_items->getAndRemoveFirstItem(),
$max_width_of_2nd_column
);
// generate next cell for 3rd column
// The 3rd column could be shorter than the first two
if( $collection_of_3rd_col_items->isEmpty() ) {
// spit out blank cell
$mark_down_table .= '|'. str_repeat(' ', $max_width_of_3rd_column);// column 3
} else {
$mark_down_table .= $generate_cell_content(
$collection_of_3rd_col_items->getAndRemoveFirstItem(),
$max_width_of_3rd_column
);
}
$mark_down_table .= '|'. PHP_EOL; // end row
} // function($key, $_1st_column_method_name) use .....
); // $collection_of_1st_col_items->each( ....
return $mark_down_table.PHP_EOL;
}; // $generateMarkDownTableFromStringCollectionOfMethodNames = function($collection)
$mark_down_table_of_contents =
$interface_methods_collection->pipeAndReturnCallbackResult(
function($collection) {
return StringsCollection::makeNew(
$collection->getName() // calls the getName() method on each
// \ReflectionMethod object in $collection
// via __call magic and returns an array of
// the names.
// see \VersatileCollections\ObjectsCollection::__call()
);
}
) // at this point we have extracted the method names from the collection of
// \ReflectionMethod objects. These method names are now in a new
// \VersatileCollections\StringsCollection instance
->sortMe() // we now sort the string collection in ascending order
->pipeAndReturnCallbackResult(
$generateMarkDownTableFromStringCollectionOfMethodNames // our callback
); // return table of contents at this point
echo $mark_down_table_of_contents; // spit out the mark down table