diff --git a/+af_tools/+utils/lednicer.m b/+af_tools/+utils/lednicer.m
new file mode 100644
index 0000000000000000000000000000000000000000..8eecbf5d7a8bea31d23c2a64cdc7f3ed544b20e0
--- /dev/null
+++ b/+af_tools/+utils/lednicer.m
@@ -0,0 +1,20 @@
+function [coord, array] = lednicer(upper, lower)
+    % Lednicer Output airofil coordinates in the Lednicer format
+    % -----
+    % (c) Copyright 2022 University of Liege
+    % Author: Thomas Lambert <t.lambert@uliege.be>
+    % ULiege - Aeroelasticity and Experimental Aerodynamics
+    % Apache 2.0 License
+    % https://gitlab.uliege.be/am-dept/matlab_airfoil_toolbox
+
+    % ----------------------------------------------------------------------------------------------
+
+    coord = [upper; lower];
+
+    nPts = size(upper, 1);
+    array = num2str([nPts, nPts; coord], '%0.7f  ');
+    sep = blanks(size(array, 2));
+
+    array = [array(1:size(upper, 1), :); sep; array(size(upper, 1) + 1:end, :)];
+
+end
diff --git a/+af_tools/+utils/selig.m b/+af_tools/+utils/selig.m
new file mode 100644
index 0000000000000000000000000000000000000000..f776cbf20ee85a20ff34284116268da00b53f510
--- /dev/null
+++ b/+af_tools/+utils/selig.m
@@ -0,0 +1,15 @@
+function [coord, array] = selig(upper, lower)
+    % SELIG Output airofil coordinates in the Selig format
+    % -----
+    % (c) Copyright 2022 University of Liege
+    % Author: Thomas Lambert <t.lambert@uliege.be>
+    % ULiege - Aeroelasticity and Experimental Aerodynamics
+    % Apache 2.0 License
+    % https://gitlab.uliege.be/am-dept/matlab_airfoil_toolbox
+
+    % ----------------------------------------------------------------------------------------------
+
+    coord = [flipud(upper); lower(2:end, :)];
+    array = num2str(coord, '%0.7f  ');
+
+end
diff --git a/+af_tools/formatairfoilcoord.m b/+af_tools/formatairfoilcoord.m
new file mode 100644
index 0000000000000000000000000000000000000000..8bd986fb4b1cba1f7706feeb4baa26873d3ff7dc
--- /dev/null
+++ b/+af_tools/formatairfoilcoord.m
@@ -0,0 +1,255 @@
+function Dat = formatairfoilcoord(varargin)
+    % FORMATAIRFOILCOORD Re-format airfoil coordinates.
+    %   The UIUC airfoil database from the University of Illinois gathers the coordinates for more
+    %   than 1600 airfoils. Two different standards are used to represent the coordinates of the
+    %   airfoil:
+    %       - Selig: The first line is the name of the airfoil, and each line after that is a set of
+    %                coordinates. The coordinates are ordered from the trailing edge, along the
+    %                upper surface to the leading edge and back around the lower surface to trailing
+    %                edge. This format is the most common one.
+    %       - Lednicer: The first line is the name of the airfoil, the second one is the number of
+    %                   points on each side and the lines after that are the coordinates. The
+    %                   coordinates are given separately for the upper and lower surfaces, each from
+    %                   the leading edge to the trailing edge.
+    %
+    %   Many engineering tools or application (such as XFOIL) rely on inputs in the Selig format
+    %   only. This script was therefore created to reformat original data so they can be used easily
+    %   with other tools.
+    %
+    %   Even though the _Selig_ format is the default option, the script allows also the user to
+    %   reformat _Selig_ files in _Lednicer_ form if needed. It also comes with the option to refine
+    %   the coordinates by adding points with a spline interpolation following the half-cosine rule
+    %   (more points are the leading and trailing edge). If that option is selected, the airfoil
+    %   will be defined using 50 points for each surface.
+    %
+    % Note:
+    %   This function can be used on many files at once in order to speed-up the process.
+    %
+    % <a href="https://gitlab.uliege.be/thlamb/airfoil_toolbox">Documentation (README)</a>
+    % <a href="https://gitlab.uliege.be/thlamb/airfoil_toolbox/-/issues">Report an issue</a>
+    % -----
+    %
+    % Usage:
+    %   DAT = FORMATAIRFOILCOORD prompts the user for all inputs, then converts the coordinates to
+    %   the Selig format.
+    %
+    %   DAT = FORMATAIRFOILCOORD(INPUTDIR) converts all dat files found in INPUTDIR.
+    %
+    %   DAT = FORMATAIRFOILCOORD(INPUTDIR, INPUTFILES) converts only the polars specified by
+    %   INPUTFILES found in INPUTDIR.
+    %
+    %   DAT = FORMATAIRFOILCOORD(..., 'autosave', true) saves the resulting coordinates in a new
+    %   dat-file.
+    %
+    %   DAT = FORMATAIRFOILCOORD(..., 'overwrite', true) saves the resulting coordinates by
+    %   overwriting the original dat-file. If autosave is not specified but overwrite is true, the
+    %   file will be overwritten anyway. If autosave is set to false and overwrite is true, the file
+    %   will not be saved at all.
+    %
+    %   DAT = FORMATAIRFOILCOORD(..., 'refine', true) refines the input data by using a spline
+    %   interpolation with 100 coordinates in total, spaced following the half-cosine rule.
+    %   False by default.
+    %
+    %   DAT = FORMATAIRFOILCOORD(..., 'outputFormat', 'Lednicer') select the output format (Selig or
+    %   Lednicer). Selig by default.
+    %
+    % Inputs:
+    %   inputDir   : Path of the directory with the UIUC oridinal dat-files
+    %   inputFiles : Files to select (ex: '*' (default), '*0012*', {'file1','file2'}, etc)
+    %
+    % Output:
+    %   Dat : A structure for the results for each input file.
+    %         - Dat.file : original filename
+    %         - Dat.format : Format of the output coordinates
+    %         - Dat.airfoil : airfoil name, parsed from the input file
+    %         - Dat.nPoints : Number of coordinates
+    %         - Dat.coord : whole airfoil coordinates, with 0 <= X <= 1
+    %         - Dat.upper : airfoil upper surface coordinates.
+    %         - Dat.lower : airfoil lower surface coordinates.
+    %
+    % Example:
+    %   FORMATAIRFOILCOORD
+    %   FORMATAIRFOILCOORD('test_data')
+    %   FORMATAIRFOILCOORD('test_data', '*0012*')
+    %   FORMATAIRFOILCOORD('test_data', {'0012_re1e5', '0012_re1e6'})
+    %   FORMATAIRFOILCOORD('test_data', 'autosave', true)
+    %   FORMATAIRFOILCOORD('test_data', 'overwrite', true)
+    %   FORMATAIRFOILCOORD('test_data', 'refine', true)
+    %   FORMATAIRFOILCOORD('test_data', 'outputFormat', 'Lednicer')
+    %
+    % See also: NACAAIRFOIL.
+    %
+    % -----
+    % UIUC Airfoil Database: https://m-selig.ae.illinois.edu/ads/coord_database.html
+    % -----
+    % (c) Copyright 2022 University of Liege
+    % Author: Thomas Lambert <t.lambert@uliege.be>
+    % ULiege - Aeroelasticity and Experimental Aerodynamics
+    % Apache 2.0 License
+    % https://gitlab.uliege.be/am-dept/matlab_airfoil_toolbox
+
+    % ----------------------------------------------------------------------------------------------
+
+    narginchk(0, 8);
+
+    % Import other functions from this package
+    import af_tools.utils.*
+
+    % Constants and defaults
+    OPTION_LIST = {'autosave', 'overwrite', 'refine', 'outputFormat'};
+    FILETYPE = '.dat';
+    REFINED_SPACING = 'halfcosine';
+    REFINED_NPOINTS = ceil((100 + 1) / 2);
+
+    % Parse inputs
+    [allFileNames, fullpath, idxOpts] = parsefileinputs(OPTION_LIST, FILETYPE, varargin{:});
+    [autosave, overwrite, refine, outputFormat] = parseoptioninputs(varargin{idxOpts:end});
+
+    % Convert filenames to string array
+    allFileNames = string(allFileNames);
+
+    % -------------------------------------------
+    % Convert all files
+
+    % Number of files found
+    nbFiles = length(allFileNames);
+
+    % Initialize structures
+    Dat = struct('file', [], 'airfoil', [], 'format', [], 'nPoints', [], 'coord', [], ...
+                 'upper', [], 'lower', []);
+
+    for i = 1:nbFiles
+
+        % Load file and start parsing
+        % No matter the file type, line 1 should always be the airfoil name
+        fileID = fopen(fullfile(fullpath, allFileNames{i}));
+        tmpAirfoil = textscan(fileID, '%s', 1, 'Delimiter', '\n:', 'HeaderLines', 0);
+        tmpCoord = cell2mat(textscan(fileID, '%f %f %*[^\n]', 'HeaderLines', 0));
+        fclose(fileID);
+        clear fileID;
+
+        % Split airfoil into its upper and lower surfaces
+        [Dat(i).upper, Dat(i).lower] = splitsurfaces(tmpCoord);
+
+        % Refines coordinates by adding points if needed
+        [Dat(i).upper, Dat(i).lower] = refinesurfaces(Dat(i).upper, Dat(i).lower, refine, ...
+                                                      REFINED_SPACING, REFINED_NPOINTS);
+
+        % Fromats according to desired output
+        switch outputFormat
+            case 'Selig'
+                [Dat(i).coord, Dat(i).array] = selig(Dat(i).upper, Dat(i).lower);
+            case 'Lednicer'
+                [Dat(i).coord, Dat(i).array] = lednicer(Dat(i).upper, Dat(i).lower);
+        end
+
+        % Output structure
+        Dat(i).path = fullpath;
+        Dat(i).file = allFileNames{i};
+        Dat(i).airfoil = char(cellstr(tmpAirfoil{:}));
+        Dat(i).format = outputFormat;
+
+    end
+
+    % -------------------------------------------
+    % Save results automatically
+
+    if autosave
+
+        for i = 1:length(Dat)
+
+            filename = split(Dat(i).file, '.dat');
+            if ~overwrite
+                filename = [filename{1}, '-', outputFormat];
+            end
+            filename = appendextension(filename, '.dat');
+            filename = fullfile(Dat(i).path, filename);
+            header = Dat(i).airfoil;
+            savetodat(filename, header, Dat(i).array);
+        end
+    end
+
+    % Cleanup
+    Dat = rmfield(Dat, 'array');
+
+end
+
+% --------------------------------------------------------------------------------------------------
+function [autosave, overwrite, refine, outputFormat] = parseoptioninputs(varargin)
+    % PARSEOPTIONINPUTS Parses the options and checks their validity
+
+    import af_tools.utils.*
+
+    % Constants and defaults
+    DEFAULT_AUTOSAVE = false;
+    DEFAULT_OVEWRITE = false;
+    DEFAULT_REFINE = false;
+    DEFAULT_FORMAT = 'Selig';
+    ALLOWED_FORMATS = {'Selig', 'Lednicer'};
+
+    % Option validator
+    validLogical = @(x) validateattributes(x, {'logical'}, {'scalar'}, mfilename());
+    validFormat = @(x) any(validatestring(x, ALLOWED_FORMATS, mfilename()));
+
+    % Parse options
+    p = inputParser;
+    addParameter(p, 'autosave', DEFAULT_AUTOSAVE, validLogical);
+    addParameter(p, 'overwrite', DEFAULT_OVEWRITE, validLogical);
+    addParameter(p, 'refine', DEFAULT_REFINE, validLogical);
+    addParameter(p, 'outputFormat', DEFAULT_FORMAT, validFormat);
+
+    parse(p, varargin{:});
+    autosave = p.Results.autosave;
+    overwrite = p.Results.overwrite;
+    refine = p.Results.refine;
+    outputFormat = p.Results.outputFormat;
+
+end
+
+function [upper, lower] = splitsurfaces(data)
+    % SPLITSURFACES Splits the whole airfoil into its upper and lower surfaces
+
+    % Determine format
+    if data(1, 1) > 1
+        inputFormat = 'Lednicer';
+    elseif data(1, 1) == 1
+        inputFormat = 'Selig';
+    else
+        error('MATLAB:formatairfoilcoord:unknownInputFormat', ...
+              ['The second line of the data file must either be 1 (Selig format) or '...
+               'an integer larger than 1 (Lednicer).']);
+    end
+
+    % Split lower and upper surfaces
+    switch inputFormat
+        case 'Selig'
+            idx = find(diff(data(:, 1)) < 0, 1, 'last');
+            upper = data(1:idx + 1, :);
+            upper = flipud(upper);
+            lower = data(idx + 1:end, :);
+        case 'Lednicer'
+            nCoord = data(1, 1);
+            upper = data(2:nCoord + 1, :);
+            lower = data(nCoord + 2:end, :);
+    end
+
+end
+
+function [newUpper, newLower] = refinesurfaces(upper, lower, refine, spacing, nPoints)
+    % REFINESURFACES Refines the upper and lower surfaces by adding more points
+
+    import af_tools.utils.spacedvector
+
+    if refine && size(upper, 1) < nPoints
+        xc = fliplr(spacedvector(spacing, nPoints))';
+
+        newUpper(:, 1) = xc;
+        newLower(:, 1) = xc;
+        newUpper(:, 2) = interp1(upper(:, 1), upper(:, 2), xc, 'spline');
+        newLower(:, 2) = interp1(lower(:, 1), lower(:, 2), xc, 'spline');
+    else
+        newUpper = upper;
+        newLower = lower;
+    end
+
+end
diff --git a/+af_tools/uiuccleaner.m b/+af_tools/uiuccleaner.m
deleted file mode 100644
index 804b0de5c9b7817a8e4d5f80e3c2024d9d2962a0..0000000000000000000000000000000000000000
--- a/+af_tools/uiuccleaner.m
+++ /dev/null
@@ -1,196 +0,0 @@
-function Dat = uiuccleaner(varargin)
-    % UIUCCLEANER Cleans airfoil data from UIUC Airfoil Database.
-    %   The UIUC airfoil database from the University of Illinois gathers the coordinates for more
-    %   than 1600 airfoils. However, there is a few discrepancies between the format and ordering of
-    %   these coordinates. This script alleviates that by re-formatting any input file from the
-    %   original database.
-    %
-    % Format:
-    %   The output format of this script follows the "labeled coordinates" file, used originally by
-    %   Selig on the UIUC Airfoil Database.
-    %   The first line contains the name of the airfoil, and each line after that is a set of
-    %   coordinates. The coordinates are ordered from the trailing edge, along the upper surface to
-    %   the leading edge and back around the lower surface to trailing edge.
-    %
-    % Note:
-    %   This function can be used on many files at once in order to speed-up the process.
-    %
-    % <a href="https://gitlab.uliege.be/thlamb/airfoil_toolbox">Documentation (README)</a>
-    % <a href="https://gitlab.uliege.be/thlamb/airfoil_toolbox/-/issues">Report an issue</a>
-    % -----
-    %
-    % Usage:
-    %   DAT = UIUCCLEANER prompts the user for all inputs, then converts the coordinates to the
-    %   correct standard.
-    %
-    %   DAT = UIUCCLEANER(INPUTDIR) converts all dat files found in INPUTDIR.
-    %
-    %   DAT = UIUCCLEANER(INPUTDIR, INPUTFILES) converts only the polars specified by INPUTFILES
-    %   found in INPUTDIR.
-    %
-    %   DAT = UIUCCLEANER(..., 'autosave', true) saves the resulting coordinates in a new dat-file.
-    %
-    %   DAT = UIUCCLEANER(..., 'overwrite', true) saves the resulting coordinates by overwriting the
-    %   original dat-file. If autosave is not specified but overwrite is true, the file will be
-    %   overwritten anyway. If autosave is set to false and overwrite is true, the file will not be
-    %   saved at all.
-    %
-    %   DAT = UIUCCLEANER(..., 'refine', true) refines the input data by using a spline
-    %   interpolation with 100 coordinates in total, spaced following the half-cosine rule.
-    %   False by default.
-    %
-    % Inputs:
-    %   inputDir   : Path of the directory with the UIUC oridinal dat-files
-    %   inputFiles : Files to select (ex: '*' (default), '*0012*', {'file1','file2'}, etc)
-    %
-    % Output:
-    %   Dat : A structure for the results for each input file.
-    %         - Dat.file : original filename
-    %         - Dat.airfoil : airfoil name, parsed from the input file
-    %         - Dat.x : airfoil X coordinates, with 0 <= X <= 1
-    %         - Dat.y : airfoil Y coordinates.
-    %
-    % Example:
-    %   UIUCCLEANER
-    %   UIUCCLEANER('test_data')
-    %   UIUCCLEANER('test_data', '*0012*')
-    %   UIUCCLEANER('test_data', {'0012_re1e5', '0012_re1e6'})
-    %   UIUCCLEANER('test_data', 'autosave', true)
-    %   UIUCCLEANER('test_data', 'overwrite', true)
-    %   UIUCCLEANER('test_data', 'refine', true)
-    %
-    % See also: NACAAIRFOIL.
-    %
-    % -----
-    % UIUC Airfoil Database: https://m-selig.ae.illinois.edu/ads/coord_database.html
-    % -----
-    % (c) Copyright 2022 University of Liege
-    % Author: Thomas Lambert <t.lambert@uliege.be>
-    % ULiege - Aeroelasticity and Experimental Aerodynamics
-    % Apache 2.0 License
-    % https://gitlab.uliege.be/am-dept/matlab_airfoil_toolbox
-
-    % ----------------------------------------------------------------------------------------------
-
-    narginchk(0, 8);
-
-    % Import other functions from this package
-    import af_tools.utils.*
-
-    % Constants and defaults
-    OPTION_LIST = {'autosave', 'overwrite', 'refine'};
-    FILETYPE = '.dat';
-    REFINED_SPACING = 'halfcosine';
-    REFINED_NPOINTS = ceil((100 + 1) / 2);
-
-    % Parse inputs
-    [allFileNames, fullpath, idxOpts] = parsefileinputs(OPTION_LIST, FILETYPE, varargin{:});
-    [autosave, overwrite, refine] = parseoptioninputs(varargin{idxOpts:end});
-
-    % Convert filenames to string array
-    allFileNames = string(allFileNames);
-
-    % -------------------------------------------
-    % Convert all files
-
-    % Number of files found
-    nbFiles = length(allFileNames);
-
-    % Initialize structures
-    Dat = struct('file', [], 'airfoil', [], 'x', [], 'y', []);
-
-    for i = 1:nbFiles
-
-        % Load file and start parsing
-        % No matter the file type, line 1 should always be the airfoil name
-        fileID = fopen(fullfile(fullpath, allFileNames{i}));
-        tmpAirfoil = textscan(fileID, '%s', 1, 'Delimiter', '\n:', 'HeaderLines', 0);
-        resultArray = cell2mat(textscan(fileID, '%f %f %*[^\n]', 'HeaderLines', 0));
-        fclose(fileID);
-        clear fileID;
-
-        % Re-order file if it is needed
-        if resultArray(1, 1) ~= 0 && resultArray(1, 1) ~= 1 && resultArray(2, 1) == 0
-            % Remove first line
-            resultArray = resultArray(2:end, :);
-
-            % Find index at the end of the upper side (normally diff would be -1,
-            % but we use -0.5 in case the LE and TE are not precisely at 0 and 1. It
-            % should be the only negative diff anyway).
-            idx = find(diff(resultArray) < -0.5, 1);
-            upper = flipud(resultArray(1:idx, :));
-            lower = resultArray(idx + 1:end, :);
-            resultArray = [upper; lower(2:end, :)];
-        end
-
-        % Refine coordinates to add more points
-        if refine && size(resultArray, 1) < 2 * REFINED_NPOINTS
-            xc = fliplr(spacedvector(REFINED_SPACING, REFINED_NPOINTS))';
-
-            idx = find(diff(resultArray(:, 1)) < 0, 1, 'last');
-            upper = resultArray(1:idx + 1, :);
-            lower = resultArray(idx + 1:end, :);
-
-            refinedUpperY = interp1(upper(:, 1), upper(:, 2), xc, 'spline');
-            refinedLowerY = interp1(lower(:, 1), lower(:, 2), flipud(xc), 'spline');
-
-            x = [xc; flipud(xc(1:end - 1))];
-            y = [refinedUpperY; refinedLowerY(2:end)];
-            resultArray = [x, y];
-        end
-
-        % Output structure
-        Dat(i).path = fullpath;
-        Dat(i).file = allFileNames{i};
-        Dat(i).airfoil = char(cellstr(tmpAirfoil{:}));
-        Dat(i).x = resultArray(:, 1);
-        Dat(i).y = resultArray(:, 2);
-
-    end
-
-    % -------------------------------------------
-    % Save results automatically
-
-    if autosave
-
-        for i = 1:length(Dat)
-
-            filename = split(Dat(i).file, '.dat');
-            if ~overwrite
-                filename = [filename{1}, '-CLEAN'];
-            end
-            filename = appendextension(filename, '.dat');
-            filename = fullfile(Dat(i).path, filename);
-            header = Dat(i).airfoil;
-            savetodat(filename, header, Dat(i).x, Dat(i).y);
-
-        end
-    end
-
-end
-
-% --------------------------------------------------------------------------------------------------
-function [autosave, overwrite, refine] = parseoptioninputs(varargin)
-    % PARSEOPTIONINPUTS Parses the options and checks their validity
-
-    import af_tools.utils.*
-
-    % Constants and defaults
-    DEFAULT_AUTOSAVE = false;
-    DEFAULT_OVEWRITE = false;
-    DEFAULT_REFINE = false;
-
-    % Option validator
-    validLogical = @(x) validateattributes(x, {'logical'}, {'scalar'}, mfilename());
-
-    % Parse options
-    p = inputParser;
-    addParameter(p, 'autosave', DEFAULT_AUTOSAVE, validLogical);
-    addParameter(p, 'overwrite', DEFAULT_OVEWRITE, validLogical);
-    addParameter(p, 'refine', DEFAULT_REFINE, validLogical);
-    parse(p, varargin{:});
-    autosave = p.Results.autosave;
-    overwrite = p.Results.overwrite;
-    refine = p.Results.refine;
-
-end
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 69e56b86eed4ef903afab4f7874b737d87f4aaa8..ff3f266b97403c5479a83bc4d4179f56496981b1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Changed
 
