diff --git a/+MBeautifier/MIndenter.m b/+MBeautifier/MIndenter.m
new file mode 100644
index 0000000..dc87aa4
--- /dev/null
+++ b/+MBeautifier/MIndenter.m
@@ -0,0 +1,196 @@
+classdef MIndenter < handle
+ % Performs code indenting. Should not be used directly but only by
+ % MBeautify.
+
+ properties (Constant)
+ Delimiters = {' ', '\f', '\n', '\r', '\t', '\v', ...
+ ','};
+ KeywordsIncrease = {'function', 'classdef', 'properties', ...
+ 'methods', 'if', 'for', 'parfor', 'switch', 'try', 'while'};
+ KeywordsSandwich = {'else', 'elseif', 'case', 'otherwise', ...
+ 'catch'};
+ KeywordsDecrease = {'end', 'end;'};
+ end
+
+ properties (Access = private)
+ Configuration;
+ end
+
+ methods
+ function obj = MIndenter(configuration)
+ % Creates a new formatter using the passed configuration.
+ obj.Configuration = configuration;
+ end
+
+ function indentedSource = performIndenting(obj, source)
+ % indentation strategy:
+ % allfunctions (default) = AllFunctionIndent
+ % nestedfunctions = MixedFunctionIndent (MATLAB default)
+ % noindent = ClassicFunctionIndent
+ strategy = obj.Configuration.specialRule('Indentation_Strategy').Value;
+
+ % determine indent string
+ indentationCharacter = obj.Configuration.specialRule('IndentationCharacter').Value;
+ indentationCount = obj.Configuration.specialRule('IndentationCount').ValueAsDouble;
+ if strcmpi(indentationCharacter, 'white-space')
+ indent = ' ';
+ for i = 2:indentationCount
+ indent = [' ', indent];
+ end
+ elseif strcmpi(indentationCharacter, 'tab')
+ indent = '\t';
+ else
+ warning('MBeautifier:IllegalSetting:IndentationCharacter', 'MBeautifier: The indentation character must be set to "white-space" or "tab". MBeautifier using MATLAB defaults.');
+ indent = ' ';
+ end
+
+ % TODO
+ %makeBlankLinesEmpty = Configuration.specialRule('Indentation_TrimBlankLines').ValueAsDouble;
+
+ % currently in continuation mode (line before ended with ...)?
+ continuationMode = 0;
+ % layer of indentatino (next line)
+ layerNext = 0;
+ % this stack keeps track of the keywords
+ stack = {};
+
+ % start indenting
+ lines = splitlines(source);
+ for linect = 1:numel(lines)
+ % layer of indentation (current line)
+ layer = layerNext;
+
+ % remove existing indentation and whitespace
+ lines{linect} = strtrim(lines{linect});
+
+ % split line in words
+ words = split(lines{linect}, obj.Delimiters);
+
+ % ignore empty lines and comments
+ if (~isempty(lines{linect}) && (lines{linect}(1) ~= '%'))
+ % find keywords and adjust indent
+ for wordct = 1:numel(words)
+ % detect end of line comments
+ if (strcmp(words{wordct}, '%'))
+ break;
+ end
+
+ % look for keywords that increase indent
+ if (sum(strcmp(words{wordct}, obj.KeywordsIncrease)))
+ layerNext = layerNext + 1;
+ % push keyword onto stack
+ stack = [stack, words{wordct}];
+
+ % correction for function keywords according to
+ % configuration
+ if (strcmp(stack{end}, 'function'))
+ switch lower(strategy)
+ case 'nestedfunctions'
+ if (numel(stack) == 1)
+ % top level function
+ layerNext = layerNext - 1;
+ else
+ if (strcmp(stack{end-1}, 'function'))
+ % nested function
+ layer = layer + 1;
+ layerNext = layerNext + 1;
+ else
+ % class method
+ % do nothing
+ end
+ end
+ case 'noindent'
+ layerNext = layerNext - 1;
+ otherwise
+ end
+ end
+
+ % correction for switch
+ if (strcmp(stack{end}, 'switch'))
+ layerNext = layerNext + 1;
+ end
+ end
+
+ % look for sandwich keywords
+ if (sum(strcmp(words{wordct}, obj.KeywordsSandwich)))
+ if (wordct == 1)
+ % at the beginning, decrease only current indent
+ layer = layer - 1;
+ end
+ end
+
+ % look for end that decreases the indent
+ if (sum(strcmp(words{wordct}, obj.KeywordsDecrease)))
+ if (wordct == 1)
+ % end at the beginning decreases indent of this line
+ layer = layer - 1;
+ end
+ % inline end may alter the indent of the next line
+ layerNext = layerNext - 1;
+
+ % correction for function keywords according to
+ % configuration
+ if (strcmp(stack{end}, 'function'))
+ switch lower(strategy)
+ case 'nestedfunctions'
+ if (numel(stack) == 1)
+ % top level function
+ layerNext = layerNext + 1;
+ else
+ if (strcmp(stack{end-1}, 'function'))
+ % nested function
+ layer = layer - 1;
+ else
+ % class method
+ % do nothing
+ end
+ end
+ case 'noindent'
+ if (wordct == 1)
+ % end at the beginning decreases indent of this line
+ layer = layer + 1;
+ end
+ layerNext = layerNext + 1;
+ otherwise
+ % do nothing
+ end
+ end
+
+ % correction for switch
+ if (strcmp(stack{end}, 'switch'))
+ if (wordct == 1)
+ % end at the beginning decreases indent of this line
+ layer = layer - 1;
+ end
+ layerNext = layerNext - 1;
+ end
+
+ % pop keyword
+ stack(end) = [];
+ end
+ end
+
+ % look for continuation lines
+ if (strcmp(words{end}, '...'))
+ if (~continuationMode)
+ continuationMode = 1;
+ layerNext = layerNext + 1;
+ end
+ else
+ if (continuationMode)
+ continuationMode = 0;
+ layerNext = layerNext - 1;
+ end
+ end
+ end
+
+ % add correct indentation
+ for ict = 1:layer
+ lines{linect} = [indent, lines{linect}];
+ end
+ end
+ complete = join(lines, newline);
+ indentedSource = complete{1};
+ end
+ end
+end
diff --git a/MBeautify.m b/MBeautify.m
index 543f441..71396f0 100644
--- a/MBeautify.m
+++ b/MBeautify.m
@@ -29,6 +29,38 @@
%% Public API
methods (Static = true)
+
+ function formatFileNoEditor(file, outFile)
+ % Formats the file specified in the first argument. If the
+ % second argument is also specified, the formatted source is
+ % saved to this file. The input and the output file can be the
+ % same, in which case the format operation is carried out
+ % in-place.
+ %
+ if ~exist(file, 'file')
+ return;
+ end
+
+ text = fileread(file);
+
+ % Format the code
+ configuration = MBeautify.getConfiguration();
+ formatter = MBeautifier.MFormatter(configuration);
+ text = formatter.performFormatting(text);
+
+ % Indent the code
+ indenter = MBeautifier.MIndenter(configuration);
+ text = indenter.performIndenting(text);
+
+ if (nargin == 1)
+ outFile = file;
+ end
+
+ % write formatted text to file
+ fid = fopen(outFile, 'wt');
+ fprintf(fid, '%s', text);
+ fclose(fid);
+ end
function formatFile(file, outFile)
% Formats the file specified in the first argument. The file is opened in the Matlab Editor. If the second
diff --git a/resources/settings/MBeautyConfigurationRules.xml b/resources/settings/MBeautyConfigurationRules.xml
index 8f5bb6d..578c6e0 100644
--- a/resources/settings/MBeautyConfigurationRules.xml
+++ b/resources/settings/MBeautyConfigurationRules.xml
@@ -127,7 +127,7 @@
:
-
+
case
@@ -174,7 +174,7 @@
1
-
+
MaximalNewLines
@@ -238,7 +238,7 @@
Indentation_Strategy
- AllFunctions
+ NestedFunctions
-
\ No newline at end of file
+