Below is a script that I wrote to clean up the style of a matlab file. It inserts whitespace around various operators and structures such as brackets. This is an essential tool for refactoring old matlab code.
function FixStyle(inFileName, replaceOldWithNew )
%% This is a collection of rules to re-style the code in an m file.
% This was developed for refactoring legacy code that I have inherited.
% inputs
% - inFileName - The file to be restyled
% - replaceOldWithNew - true/false - if true then rename the inFile to
% inFile.old.m and replace with the new file.
%
% (c) Duncan Blair 2013.
if isempty(inFileName)
error('No file name provided. Exiting...');
end
patten = '\.m';
replaceWith = '\.cleaned\.m';
outFileName = regexprep(inFileName, patten, replaceWith);
%try to open the file and read it in line by line
inFileID = fopen(inFileName,'r');
outFileID = fopen(outFileName, 'w');
try
%process the file line by line
textLine = fgets(inFileID);
while ischar(textLine)
%reformat the line
textLine = PrettyFormat(textLine);
% write it to the new file
fwrite(outFileID, textLine);
textLine = fgets(inFileID);
end %while
%process the file by block
%frewind(inFileID);
fclose(inFileID); %close the in file
fclose(outFileID);%close the out file
catch err
fclose(inFileID); %close the in file
fclose(outFileID);%close the out file
rethrow(err);
end
%change the filenames after success
if strcmp(replaceOldWithNew, 'true')
patten = '\.m';
replaceWith = '\.old\.m';
newname = regexprep(inFileName, patten, replaceWith);
movefile(inFileName, newname);
movefile(outFileName, inFileName);
end
return;
end
%% Apply the formatting rules to a line of text
function cleanLine = PrettyFormat(dirtyLine)
%if its a comment line then ignore it
[code, comment] = SplitCommentLine(dirtyLine);
if isempty(code)%early exit for comment-only lines
cleanLine = comment;
return;
end
%Relational Operators
code = Fix2CharOperator(code, '<=');
code = Fix2CharOperator(code, '>=');
code = Fix2CharOperator(code, '==');
code = Fix2CharOperator(code, '~=');
code = Fix1CharOperator(code, '>');
code = Fix1CharOperator(code, '<');
%short circut logical operators
code = Fix2CharOperator(code, '\|\|');
code = Fix2CharOperator(code, '&&');
%Element wise logical operators
code = Fix1CharOperator(code, '&');
code = Fix1CharOperator(code, '\|');
code = Fix1CharOperator(code, '~'); %may require special handling
%arithmetic operators
code = Fix1CharOperator(code, '+');
code = Fix1CharOperator(code, '-');
code = Fix1CharOperator(code, '/');
code = Fix2CharOperator(code, '\./');
code = Fix1CharOperator(code, '*');
code = Fix2CharOperator(code, '\.\*');
code = Fix1CharOperator(code, '\\');
code = Fix2CharOperator(code, '\.\\');
code = Fix1CharOperator(code, '\^');
code = Fix2CharOperator(code, '\.\^');
%cl = Fix1CharOperator(cl, '\'''); %messes up string literals
%cl = Fix2CharOperator(cl, '.\'''); %messes up string literals
%assignment operator
code = Fix1CharOperator(code, '\=');
%initialise an array
code = Fix2CharOperator(code, '\[\]');
%Brackets
% []
code = FixBrackets(code, '\[', '\]');
%{}
code = FixBrackets(code, '\{', '\}');
%()
code = FixBrackets(code, '\(', '\)');
%Special characters
% ! @ ; : ' ... .. . .()
%string literals
code = FixInvertedCommaPairs(code);
code = FixComma(code);
%Fix any leading whitespace before semi-colons
%these may have been introduced by earlier operations
code = FixSemiColon(code);
%append any trailing comment
cleanLine = [code comment];
end
%% Rules for String Literals
function cleanLine = FixInvertedCommaPairs( dirtyLine )
% Add whitespace before string literal
patten = '(\S)(\''[^\'']*\'') ';
replaceWith = '$1 $2';
cleanLine = regexprep(dirtyLine, patten, replaceWith);
% Add whitespace after string literal
patten = '(\s\''[^\'']*\'')(\S)';
replaceWith = '$1 $2';
cleanLine = regexprep(cleanLine, patten, replaceWith);
end
%% Rules for commas
function cleanLine = FixComma( dirtyLine )
%put a trailing space after commas
patten = '(\,)(\S)';
replaceWith = '$1 $2';
cleanLine = regexprep(dirtyLine, patten, replaceWith);
%remove leading white spaces before comma
patten = '\s*(\,)';
replaceWith = '$1';
cleanLine = regexprep(cleanLine, patten, replaceWith);
end
%% Rules for Semi-Colons
function cleanLine = FixSemiColon( dirtyLine )
%put a trailing space after semi-colon
patten = '(\;)(\S)';
replaceWith = '$1 $2';
cleanLine = regexprep(dirtyLine, patten, replaceWith);
%remove leading whitespaces before semi-colon
patten = '\s*(\;)';
replaceWith = '$1';
cleanLine = regexprep(cleanLine, patten, replaceWith);
end
%% Rules for single character operators
function cleanLine = Fix1CharOperator( dirtyLine, op )
%add both whitespace
patten = ['([^' op '\s])(' op ')([^' op '\s)'];
replaceWith = '$1 $2 $3';
cleanLine = regexprep(dirtyLine, patten, replaceWith);
%add leading whitespace
patten = ['([^' op '\s\.<>~])(' op '{1})'];
replaceWith = '$1 $2';
cleanLine = regexprep(cleanLine, patten, replaceWith);
%add trailing whitespace
patten = ['(' op '{1})([^' op '\s\=\*\^/\.])'];
replaceWith = '$1 $2';
cleanLine = regexprep(cleanLine, patten, replaceWith);
end
%% Rules for two-character operators
function cleanLine = Fix2CharOperator( dirtyLine, op )
%add both whitespace
patten = ['(\S)(' op ')(\S)'];
replaceWith = '$1 $2 $3';
cleanLine = regexprep(dirtyLine, patten, replaceWith);
%add leading whitespace
patten = ['(\S)(' op ')'];
replaceWith = '$1 $2';
cleanLine = regexprep(cleanLine, patten, replaceWith);
%add trailing whitespace
patten = ['(\s)(' op ')(\S)'];
replaceWith = '$1$2 $3';
cleanLine = regexprep(cleanLine, patten, replaceWith);
end
%% Rules for brackets
function cleanLine = FixBrackets( dirtyLine, leftBracket, rightBracket )
% no whitespace after left
patten = ['(' leftBracket ')(?=\S)'];
replaceWith = '$1 ';
cleanLine = regexprep(dirtyLine, patten, replaceWith);
% no whitespace before right
patten = ['(\S)(?=' rightBracket ')'];
replaceWith = '$1 ';
cleanLine = regexprep(cleanLine, patten, replaceWith);
end
%% Divide lines into code and trailing comments
function [code, comment] = SplitCommentLine(line)
k = strfind(line, '%');
if isempty(k)
code = line;
comment = '';
else
startOfComment = k(1);
code = line(1:startOfComment - 1);
comment = line(startOfComment:end);
end;
end
DuncansTools Notes
Updates and notes on various software packages I maintain
Friday, June 7, 2013
Matlab Fix Style tool to fix formating of code
Thursday, April 11, 2013
GailsTools Bugfix
I have fixed a small bug that was causing the add-in to crash on load.
The old code was from some web tutorial and was trapping for errors rather than pre-testing for conditions.
Sub RemoveMenubar()
On Error Resume Next
Application.CommandBars(ToolBarName).Delete
On Error GoTo 0
End Sub
The new code is below.
Sub RemoveMenubar()
For Each cbar In CommandBars
If cbar.Name = ToolBarName Then
cbar.Delete
End If
Next
End Sub
GailsTools is now at v5.3.
The old code was from some web tutorial and was trapping for errors rather than pre-testing for conditions.
Sub RemoveMenubar()
On Error Resume Next
Application.CommandBars(ToolBarName).Delete
On Error GoTo 0
End Sub
The new code is below.
Sub RemoveMenubar()
For Each cbar In CommandBars
If cbar.Name = ToolBarName Then
cbar.Delete
End If
Next
End Sub
GailsTools is now at v5.3.
Friday, September 16, 2011
Visual Studio Custom Build Rules File for HelpNDoc version 3
This custom build rules file allows compilation of a HelpNDoc help project file. This allows inclusion of the resulting ouput files within your VS setup and deployment projects.
I find this very handy to ensure I have the most current version of the help file included in the setup project without having to manually go and build the help file before building the setup files. Prevents those moments where you wonder if you had pressed compile after that late night tweaks in the documentation...
This custom build rules file is for Visual Studio 2008 and HelpNDoc3. It supports the command line switches for all the options including the template system. It's only slightly different from the version for HelpNDoc 2.
HelpNDoc3 Build Rule for VS2008.zip
This custom build rules file allows compilation of a HelpNDoc help project file. This allows inclusion of the resulting ouput files within your VS setup and deployment projects.
I find this very handy to ensure I have the most current version of the help file included in the setup project without having to manually go and build the help file before building the setup files. Prevents those moments where you wonder if you had pressed compile after that late night tweaks in the documentation...
This custom build rules file is for Visual Studio 2008 and HelpNDoc3. It supports the command line switches for all the options including the template system. It's only slightly different from the version for HelpNDoc 2.
HelpNDoc3 Build Rule for VS2008.zip
Wednesday, September 7, 2011
Export script for Treadmill data from 3ds max to PointLightLab model file (Left Viewport Version)
This script exports a 28 point model from 3ds MAX to a PointLightLab model file format ( 2D version for V4 of PLL)
This script exports a 28 point model from 3ds MAX to a PointLightLab model file format ( 2D version for V4 of PLL)
macroScript TM_LeftFacing_Exporter category:"DuncansTools" ( -- number of points to export num_dummies = 28 -- array to hold the dummy refs dummy_array = #() --scaling factor scale = 0.3 output_name = getSaveFileName caption:"PointLightLab Model File" types:"Models (*.pllm)|*.pllm|All Files (*.*)|*.*|" if output_name != undefined then ( output_file = createfile output_name --create the array of dummies for dummies = 1 to num_dummies do ( dummy_array[dummies] = execute ((if dummies < 10 then ("$Dummy0" ) else ("$Dummy")) + dummies as string) ) --Write the file header-- format "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?>\n" to:output_file format "<!DOCTYPE DuncansModelFile SYSTEM \"C:\\Program Files\\DuncansTools\\PointLightLab\\configuration\\ModelFormatv4.dtd\">\n" to:output_file format "<DuncansModelFile Version=\"4.0\">\n\n" to:output_file for t = animationrange.start to animationrange.end do ( format "<FrameSet>\n" to:output_file for dummies = 1 to num_dummies do ( at time t obj_1 = dummy_array[dummies].center format "<FramePoint Xpos=\"" to:output_file format "%" (obj_1.y * scale ) to:output_file format "\" Ypos=\"" to:output_file format "%" (obj_1.z * scale ) to:output_file format "\"/>\n" to:output_file ) format "</FrameSet>\n\n" to:output_file ) format "\n</DuncansModelFile>" to:output_file close output_file edit output_name )--end if )--end macroScript
Monday, September 5, 2011
Import script for getting Treadmill Mocap data into 3ds MAX
Maxscript importer for .t3d files generated from PhaseSpace motion capture system using the a full suit and cap with 28 LED's. The .t3d files are generated from C3DWorkbench as simple tab delimited text files with X Y Z data on each line. The number of points needs to be known before hand and set in the "num_dummies" var. I was importing 5 second blocks of motion at 30 frames a second, hence the hard wired number of frames in "num_frames" var.
This script generates an array of dummy objects to hold the motion data as a point cloud style data set. Each point's data is mapped as a keyframe on the dummy except where the point has dropped out or "popped" (if you use EEG nomenclature....) These are filtered out during the import to make it easier to fix the data in the curve editor. Be careful of frame 0, as it does not seem to filter correctly. (Will figure this out later)
Maxscript importer for .t3d files generated from PhaseSpace motion capture system using the a full suit and cap with 28 LED's. The .t3d files are generated from C3DWorkbench as simple tab delimited text files with X Y Z data on each line. The number of points needs to be known before hand and set in the "num_dummies" var. I was importing 5 second blocks of motion at 30 frames a second, hence the hard wired number of frames in "num_frames" var.
This script generates an array of dummy objects to hold the motion data as a point cloud style data set. Each point's data is mapped as a keyframe on the dummy except where the point has dropped out or "popped" (if you use EEG nomenclature....) These are filtered out during the import to make it easier to fix the data in the curve editor. Be careful of frame 0, as it does not seem to filter correctly. (Will figure this out later)
macroscript TM_Importer category: "DuncansTools" ( num_dummies = 28 num_frames = 151 dummy_array = #() animationRange = interval 0 num_frames --create the array of dummies for d = 1 to num_dummies do ( dummy_array[d] = dummy () dummy_array[d].boxsize = [1,1,1] ) --local x = dummy_array[1].pos.controller --showProperties x --get the text file ( tab delimeted works. from excel ) in_name = getOpenFileName types:"Text 3d (*.t3d|*.t3d|All (*.*)|*.*|" if in_name != undefined then ( in_file = openFile in_name if in_file != undefined then ( -- turn on animation so we can automatically create keys with animate on ( for frames = 0 to num_frames - 1 do ( for dummies = 1 to num_dummies do ( -- read the pairs of values from the file x_val = readValue in_file y_val = readValue in_file z_val = readValue in_file -- put the values to the dummies as motion keys if x_val < 0.5 or x_val > 0.5 then ( at time frames dummy_array[dummies].pos.controller.x_position = x_val ) if y_val < 0.5 or y_val > 0.5 then ( at time frames dummy_array[dummies].pos.controller.y_position = y_val ) if z_val < 0.5 or z_val > 0.5 then ( at time frames dummy_array[dummies].pos.controller.z_position = z_val ) ) ) ) ) close in_file ) )
Labels:
3ds MAX,
Code Snippit,
maxscript,
PhaseSpace,
Treadmill data
C3D Workbench
Version 1.2
* Removed "Open File" button and merged the functionality with the "Browse" button.
* Moved the "File Parameters" functionality to a seperate dialog. Witha access via a button from the main UI called "Show File Parameter
Info".
* Re-arranged the Main UI layout.
* Added more data mapping options in the view tools (XYZ,XZY,YZX,YXZ,ZYX,ZXY). These also map correctly during export if selected.
* Added "Center to View" button and functionality. TODO. This needs to calculate scale as part of the operation.
* Fixed bug in the rendering code that was not correctly positioning the view.
* Added Export to a simple raw tab delimited 3D file format (.t3d) which is for import into 3ds max via an import script.
Version 1.2
* Removed "Open File" button and merged the functionality with the "Browse" button.
* Moved the "File Parameters" functionality to a seperate dialog. Witha access via a button from the main UI called "Show File Parameter
Info".
* Re-arranged the Main UI layout.
* Added more data mapping options in the view tools (XYZ,XZY,YZX,YXZ,ZYX,ZXY). These also map correctly during export if selected.
* Added "Center to View" button and functionality. TODO. This needs to calculate scale as part of the operation.
* Fixed bug in the rendering code that was not correctly positioning the view.
* Added Export to a simple raw tab delimited 3D file format (.t3d) which is for import into 3ds max via an import script.
Subscribe to:
Posts (Atom)