macro_file align_tabs;

/***********************************************
 Align columns in tab separated data files,
 similar to 'auto-size' in Excel

 This macro does not alter the actual file in
 any way. Only the files appearance in MEW is
 changed.

 Written by James Olsen, Jan 17 20002
 james@planetolsen.com

 1.0.1 2002-09-17
       Fixed problem with the end of some files
       not getting lined up in columns. Bug was
       due to insufficient information in the 
       CMAC manual about strings. The manual says
       stings can be up to 16000 characters long,
       but fails to mention they are 255 characters
       max by default, and fails to mention how to
       override the default. I found out how by
       browsing other code and voila, now all
       tabs in a file get lined up into columns.

 **********************************************/

// Save this into a file named "align_tabs.s"
// Load this file into MEW
// Select Tools | Execute Compiler from the menu
// Choose "Compile CMACWIN" from the popup dialog


// If you want to auto-adjust tab-delimited files when you open 
// them then do the following:
// - Go to Tools | Customize | General | File Extensions
// - Then locate the file extension(s) you consider tab delimited
// - Click EDIT
// - in the "post-load macro" text box type: align_tabs
// - click Ok/Close/Ok 
// The next time you open a file with those extensions, they will
// automatically be reflowed. 

// You may instead/also map a key to this function and invoke it
// manually. 

#include mewlib32.sh

struct t_tab_array {
  int tarray[5000];
}

//void align_tabbed_data_into_columns {
void align_tabs {
	int tab_counter;
	int character_counter;
	struct t_tab_array len_array;
	int last_line;
	int iteration;
	str format_line_string[10000];
	int jol;
	int joc;
	int prior_pos_on_this_line = 0;
	int total_tabs;
				
  push_undo;						
  mark_pos;							// Remember the current cursor position
  refresh=0;						// Turn off screen updates to speed things up
	// We want to make tabs appear as a single space so we can calculate
	// the distance between each tab
	use_format_line=0;		// Turn off the formatting line
	SetTabs(1); 					// make a tab effectively the same as a space	

	// Initialize array to 0's
  for (tab_counter = 0; tab_counter < 5000; tab_counter++) { 
		len_array.tarray[tab_counter] = 0;                      
  }      
  tab_counter = 0;
	last_line = 1;
	//last_line_eof = 0;
	iteration = 0;        
	goto_col(1);
	goto_line(1);
	while ( search_fwd("@t", 0) ) {		
		if (C_LINE > last_line) {
			joc = c_col;
			jol = c_line;					 						
			up;
			eol;
			len_array.tarray[tab_counter] = (C_COL - prior_pos_on_this_line);
			goto_col(joc);
			goto_line(jol);

			last_line = C_LINE;
			tab_counter = 0;
			prior_pos_on_this_line = 0;
		}
										 
		if (len_array.tarray[tab_counter] < (C_COL - prior_pos_on_this_line)) {
			len_array.tarray[tab_counter] = (C_COL - prior_pos_on_this_line);
		}

		tab_counter++;
		prior_pos_on_this_line = C_COL;

		if (iteration++ > 5000) {
			break;
		}
		right;

	}

	total_tabs = 0;
	pad_str(format_line_string, 10000, ' '); 
  
	for (tab_counter = 0; len_array.tarray[tab_counter] > 0; tab_counter++) {
		total_tabs = total_tabs + len_array.tarray[tab_counter]+2;
    format_line_string = str_ins(char(16), format_line_string, total_tabs);
	}	

	format_line = format_line_string;
	use_format_line = 1;
	goto_mark;
	refresh=1;
	redraw;
	pop_undo;
}

