fork(1) download
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <regex>
  4. #include <string>
  5. #include <vector>
  6.  
  7. namespace boris {
  8.  
  9. namespace JSONPrettify_specifics{
  10. enum class Colons{
  11. TIGHT,
  12. SPACED
  13. };
  14. enum class Position{
  15. TAB = 0,
  16. COMMA = 1,
  17. OBJ_START = 2,
  18. OBJ_END = 3,
  19. ARRAY_START = 4,
  20. ARRAY_END = 5
  21. };
  22. struct RegexPos{
  23. size_t pos;
  24. long length;
  25. };
  26.  
  27. std::string generateSpaces( int l ){
  28. return std::string(l*4, ' ');
  29. }
  30. long lowestOf( std::vector<size_t> of ){
  31. std::vector<size_t>::iterator result = std::min_element(std::begin(of), std::end(of));
  32. return std::distance(std::begin(of), result);
  33. }
  34.  
  35. void insertColonSpaces( std::string & j ){
  36. std::regex colon = std::regex(R"(\s*?\:\s*?(?=\S))");
  37. j.assign(std::regex_replace(j, colon, " : "));
  38. }
  39. RegexPos findRegexFirstPosition( const std::string & json, const long start_pos, const std::regex rx ){
  40. size_t at = -1;
  41. long l = 0;
  42.  
  43. std::string ss( json.begin()+start_pos, json.end() );
  44. std::smatch m;
  45.  
  46. std::regex_search( ss, m, rx );
  47.  
  48. if ( m.size() > 0 ) {
  49. at = m.position(0);
  50. l = m[0].str().size();
  51. }
  52. if( at < json.size() ) at += start_pos;
  53. return {at,l};
  54. }
  55. }
  56.  
  57. std::string JSONPrettify( const std::string & json, boris::JSONPrettify_specifics::Colons spacing=boris::JSONPrettify_specifics::Colons::TIGHT ){
  58.  
  59. using namespace boris::JSONPrettify_specifics;
  60.  
  61. std::string pretty = json;
  62. const std::regex var = std::regex(R"((\".+?\".*?(?=\{|\[|\,|\]|\}))|(\d+?))");
  63.  
  64. long it = 0;
  65. int depth = 0;
  66.  
  67. while( it < pretty.size() ){
  68.  
  69. RegexPos pos_tab = findRegexFirstPosition( pretty,it, var );
  70. auto pos_comma = pretty.find( ",", it );
  71. auto pos_obj_start = pretty.find( "{", it );
  72. auto pos_obj_end = pretty.find( "}", it );
  73. auto pos_array_start = pretty.find( "[", it );
  74. auto pos_array_end = pretty.find( "]", it );
  75.  
  76. long old_it = it;
  77.  
  78. Position work_with;
  79.  
  80. {
  81. std::vector<size_t> _temp = { pos_tab.pos, pos_comma, pos_obj_start, pos_obj_end,pos_array_start,pos_array_end };
  82.  
  83. auto at = lowestOf(_temp);
  84.  
  85.  
  86. if(_temp[at] > pretty.size()) break;
  87.  
  88.  
  89. work_with = static_cast<Position>(at);
  90. }
  91.  
  92. switch( work_with ){
  93.  
  94. case(Position::TAB):{
  95. std::string insert = generateSpaces(depth);
  96.  
  97. pretty.insert( pos_tab.pos, insert );
  98.  
  99. it = pos_tab.pos+insert.size()+pos_tab.length;
  100. break;
  101. }
  102.  
  103. case(Position::COMMA):{
  104. std::string insert = "\n";
  105.  
  106. pretty.insert( pos_comma+1, insert );
  107.  
  108. it = pos_comma+1;
  109. break;
  110. }
  111.  
  112. case(Position::OBJ_START):{
  113. std::string insert = "\n";
  114. pretty.insert( pos_obj_start+1, insert );
  115.  
  116. it = pos_obj_start+insert.size();
  117.  
  118. depth+=1;
  119.  
  120. if(pos_obj_start-1 > pretty.size()) continue;
  121.  
  122. if(pretty.at(pos_obj_start-1) != ':'){
  123. std::string extra = generateSpaces( depth-1 );
  124. pretty.insert( pos_obj_start, extra );
  125. it+=extra.size();
  126. }
  127.  
  128. break;
  129. }
  130.  
  131. case(Position::OBJ_END):{
  132. std::string insert = "\n"+generateSpaces( depth-1 );
  133. pretty.insert( pos_obj_end, insert );
  134.  
  135. it = pos_obj_end+insert.size()+1;
  136.  
  137. depth-=1;
  138. break;
  139. }
  140.  
  141. case(Position::ARRAY_START):{
  142. std::string insert = "\n";
  143. pretty.insert( pos_array_start+1,insert );
  144. it=pos_array_start+insert.size();
  145.  
  146. depth+=1;
  147. break;
  148. }
  149.  
  150. case(Position::ARRAY_END):{
  151. std::string insert = "\n"+generateSpaces( depth-1 );
  152. pretty.insert( pos_array_end,insert );
  153. it=pos_array_end+insert.size()+1;
  154.  
  155. depth-=1;
  156. break;
  157. }
  158.  
  159. default:{
  160. break;
  161. }
  162. };
  163.  
  164. if(it == old_it)
  165. break;
  166. }
  167.  
  168. if(spacing == Colons::TIGHT)
  169. insertColonSpaces(pretty);
  170.  
  171. return pretty;
  172. }
  173. };
  174.  
  175. int main() {
  176. std::cout << boris::JSONPrettify("abc") ;
  177. }
Success #stdin #stdout 0s 3548KB
stdin
Standard input is empty
stdout
abc