@@ -21,8 +21,12 @@ Usage: %s [options] <selector> <mode> [mode argument]
21
21
Options:
22
22
-h, --help
23
23
show this text
24
- -f, --file
24
+ -f, --file <file>
25
25
file to read (defaults to stdin)
26
+ -d, --delimiter <delim>
27
+ delimiter character to use between results (defaults to newline)
28
+ -0, --null
29
+ uses \0 as delimiter
26
30
27
31
<selector>
28
32
CSS selector to match against
@@ -47,6 +51,7 @@ static map<const string, bool> flags = {
47
51
static map<const string, string> state = { // global state
48
52
{" progname" , " hq" }, // program name
49
53
{" file" , " -" }, // input file path, or - for stdin
54
+ {" delim" , " \n " }, // result delimiter
50
55
{" selector" , " " }, // matching selector
51
56
{" mode" , " " }, // output mode
52
57
{" data" , " " }, // read input data
@@ -87,7 +92,9 @@ template <typename T> inline bool vec_has(vector<T> &vec, T val){
87
92
88
93
static map<const char , const string> option_longopts = { // maps shortopts to longopts from option_handlers
89
94
{' h' , " help" },
90
- {' f' , " file" }
95
+ {' f' , " file" },
96
+ {' d' , " delimiter" },
97
+ {' 0' , " zero" }
91
98
};
92
99
93
100
static map<const string, const function<void (int &, const char **&)>> option_handlers = { // maps longopts to functions
@@ -98,6 +105,13 @@ static map<const string, const function<void(int&, const char**&)>> option_handl
98
105
{" file" , [](int &argc, const char ** &argv) {
99
106
readarg (argc, ++argv, " file" );
100
107
argv--;
108
+ }},
109
+ {" delimiter" , [](int &argc, const char ** &argv) {
110
+ readarg (argc, ++argv, " delim" );
111
+ argv--;
112
+ }},
113
+ {" zero" , [](int &argc, const char ** &argv) {
114
+ state[" delim" ] = " \0 " ;
101
115
}}
102
116
};
103
117
@@ -107,15 +121,19 @@ static map<const string, const function<void(myhtml_tree_node_t*)>> mode_handler
107
121
printf (" %.*s" , static_cast <int >(len), data);
108
122
return 0 ;
109
123
}, nullptr );
110
- cout << endl ;
124
+ printf ( " %c " , state[ " delim " ][ 0 ]) ;
111
125
}},
112
126
113
127
{" text" , [](myhtml_tree_node_t * node) {
114
128
string rendered = " " ;
115
129
116
130
static vector<char > collapsible = {' ' , ' \t ' , ' \n ' , ' \r ' };
131
+ static vector<unsigned long > breaking = {
132
+ MyHTML_TAG_BR,
133
+ MyHTML_TAG_P
134
+ };
117
135
118
- myhtml_tree_node_t * node_iter = node;
136
+ myhtml_tree_node_t * node_iter = node-> child ;
119
137
while (node_iter){
120
138
const char * text_c = myhtml_node_text (node_iter, nullptr );
121
139
string text = " " ;
@@ -136,14 +154,15 @@ static map<const string, const function<void(myhtml_tree_node_t*)>> mode_handler
136
154
rendered += text;
137
155
}
138
156
139
- if (node_iter->tag_id == MyHTML_TAG_BR){ // <br/>
140
- rendered += " \n " ;
141
- }
142
-
143
157
if (node_iter->child ) node_iter = node_iter->child ;
144
158
else {
145
159
while (node_iter != node && node_iter->next == nullptr ) node_iter = node_iter->parent ;
146
160
if (node_iter == node) break ;
161
+
162
+ if (vec_has (breaking, node_iter->tag_id )){ // <br/>
163
+ rendered += " \n " ;
164
+ }
165
+
147
166
node_iter = node_iter->next ;
148
167
}
149
168
}
@@ -157,10 +176,11 @@ static map<const string, const function<void(myhtml_tree_node_t*)>> mode_handler
157
176
rendered.erase (index , 1 );
158
177
}
159
178
160
- while (rendered[0 ] == ' ' ) rendered.erase (0 , 1 ); // clear whitespace before single-line content
161
- while (*(rendered.end ()-1 ) == ' ' ) rendered.erase (rendered.length ()-1 , 1 ); // clear whitespace after single-line content
179
+ while (vec_has (collapsible, rendered[0 ]) ) rendered.erase (0 , 1 ); // clear whitespace before single-line content
180
+ while (vec_has (collapsible, *(rendered.end ()-1 )) ) rendered.erase (rendered.length ()-1 , 1 ); // clear whitespace after single-line content
162
181
163
- cout << rendered << endl;
182
+ cout << rendered;
183
+ printf (" %c" , state[" delim" ][0 ]);
164
184
}},
165
185
166
186
{" attr" , [](myhtml_tree_node_t * node) {
@@ -176,8 +196,10 @@ static map<const string, const function<void(myhtml_tree_node_t*)>> mode_handler
176
196
if (attr == nullptr ) return ;
177
197
178
198
do {
179
- if (state[" modearg" ] == mycore_string_data (&attr->key ))
180
- cout << mycore_string_data (&attr->value ) << endl;
199
+ if (state[" modearg" ] == mycore_string_data (&attr->key )){
200
+ cout << mycore_string_data (&attr->value );
201
+ printf (" %c" , state[" delim" ][0 ]);
202
+ }
181
203
182
204
if (attr != token->attr_last ) attr = attr->next ;
183
205
}while (attr != token->attr_last );
0 commit comments