@@ -21,8 +21,12 @@ Usage: %s [options] <selector> <mode> [mode argument]
2121Options:
2222 -h, --help
2323 show this text
24- -f, --file
24+ -f, --file <file>
2525 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
2630
2731 <selector>
2832 CSS selector to match against
@@ -47,6 +51,7 @@ static map<const string, bool> flags = {
4751static map<const string, string> state = { // global state
4852 {" progname" , " hq" }, // program name
4953 {" file" , " -" }, // input file path, or - for stdin
54+ {" delim" , " \n " }, // result delimiter
5055 {" selector" , " " }, // matching selector
5156 {" mode" , " " }, // output mode
5257 {" data" , " " }, // read input data
@@ -87,7 +92,9 @@ template <typename T> inline bool vec_has(vector<T> &vec, T val){
8792
8893static map<const char , const string> option_longopts = { // maps shortopts to longopts from option_handlers
8994 {' h' , " help" },
90- {' f' , " file" }
95+ {' f' , " file" },
96+ {' d' , " delimiter" },
97+ {' 0' , " zero" }
9198};
9299
93100static 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
98105 {" file" , [](int &argc, const char ** &argv) {
99106 readarg (argc, ++argv, " file" );
100107 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 " ;
101115 }}
102116};
103117
@@ -107,15 +121,19 @@ static map<const string, const function<void(myhtml_tree_node_t*)>> mode_handler
107121 printf (" %.*s" , static_cast <int >(len), data);
108122 return 0 ;
109123 }, nullptr );
110- cout << endl ;
124+ printf ( " %c " , state[ " delim " ][ 0 ]) ;
111125 }},
112126
113127 {" text" , [](myhtml_tree_node_t * node) {
114128 string rendered = " " ;
115129
116130 static vector<char > collapsible = {' ' , ' \t ' , ' \n ' , ' \r ' };
131+ static vector<unsigned long > breaking = {
132+ MyHTML_TAG_BR,
133+ MyHTML_TAG_P
134+ };
117135
118- myhtml_tree_node_t * node_iter = node;
136+ myhtml_tree_node_t * node_iter = node-> child ;
119137 while (node_iter){
120138 const char * text_c = myhtml_node_text (node_iter, nullptr );
121139 string text = " " ;
@@ -136,14 +154,15 @@ static map<const string, const function<void(myhtml_tree_node_t*)>> mode_handler
136154 rendered += text;
137155 }
138156
139- if (node_iter->tag_id == MyHTML_TAG_BR){ // <br/>
140- rendered += " \n " ;
141- }
142-
143157 if (node_iter->child ) node_iter = node_iter->child ;
144158 else {
145159 while (node_iter != node && node_iter->next == nullptr ) node_iter = node_iter->parent ;
146160 if (node_iter == node) break ;
161+
162+ if (vec_has (breaking, node_iter->tag_id )){ // <br/>
163+ rendered += " \n " ;
164+ }
165+
147166 node_iter = node_iter->next ;
148167 }
149168 }
@@ -157,10 +176,11 @@ static map<const string, const function<void(myhtml_tree_node_t*)>> mode_handler
157176 rendered.erase (index, 1 );
158177 }
159178
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
162181
163- cout << rendered << endl;
182+ cout << rendered;
183+ printf (" %c" , state[" delim" ][0 ]);
164184 }},
165185
166186 {" attr" , [](myhtml_tree_node_t * node) {
@@ -176,8 +196,10 @@ static map<const string, const function<void(myhtml_tree_node_t*)>> mode_handler
176196 if (attr == nullptr ) return ;
177197
178198 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+ }
181203
182204 if (attr != token->attr_last ) attr = attr->next ;
183205 }while (attr != token->attr_last );
0 commit comments