## Copyright (C) 2006 Hansgeorg Schwibbe
## Copyright (C) 2019 John Donoghue
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {} csv2latex(@var{csv_file}, @var{csv_sep}, @var{latex_file})
## @deftypefnx {} csv2latex(@var{csv_file}, @var{csv_sep}, @var{latex_file},@
##              @var{tabular_alignments})
## @deftypefnx {} csv2latex(@var{csv_file}, @var{csv_sep}, @var{latex_file},@
##              @var{tabular_alignments}, @var{has_hline})
## @deftypefnx {} csv2latex(@var{csv_file}, @var{csv_sep}, @var{latex_file},   @
##              @var{tabular_alignments}, @var{has_hline}, @var{column_titles})
## @deftypefnx {} csv2latex(@var{csv_file}, @var{csv_sep}, @var{latex_file},@
##              @var{tabular_alignments}, @var{has_hline},@
##              @var{column_titles}, @var{row_titles})
##
## Creates a latex file from a csv file. The generated latex file contains a 
## tabular with all values of the csv file. The tabular can be decorated with 
## row and column titles. The generated latex file can be inserted in any latex
## document by using the '\input@{latex file name without .tex@}' statement.
##
## csv_file - the path to an existing csv file@*
## csv_sep - the seperator of the csv values@*
## latex_file - the path of the latex file to create@*
## tabular_alignments - the tabular alignment preamble
##    (default = @{'l','l',...@})@*
## has_hline - indicates horizontal line seperator (default = false)@*
## column_titles - array with the column titles of the tabular
##    (default = @{@})@*
## row_titles - array with the row titles of the tabular (default = @{@})@*
##
## Examples:
##
## @example
## # creates the latex file 'example.tex' from the csv file 'example.csv' 
## csv2latex("example.csv", '\t', "example.tex");
##
## # creates the latex file with horizontal and vertical lines
## csv2latex('example.csv', '\t', 'example.tex', @{'|l|', 'l|'@}, true);
## 
## # creates the latex file with row and column titles
## csv2latex('example.csv', '\t', 'example.tex', @{'|l|', 'l|'@}, true, 
##            @{'Column 1', 'Column 2', 'Column 3'@}, @{'Row 1', 'Row 2'@});
## @end example
## @end deftypefn

function csv2latex (csv_file, csv_sep, latex_file, tabular_alignments, has_hline, column_titles, row_titles)

  ## set up the default values
  if nargin < 7
   row_titles = {};
  endif
  if nargin < 6
   column_titles = {};
  endif
  if nargin < 5
   has_hline = false;
  endif
  if nargin < 4
   tabular_alignments = {};
  endif

  ## load the csv file and create the csv cell
  [fid, msg] = fopen (csv_file, 'r'); # open the csv file to read
  csv = cell();
  if fid != -1
    [val, count] = fread(fid); # read all data from the file
    fclose(fid); # close the csv file after reading
    csv_value = '';
    line_index = 1;
    value_index = 1;
    for index = 1:count
      if val(index) == csv_sep
        csv(line_index, value_index) = csv_value;
        value_index++;
        csv_value = '';
      elseif (val(index) == '\n' || (val(index) == '\r' && val(index+1) == '\r'))
        csv(line_index, value_index) = csv_value;
        value_index++;
        csv_value = '';
        value_index = 1;
        line_index++;
      else
        csv_value = sprintf('%s%c', csv_value, val(index));
      endif
    endfor
  endif

  ## get the size and length values
  [row_size, col_size] = size(csv);
  alignment_size = length(tabular_alignments);
  column_title_size = length(column_titles);
  row_title_size = length(row_titles);

  ## create the alignment preamble and the column titles
  alignment_preamble = '';
  tabular_headline = '';
  if row_title_size != 0
    current_size = col_size + 1;
  else
    current_size = col_size;
  endif
  for col_index = 1:current_size
   if col_index <=  alignment_size
     alignment_preamble = sprintf ('%s%s', alignment_preamble, tabular_alignments(col_index));
   else
     alignment_preamble = sprintf ('%sl', alignment_preamble);
   endif
   if column_title_size != 0
     if col_index <= column_title_size
       if col_index == 1
         tabular_headline = sprintf ('%s', column_titles(col_index));
       else
         tabular_headline = sprintf ('%s & %s', tabular_headline, column_titles(col_index));
       endif
     else
       tabular_headline = sprintf ('%s &', tabular_headline);       
     endif
   endif
  endfor

  ## print latex file
  [fid, msg] = fopen (latex_file, 'w'); # open the latex file for writing
  if fid != -1
    fprintf (fid, '\\begin{tabular}{%s}\n', alignment_preamble); # print the begin of the tabular
    if column_title_size != 0
      if has_hline == true
        fprintf (fid, '  \\hline\n');
      endif
      fprintf (fid, '  %s \\\\\n',  tabular_headline); # print the headline of the tabular
    endif
    for row_index = 1:row_size
      if has_hline == true
        fprintf (fid, '  \\hline\n');
      endif
      for col_index = 1:col_size
        if col_index == 1
          if row_title_size != 0
            if row_index <= row_title_size
              fprintf (fid, '  %s & ', row_titles(row_index)); # print the row title
            else
              fprintf (fid, '  & '); # print an empty row title
            endif
          endif
          fprintf (fid, '  %s ', csv{row_index, col_index});
        else
         fprintf (fid, '& %s ', csv{row_index, col_index});
        endif
      endfor
      fprintf (fid, '\\\\\n');
    endfor
    if has_hline == true
      fprintf (fid, '  \\hline\n');
    endif
    fprintf (fid, '\\end{tabular}', alignment_preamble); # print the end of the tabular
    fclose(fid); # close the latex file after writing
  endif
endfunction

%!error csv2latex()
%!error csv2latex("")
%!error csv2latex("", "")

%!test
%! f1name = tempname();
%! f2name = tempname();
%! f = -1;
%! unwind_protect
%!   f = fopen(f1name, "w");
%!   fprintf(f, "A|B|C\nD|E|F\n");
%! unwind_protect_cleanup
%!   if f != -1
%!     fclose(f);
%!   endif
%! end_unwind_protect
%! csv2latex(f1name, '|', f2name);
%! a = fileread(f2name);
%! checkstr = "\\begin{tabular}{llll}";
%! assert(strncmp(a, checkstr, length(checkstr)));