+- **BREAKING**: Renamed **uiuccleaner** in **formatairfoilcoord**
+- Feat: Add possibility to select output style for **formatairfoilcoord**
+- Feat: Add Selig and Lednicer utils for airfoil formatting
 - Style: Adopt style from MISS_HIT
 - Copyright notice: change main copyright holder to the University
 - Doc: Revamp `CONTRIBUTING.md` to put emphasis on MISS_HIT and conventions
diff --git a/README.md b/README.md
index 0915c8cc4f9ef5c2b523846f6ef69319131b3489..7e181b15db0024bd1ecfa1852a6ab017b988e497 100644
--- a/README.md
+++ b/README.md
@@ -84,8 +84,8 @@ af_tools.xf2mat(args)
 List of functions:
 
 - [xf2mat](#xf2mat): Aggregates multiple XFOIL or XFLR5 polar results into a single structure.
-- [uiuccleaner](#uiuccleaner): Re-formats airfoil coordinates obtained from UIUC
-  Airfoil database.
+- [formatairfoilcoord](#formatairfoilcoord): Re-format airfoil coordinates
+  datafile.
 - [Airfoil generation](#airfoil-generation)
   - [nacacamber](#nacacamber): Generates the coordinates of the camberline for a NACA 4 or 5 digits airfoil.
   - [nacaairfoil](#nacaairfoil): Generates the full coordinates of a NACA 4 or 5 digits airfoil.
@@ -136,20 +136,34 @@ angles of attack and N is the number of input files.
 | `cd`         | Drag coefficient                                 | [M x N] |
 | `cm`         | Moment coefficient                               | [M x N] |
 
-### uiuccleaner
-
-The [UIUC airfoil database][uiuc-af-db] from the University of Illinois gathers the
-coordinates for more than 1600 airfoils. However, there is a few
-discrepancies between the format and ordering of these coordinates. This
-scripts alleviates that by re-formatting any input file from the original
-database. The main use of this function is to make the coordinates files
-compliant with other existing tools, such as [XFOIL][xfoil].
-
-The output format of this script follows the "labeled coordinates" file, used
-originally by Selig on the UIUC Airfoil Database. The first line contains the
-name of the airfoil, and each line after that is a set of coordinates. The
-coordinates are ordered from the trailing edge, along the upper surface to the
-leading edge and back around the lower surface to trailing edge.
+### formatairfoilcoord
+
+The [UIUC airfoil database][uiuc-af-db] from the University of Illinois gathers
+the coordinates for more than 1600 airfoils. Two different standards are used
+to represent the coordinates of the airfoil:
+
+- _Selig_: The first line is the name of the airfoil, and each line after that
+  is a set of coordinates. The coordinates are ordered from the trailing edge,
+  along the upper surface to the leading edge and back around the lower surface
+  to trailing edge (_e.g._, see
+  [E205](https://m-selig.ae.illinois.edu/ads/coord/e205.dat)). This format is
+  the most common one.
+- _Lednicer_: The first line is the name of the airfoil, the second one is the
+  number of points on each side and the lines after that are the coordinates.
+  The coordinates are given separately for the upper and lower surfaces, each
+  from the leading edge to the trailing edge (_e.g._, see [Clark
+  Y](https://m-selig.ae.illinois.edu/ads/coord/clarky.dat)).
+
+Many engineering tools or application (such as [XFOIL][xfoil]) rely on inputs in
+the _Selig_ format only. This script was therefore created to reformat original
+data so they can be used easily with other tools.
+
+Even though the _Selig_ format is the default option, the script allows also the
+user to reformat _Selig_ files in _Lednicer_ form if needed. It also comes with
+the option to refine the coordinates by adding points with a spline
+interpolation following the half-cosine rule (more points are the leading and
+trailing edge). If that option is selected, the airfoil will be defined using 50
+points for each surface.
 
 ```matlab
 import af_tools.xf2mat
@@ -158,14 +172,15 @@ Polar = uiuccleaner(inputDir, inputFiles, 'autosave', true)
 Polar = uiuccleaner(inputDir, inputFiles, 'overwrite', true)
 ```
 
-| Input        | Example                                        | Default |
-|------------- | ---------------------------------------------- | --------|
-| `inputDir`   | `'.'`, `'xf_results'`                          | -       |
-| `inputFiles` | `'*'`, `'*0012*'`, `'{'*0012_1*', '*0012_2*'}` | `'*'`   |
-|              |                                                |         |
-| 'autosave'   | `false`, `true`                                | `false` |
-| 'overwrite'  | `false`, `true`                                | `false` |
-| 'refine'     | `false`, `true`                                | `false` |
+| Input          | Example                                        | Default |
+|--------------- | ---------------------------------------------- | --------|
+| `inputDir`     | `'.'`, `'xf_results'`                          | -       |
+| `inputFiles`   | `'*'`, `'*0012*'`, `'{'*0012_1*', '*0012_2*'}` | `'*'`   |
+|                |                                                |         |
+| 'autosave'     | `false`, `true`                                | `false` |
+| 'overwrite'    | `false`, `true`                                | `false` |
+| 'refine'       | `false`, `true`                                | `false` |
+| 'outputFormat' | `Selig`, `Lednicer`                            | `Selig` |
 
 ### Airfoil generation
 
diff --git a/tests/test_formatairfoilcoord.m b/tests/test_formatairfoilcoord.m
new file mode 100644
index 0000000000000000000000000000000000000000..d1660f5034479c87f7288cddbb573b5f1e763f53
--- /dev/null
+++ b/tests/test_formatairfoilcoord.m
@@ -0,0 +1,222 @@
+% TEST_FORMATAIRFOILCOORD Unitary tests for the formatairfoilcoord function
+% Note:
+%   Matlab package functionality is not very test-framework friendly.
+%   Either the whole package has to be imported in EVERY SINGLE TEST or the
+%   functions must be called as <package>.function() everytime.
+%   The second option is preferred for the tests as it has the smaller scope.
+%
+% -----
+% (c) Copyright 2022 University of Liege
+% Author: Thomas Lambert <t.lambert@uliege.be>
+% ULiege - Aeroelasticity and Experimental Aerodynamics
+% Apache 2.0 License
+% https://gitlab.uliege.be/am-dept/matlab_airfoil_toolbox
+
+% --------------------------------------------------------------------------------------------------
+
+%% Main test function
+
+function tests = test_formatairfoilcoord
+
+    tests = functiontests(localfunctions);
+
+end
+
+%% Setup and teardown
+
+function setupOnce(testCase)
+
+    addpath('../.'); % Add repository to Matlab Path
+    addpath('./test_utils'); % Add utils to Matlab Path
+
+    % Set random number generator settings.
+    testCase.TestData.currentRNG = rng;
+
+end
+
+function teardownOnce(testCase)
+
+    rmpath('../.'); % Remove repository from Matlab Path
+    rmpath('./test_utils'); % Remove utils from Matlab Path
+
+    % Restore the random number generator settings.
+    s = testCase.TestData.currentRNG;
+    rng(s);
+
+end
+
+function teardown(~)
+
+    close all; % Close all figures that would have been openend
+
+end
+
+%% Arguments and errors tests
+
+function test_nargin(testCase)
+    % Error if too many arguments
+
+    dummy = (1:10)';
+
+    verifyError(testCase, ...
+                @() af_tools.formatairfoilcoord(dummy, dummy, dummy, ...
+                                                'autosave', true, 'overwrite', false, 'refine', true), ...
+                'MATLAB:narginchk:tooManyInputs');
+
+end
+
+function test_invalidInputsType(testCase)
+    % Error if base inputs are of the wrong type
+
+    empty = [];
+    scal = 0;
+    logi = true;
+    Struct = struct;
+
+    % 1. inputDir (char vector or string)
+    verifyError(testCase, @() af_tools.formatairfoilcoord(empty), 'MATLAB:parsefileinputs:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(scal), 'MATLAB:parsefileinputs:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(logi), 'MATLAB:parsefileinputs:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(Struct), 'MATLAB:parsefileinputs:invalidType');
+
+    % 2. inputFile (char, string, cell of chars)
+    verifyError(testCase, @() af_tools.formatairfoilcoord(scal, empty), 'MATLAB:parsefileinputs:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(scal, scal), 'MATLAB:parsefileinputs:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(scal, logi), 'MATLAB:parsefileinputs:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(scal, Struct), 'MATLAB:parsefileinputs:invalidType');
+
+end
+
+function test_invalidOptions(testCase)
+    % Error if invalid option name or missing parameter value
+
+    wrongName = 'wrongOption';
+    testdir = [pwd, '/test_utils'];
+
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, '*', wrongName), ...
+                'MATLAB:InputParser:ParamMissingValue');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, '*', wrongName, true), ...
+                'MATLAB:InputParser:UnmatchedParameter');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'autosave', true, wrongName), ...
+                'MATLAB:InputParser:ParamMissingValue');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'autosave', true, wrongName, true), ...
+                'MATLAB:InputParser:UnmatchedParameter');
+
+end
+
+function test_invalidOptionsVal(testCase)
+    % Error if valid option name but invalid value
+
+    empty = [];
+    scal = 0;
+    char = 'test';
+    Struct = struct;
+    vect = 1:10;
+
+    testdir = [pwd, '/test_utils'];
+
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'autosave', empty), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'autosave', scal), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'autosave', char), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'autosave', Struct), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'autosave', vect), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'overwrite', empty), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'overwrite', scal), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'overwrite', char), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'overwrite', Struct), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'overwrite', vect), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'refine', empty), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'refine', scal), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'refine', char), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'refine', Struct), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'refine', vect), ...
+                'MATLAB:formatairfoilcoord:invalidType');
+
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'outputFormat', empty), ...
+                'MATLAB:formatairfoilcoord:unrecognizedStringChoice');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'outputFormat', scal), ...
+                'MATLAB:formatairfoilcoord:unrecognizedStringChoice');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'outputFormat', char), ...
+                'MATLAB:formatairfoilcoord:unrecognizedStringChoice');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'outputFormat', Struct), ...
+                'MATLAB:formatairfoilcoord:unrecognizedStringChoice');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'outputFormat', vect), ...
+                'MATLAB:formatairfoilcoord:unrecognizedStringChoice');
+
+end
+
+% -------------------------------------
+function test_dirNotFound(testCase)
+    % Error if valid inputDir not found
+
+    verifyError(testCase, @() af_tools.formatairfoilcoord('missingdir'), 'MATLAB:parsefileinputs:dirNotFound');
+
+end
+
+function test_fileNotFound(testCase)
+    % Error if valid inputDir not found
+
+    testdir = [pwd, '/test_utils'];
+
+    verifyWarning(testCase, @() af_tools.formatairfoilcoord(testdir, {'clarky.dat', 'testdummy.dat'}), ...
+                  'MATLAB:parsefileinputs:FileNotFound');
+    % remove warning first warning about FileNotFound before it throws the error
+    warning('off', 'MATLAB:parsefileinputs:FileNotFound');
+    verifyError(testCase, @() af_tools.formatairfoilcoord(testdir, 'randomFile'), ...
+                'MATLAB:parsefileinputs:noFilesFound');
+    warning on; % Reactivate warnings
+
+end
+
+%% Test if function returns expected outputs
+
+function test_correctOrder(testCase)
+    % Verify if the output starts and ends at X = 1;
+
+    testdir = [pwd, '/test_utils'];
+
+    Dat = af_tools.formatairfoilcoord(testdir, '*');
+
+    verifyEqual(testCase, Dat(1).coord(1, 1), 1);
+    verifyEqual(testCase, Dat(1).coord(end, 1), 1);
+    verifyEqual(testCase, Dat(2).coord(1, 1), 1);
+    verifyEqual(testCase, Dat(2).coord(end, 1), 1);
+
+end
+
+function test_correctRefinePoints(testCase)
+    % Verify if the output of refined solution has 101 points
+
+    testdir = [pwd, '/test_utils'];
+    nPoints = 101;
+
+    DatNoRefine = af_tools.formatairfoilcoord(testdir, '*');
+    Dat = af_tools.formatairfoilcoord(testdir, '*', 'refine', true);
+
+    for i = 1:length(Dat)
+        if length(DatNoRefine(i).coord(:, 1)) > nPoints
+            verifyEqual(testCase, Dat(i).coord(:, 1), DatNoRefine(i).coord(:, 1));
+            verifyEqual(testCase, Dat(i).coord(:, 2), DatNoRefine(i).coord(:, 2));
+        else
+            verifyEqual(testCase, length(Dat(i).coord(:, 1)), nPoints);
+            verifyEqual(testCase, length(Dat(i).coord(:, 2)), nPoints);
+        end
+    end
+
+end
diff --git a/tests/test_uiuccleaner.m b/tests/test_uiuccleaner.m
deleted file mode 100644
index 83b0534c4b54ccac915efd2b545051357392d673..0000000000000000000000000000000000000000
--- a/tests/test_uiuccleaner.m
+++ /dev/null
@@ -1,195 +0,0 @@
-% TEST_UIUCCLEANER Unitary tests for the uiuccleaner function
-% Note:
-%   Matlab package functionality is not very test-framework friendly.
-%   Either the whole package has to be imported in EVERY SINGLE TEST or the
-%   functions must be called as <package>.function() everytime.
-%   The second option is preferred for the tests as it has the smaller scope.
-%
-% -----
-% (c) Copyright 2022 University of Liege
-% Author: Thomas Lambert <t.lambert@uliege.be>
-% ULiege - Aeroelasticity and Experimental Aerodynamics
-% Apache 2.0 License
-% https://gitlab.uliege.be/am-dept/matlab_airfoil_toolbox
-
-% --------------------------------------------------------------------------------------------------
-
-%% Main test function
-
-function tests = test_uiuccleaner
-
-    tests = functiontests(localfunctions);
-
-end
-
-%% Setup and teardown
-
-function setupOnce(testCase)
-
-    addpath('../.'); % Add repository to Matlab Path
-    addpath('./test_utils'); % Add utils to Matlab Path
-
-    % Set random number generator settings.
-    testCase.TestData.currentRNG = rng;
-
-end
-
-function teardownOnce(testCase)
-
-    rmpath('../.'); % Remove repository from Matlab Path
-    rmpath('./test_utils'); % Remove utils from Matlab Path
-
-    % Restore the random number generator settings.
-    s = testCase.TestData.currentRNG;
-    rng(s);
-
-end
-
-function teardown(~)
-
-    close all; % Close all figures that would have been openend
-
-end
-
-%% Arguments and errors tests
-
-function test_nargin(testCase)
-    % Error if too many arguments
-
-    dummy = (1:10)';
-
-    verifyError(testCase, ...
-                @() af_tools.uiuccleaner(dummy, dummy, dummy, ...
-                                         'autosave', true, 'overwrite', false, 'refine', true), ...
-                'MATLAB:narginchk:tooManyInputs');
-
-end
-
-function test_invalidInputsType(testCase)
-    % Error if base inputs are of the wrong type
-
-    empty = [];
-    scal = 0;
-    logi = true;
-    Struct = struct;
-
-    % 1. inputDir (char vector or string)
-    verifyError(testCase, @() af_tools.uiuccleaner(empty), 'MATLAB:parsefileinputs:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(scal), 'MATLAB:parsefileinputs:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(logi), 'MATLAB:parsefileinputs:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(Struct), 'MATLAB:parsefileinputs:invalidType');
-
-    % 2. inputFile (char, string, cell of chars)
-    verifyError(testCase, @() af_tools.uiuccleaner(scal, empty), 'MATLAB:parsefileinputs:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(scal, scal), 'MATLAB:parsefileinputs:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(scal, logi), 'MATLAB:parsefileinputs:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(scal, Struct), 'MATLAB:parsefileinputs:invalidType');
-
-end
-
-function test_invalidOptions(testCase)
-    % Error if invalid option name or missing parameter value
-
-    wrongName = 'wrongOption';
-    testdir = [pwd, '/test_utils'];
-
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, '*', wrongName), ...
-                'MATLAB:InputParser:ParamMissingValue');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, '*', wrongName, true), ...
-                'MATLAB:InputParser:UnmatchedParameter');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'autosave', true, wrongName), ...
-                'MATLAB:InputParser:ParamMissingValue');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'autosave', true, wrongName, true), ...
-                'MATLAB:InputParser:UnmatchedParameter');
-
-end
-
-function test_invalidOptionsVal(testCase)
-    % Error if valid option name but invalid value
-
-    empty = [];
-    scal = 0;
-    char = 'test';
-    Struct = struct;
-    vect = 1:10;
-
-    testdir = [pwd, '/test_utils'];
-
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'autosave', empty), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'autosave', scal), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'autosave', char), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'autosave', Struct), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'autosave', vect), 'MATLAB:uiuccleaner:invalidType');
-
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'overwrite', empty), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'overwrite', scal), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'overwrite', char), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'overwrite', Struct), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'overwrite', vect), 'MATLAB:uiuccleaner:invalidType');
-
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'refine', empty), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'refine', scal), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'refine', char), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'refine', Struct), 'MATLAB:uiuccleaner:invalidType');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'refine', vect), 'MATLAB:uiuccleaner:invalidType');
-
-end
-
-% -------------------------------------
-function test_dirNotFound(testCase)
-    % Error if valid inputDir not found
-
-    verifyError(testCase, @() af_tools.uiuccleaner('missingdir'), 'MATLAB:parsefileinputs:dirNotFound');
-
-end
-
-function test_fileNotFound(testCase)
-    % Error if valid inputDir not found
-
-    testdir = [pwd, '/test_utils'];
-
-    verifyWarning(testCase, @() af_tools.uiuccleaner(testdir, {'clarky.dat', 'testdummy.dat'}), ...
-                  'MATLAB:parsefileinputs:FileNotFound');
-    % remove warning first warning about FileNotFound before it throws the error
-    warning('off', 'MATLAB:parsefileinputs:FileNotFound');
-    verifyError(testCase, @() af_tools.uiuccleaner(testdir, 'randomFile'), 'MATLAB:parsefileinputs:noFilesFound');
-    warning on; % Reactivate warnings
-
-end
-
-%% Test if function returns expected outputs
-
-function test_correctOrder(testCase)
-    % Verify if the output starts and ends at X = 1;
-
-    testdir = [pwd, '/test_utils'];
-
-    Dat = af_tools.uiuccleaner(testdir, '*');
-
-    verifyEqual(testCase, Dat(1).x(1), 1);
-    verifyEqual(testCase, Dat(1).x(end), 1);
-    verifyEqual(testCase, Dat(2).x(end), 1);
-    verifyEqual(testCase, Dat(2).x(end), 1);
-
-end
-
-function test_correctRefinePoints(testCase)
-    % Verify if the output of refined solution has 101 points
-
-    testdir = [pwd, '/test_utils'];
-    nPoints = 101;
-
-    DatNoRefine = af_tools.uiuccleaner(testdir, '*');
-    Dat = af_tools.uiuccleaner(testdir, '*', 'refine', true);
-
-    for i = 1:length(Dat)
-        if length(DatNoRefine(i).x) > nPoints
-            verifyEqual(testCase, Dat(i).x, DatNoRefine(i).x);
-            verifyEqual(testCase, Dat(i).y, DatNoRefine(i).y);
-        else
-            verifyEqual(testCase, length(Dat(i).x), nPoints);
-            verifyEqual(testCase, length(Dat(i).y), nPoints);
-        end
-    end
-
-end