diff --git a/src/@report/addData.m b/src/@report/addData.m new file mode 100644 index 0000000000000000000000000000000000000000..7559f2097581d5a423f451c72160147b7b3bc453 --- /dev/null +++ b/src/@report/addData.m @@ -0,0 +1,45 @@ +function o = addData(o, varargin) +%function o = addData(o, varargin) +% Add data to the current section of the current page in the report +% +% INPUTS +% o [report] report object +% varargin arguments to @report_table/addData +% +% OUTPUTS +% o [report] updated report object +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare 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. +% +% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>. + +assert(~isempty(o.pages) , ... + ['@report.addData: Before adding data, you must add a page, ' ... + 'section, and a table.']); +assert(~isempty(o.pages{end}.sections) , ... + ['@report.addData: Before adding data, you must add a section and ' ... + 'a table']); +assert(~isempty(o.pages{end}.sections{end}.elements), ... + '@report.addData: Before adding data, you must add a table'); +assert(isa(o.pages{end}.sections{end}.elements{end}, 'report_table'), ... + '@report.addData: you can only add data to a report_table object'); + +o.pages{end}.sections{end}.elements{end} = ... + o.pages{end}.sections{end}.elements{end}.addData(varargin{:}); +end diff --git a/src/@report_data/display.m b/src/@report_data/display.m new file mode 100644 index 0000000000000000000000000000000000000000..70978f668acdfb8791a048d6c05fb2e4bbecfcb9 --- /dev/null +++ b/src/@report_data/display.m @@ -0,0 +1,32 @@ +function display(o) +%function display(o) +% Display a Report_Series object +% +% INPUTS +% o [report_series] report_series object +% +% OUTPUTS +% none +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2013-2015 Dynare Team +% +% This file is part of Dynare. +% +% Dynare 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. +% +% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>. + +display_reporting_object(o); +end \ No newline at end of file diff --git a/src/@report_data/printData.m b/src/@report_data/printData.m new file mode 100644 index 0000000000000000000000000000000000000000..6af033a9d1b0a8db24dc9448fcb2b2a8a788fc56 --- /dev/null +++ b/src/@report_data/printData.m @@ -0,0 +1,47 @@ +function o = printData(o, fid, data, precision) +%function printData(o, fid, dser, precision) +% function to print a row of data, contained in data +% +% INPUTS +% fid [int] file id +% data [string] value to be printed +% dates [dates] dates for report_series slice +% precision [float] precision with which to print the data +% +% +% OUTPUTS +% o [report_series] report_series object +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare 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. +% +% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>. + +dataString = sprintf('%%.%df', precision); +precision = 10^precision; +data = setDataToZeroFromZeroTol(o, data); +for i=1:size(data,1) + fprintf(fid, '&'); + output = round(data(i)*precision)/precision; + if isnan(output) + fprintf(fid, '%s', o.tableNaNSymb); + else + fprintf(fid, dataString, output); + end +end +end diff --git a/src/@report_data/report_data.m b/src/@report_data/report_data.m new file mode 100644 index 0000000000000000000000000000000000000000..0edca41d0362a72dd63f57632e54b013b25dfbe7 --- /dev/null +++ b/src/@report_data/report_data.m @@ -0,0 +1,76 @@ +function o = report_data(varargin) +%function o = report_data(varargin) +% Report_Data Class Constructor +% +% INPUTS +% varargin 0 args : empty report_data object +% 1 arg : must be report_data object (return a copy of arg) +% > 1 args: option/value pairs (see structure below for +% options) +% +% OUTPUTS +% o [report_data] report_data object +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare 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. +% +% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>. + +o = struct; + +o.data = ''; + +o.tableSubSectionHeader = ''; +o.tableAlignRight = false; + +o.tableRowColor = 'white'; +o.tableRowIndent = 0; + +o.tableNaNSymb = 'NaN'; + +o.tablePrecision = ''; + +o.zeroTol = 1e-6; + +if nargin == 1 + assert(isa(varargin{1}, 'report_data'), ... + '@report_data.report_data: with one arg you must pass a report_data object'); + o = varargin{1}; + return; +elseif nargin > 1 + if round(nargin/2) ~= nargin/2 + error('@report_data.report_data: options must be supplied in name/value pairs.'); + end + + optNames = fieldnames(o); + + % overwrite default values + for pair = reshape(varargin, 2, []) + ind = find(strcmpi(optNames, pair{1})); + assert(isempty(ind) || length(ind) == 1); + if ~isempty(ind) + o.(optNames{ind}) = pair{2}; + else + error('@report_data.report_data: %s is not a recognized option.', pair{1}); + end + end +end + +% Create report_data object +o = class(o, 'report_data'); +end diff --git a/src/@report_data/subsasgn.m b/src/@report_data/subsasgn.m new file mode 100644 index 0000000000000000000000000000000000000000..eebda6ef4f8dcf8256e7c7e9ac638721d31b1640 --- /dev/null +++ b/src/@report_data/subsasgn.m @@ -0,0 +1,42 @@ +function B = subsasgn(A, S, V) +% function B = subsasgn(A, S, V) + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare 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. +% +% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>. + +B = A; +if length(S) > 1 + for i=1:(length(S)-1) + B = subsref(B, S(i)); + end + B = subsasgn(B, S(end), V); + B = subsasgn(A, S(1:(end-1)), B); + return +end + +switch S.type + case '.' + switch S.subs + case fieldnames(A) + B.(S.subs) = V; + otherwise + error(['@report_data.subsasgn: field ' S.subs 'does not exist']); + end + otherwise + error('@report_data.subsasgn: syntax error'); +end +end \ No newline at end of file diff --git a/src/@report_data/subsref.m b/src/@report_data/subsref.m new file mode 100644 index 0000000000000000000000000000000000000000..1f887da2297b43e12afaaaf2d2abecc3674bcf89 --- /dev/null +++ b/src/@report_data/subsref.m @@ -0,0 +1,46 @@ +function A = subsref(A, S) +%function A = subsref(A, S) + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare 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. +% +% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>. + +switch S(1).type + case '.' + switch S(1).subs + case fieldnames(A) + A = A.(S(1).subs); + case methods(A) + if areParensNext(S) + A = feval(S(1).subs, A, S(2).subs{:}); + S = shiftS(S,1); + else + A = feval(S(1).subs, A); + end + otherwise + error(['@report_data.subsref: unknown field or method: ' S(1).subs]); + end + case {'()', '{}'} + error(['@report_data.subsref: ' S(1).type ' indexing not supported.']); + otherwise + error('@report_data.subsref: impossible case') +end + +S = shiftS(S,1); +if length(S) >= 1 + A = subsref(A, S); +end +end diff --git a/src/@report_data/writeDataForTable.m b/src/@report_data/writeDataForTable.m new file mode 100644 index 0000000000000000000000000000000000000000..46b4074b36d8ef5ba8a8b32db5cfb8b337a6ef17 --- /dev/null +++ b/src/@report_data/writeDataForTable.m @@ -0,0 +1,119 @@ +function o = writeDataForTable(o, fid, precision) +%function o = writeDataForTable(o, fid, precision) +% Write Table Data +% +% INPUTS +% o [report_data] report_data object +% fid [int] file id +% precision [float] precision with which to print the data +% +% +% OUTPUTS +% o [report_data] report_data object +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare 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. +% +% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>. + +%% Validate options passed to function +assert(fid ~= -1); +assert(isint(precision)); + +%% Validate options provided by user +assert(ischar(o.tableSubSectionHeader), '@report_data.writeDataForTable: tableSubSectionHeader must be a string'); +if isempty(o.tableSubSectionHeader) + assert(~isempty(o.data) && iscell(o.data), ... + '@report_data.writeDataForTable: must provide data as a cell'); +end + +assert(ischar(o.tableRowColor), '@report_data.writeDataForTable: tableRowColor must be a string'); +assert(isint(o.tableRowIndent) && o.tableRowIndent >= 0, ... + '@report_data.writeDataForTable: tableRowIndent must be an integer >= 0'); +assert(islogical(o.tableAlignRight), '@report_data.writeDataForTable: tableAlignRight must be true or false'); +assert(ischar(o.tableNaNSymb), '@report_data.writeDataForTable: tableNaNSymb must be a string'); + +if ~isempty(o.tablePrecision) + assert(isint(o.tablePrecision) && o.tablePrecision >= 0, ... + '@report_data.writeDataForTable: tablePrecision must be a non-negative integer'); + precision = o.tablePrecision; +end +rounding = 10^precision; + +%% Write Output +fprintf(fid, '%% Table Data (report_data)\n'); +nrows = length(o.data{1}); +ncols = length(o.data); +for i = 1:nrows + if ~isempty(o.tableRowColor) && ~strcmpi(o.tableRowColor, 'white') + fprintf(fid, '\\rowcolor{%s}', o.tableRowColor); + else + fprintf(fid, '\\rowcolor{%s}', o.tableRowColor); + end + if ~isempty(o.tableSubSectionHeader) + fprintf(fid, '\\textbf{%s}', o.tableSubSectionHeader); + for i=1:ncols-1 + fprintf(fid, ' &'); + end + fprintf(fid, '\\\\%%\n'); + return; + end + if o.tableAlignRight + fprintf(fid, '\\multicolumn{1}{r}{'); + end + if o.tableRowIndent == 0 + fprintf(fid, '\\noindent '); + else + for j=1:o.tableRowIndent + fprintf(fid,'\\indent '); + end + end + if o.tableAlignRight + fprintf(fid, '}'); + end + for j = 1:ncols + val = o.data{j}(i); + if iscell(val) + val = val{:}; + end + if isnan(val) + val = o.tableNaNSymb; + dataString = '%s'; + elseif isnumeric(val) + dataString = sprintf('%%.%df', precision); + if val < o.zeroTol && val > -o.zeroTol + val = 0; + end + val = round(val*rounding)/rounding; + if isnan(val) + val = o.tableNaNSymb; + dataString = '%s'; + end + else + dataString = '%s'; + val = regexprep(val, '_', '\\_'); + end + fprintf(fid, dataString, val); + if j ~= ncols + fprintf(fid, ' & '); + else + fprintf(fid, '\\\\%%\n'); + end + end +end +end diff --git a/src/@report_table/addData.m b/src/@report_table/addData.m new file mode 100644 index 0000000000000000000000000000000000000000..e095799318278425cce824827d29c6e11e1a2494 --- /dev/null +++ b/src/@report_table/addData.m @@ -0,0 +1,22 @@ +function o = addData(o, varargin) +% function o = addData(o, varargin) + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare 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. +% +% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>. + +o.table_data{end+1} = report_data(varargin{:}); +end \ No newline at end of file diff --git a/src/@report_table/report_table.m b/src/@report_table/report_table.m index 023987f4e301332066b7fa625f59dacdbd1b9285..a800cf5b849bfac654de8b69ce7b56cd55afd364 100644 --- a/src/@report_table/report_table.m +++ b/src/@report_table/report_table.m @@ -12,7 +12,7 @@ function o = report_table(varargin) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2013-2017 Dynare Team +% Copyright (C) 2013-2019 Dynare Team % % This file is part of Dynare. % @@ -53,6 +53,11 @@ o.writeCSV = false; o.highlightRows = {''}; +o.preamble = {''}; +o.afterward = {''}; +o.column_names = ''; +o.table_data = {}; + if nargin == 1 assert(isa(varargin{1}, 'report_table'),['With one arg to Report_Table constructor, ' ... 'you must pass a report_table object']); @@ -89,6 +94,7 @@ end if ischar(o.title) o.title = {o.title}; end + if ischar(o.titleFormat) o.titleFormat = {o.titleFormat}; end diff --git a/src/@report_table/writeTableFile.m b/src/@report_table/writeTableFile.m index 0f1e79a5bd49b4382942e5252371ee7e3d58ff93..06f0af71397a8d954c717eac2b6ba48167264896 100644 --- a/src/@report_table/writeTableFile.m +++ b/src/@report_table/writeTableFile.m @@ -33,7 +33,8 @@ function o = writeTableFile(o, pg, sec, row, col) % along with Dynare. If not, see <http://www.gnu.org/licenses/>. ne = length(o.series); -if ne == 0 +is_data_table = ~isempty(o.table_data); +if ne == 0 && ~is_data_table warning('@report_table.write: no series to plot, returning'); return; end @@ -49,6 +50,10 @@ if fid == -1 error(['@report_table.writeTableFile: ' msg]); end +fprintf(fid, '%% Report_Table Object\n'); +fprintf(fid, '\\setlength{\\parindent}{6pt}\n'); +fprintf(fid, '\\setlength{\\tabcolsep}{4pt}\n'); + %number of left-hand columns, 1 until we allow the user to group data, % e.g.: GDP Europe % GDP France @@ -56,140 +61,166 @@ end % this example would be two lh columns, with GDP Europe spanning both nlhc = 1; -if isempty(o.range) - dates = getMaxRange(o.series); - o.range = {dates}; -else - dates = o.range{1}; -end -ndates = dates.ndat; - -fprintf(fid, '%% Report_Table Object\n'); -fprintf(fid, '\\setlength{\\parindent}{6pt}\n'); -fprintf(fid, '\\setlength{\\tabcolsep}{4pt}\n'); -fprintf(fid, '\\begin{tabular}{@{}l'); +if ~is_data_table + fprintf(fid, '\\begin{tabular}{@{}l'); + if isempty(o.range) + dates = getMaxRange(o.series); + o.range = {dates}; + else + dates = o.range{1}; + end + ndates = dates.ndat; -for i=1:ndates - fprintf(fid, 'r'); - if o.showVlines - fprintf(fid, '|'); - elseif o.vlineAfterEndOfPeriod && dates(i).time(2) == dates(i).freq - fprintf(fid, '|'); - elseif ~isempty(o.vlineAfter) - for j=1:length(o.vlineAfter) - if dates(i) == o.vlineAfter{j} - fprintf(fid, '|'); + for i=1:ndates + fprintf(fid, 'r'); + if o.showVlines + fprintf(fid, '|'); + elseif o.vlineAfterEndOfPeriod && dates(i).time(2) == dates(i).freq + fprintf(fid, '|'); + elseif ~isempty(o.vlineAfter) + for j=1:length(o.vlineAfter) + if dates(i) == o.vlineAfter{j} + fprintf(fid, '|'); + end end end end -end -datedata = dates.time; -years = unique(datedata(:, 1)); -if length(o.range) > 1 - rhscols = strings(o.range{2}); - if o.range{2}.freq == 1 - rhscols = strrep(rhscols, 'Y', ''); + datedata = dates.time; + years = unique(datedata(:, 1)); + if length(o.range) > 1 + rhscols = strings(o.range{2}); + if o.range{2}.freq == 1 + rhscols = strrep(rhscols, 'Y', ''); + end + else + rhscols = {}; end -else - rhscols = {}; -end -for i=1:length(rhscols) - fprintf(fid, 'r'); - if o.showVlines - fprintf(fid, '|'); + for i=1:length(rhscols) + fprintf(fid, 'r'); + if o.showVlines + fprintf(fid, '|'); + end end -end -nrhc = length(rhscols); -ncols = ndates+nlhc+nrhc; -fprintf(fid, '@{}}%%\n'); -for i=1:length(o.title) - if ~isempty(o.title{i}) - fprintf(fid, '\\multicolumn{%d}{c}{%s %s}\\\\\n', ... + nrhc = length(rhscols); + ncols = ndates+nlhc+nrhc; + fprintf(fid, '@{}}%%\n'); + for i=1:length(o.title) + if ~isempty(o.title{i}) + fprintf(fid, '\\multicolumn{%d}{c}{%s %s}\\\\\n', ... ncols, o.titleFormat{i}, o.title{i}); + end end -end -fprintf(fid, '\\toprule%%\n'); + fprintf(fid, '\\toprule%%\n'); -% Column Headers -thdr = num2cell(years, size(years, 1)); -if dates.freq == 1 - for i=1:size(thdr, 1) - fprintf(fid, ' & %d', thdr{i, 1}); - end - for i=1:length(rhscols) - fprintf(fid, ' & %s', rhscols{i}); - end -else - thdr{1, 2} = datedata(:, 2)'; - if size(thdr, 1) > 1 - for i=2:size(thdr, 1) - split = find(thdr{i-1, 2} == dates.freq, 1, 'first'); - assert(~isempty(split), '@report_table.writeTableFile: Shouldn''t arrive here'); - thdr{i, 2} = thdr{i-1, 2}(split+1:end); - thdr{i-1, 2} = thdr{i-1, 2}(1:split); + % Column Headers + thdr = num2cell(years, size(years, 1)); + if dates.freq == 1 + for i=1:size(thdr, 1) + fprintf(fid, ' & %d', thdr{i, 1}); end - end - for i=1:size(thdr, 1) - fprintf(fid, ' & \\multicolumn{%d}{c}{%d}', size(thdr{i,2}, 2), thdr{i,1}); - end - for i=1:length(rhscols) - fprintf(fid, ' & %s', rhscols{i}); - end - fprintf(fid, '\\\\\n'); - switch dates.freq - case 4 - sep = 'Q'; - case 12 - sep = 'M'; - case 52 - sep = 'W'; - otherwise - error('@report_table.writeTableFile: Invalid frequency.'); - end - for i=1:size(thdr, 1) - period = thdr{i, 2}; - for j=1:size(period, 2) - fprintf(fid, ' & \\multicolumn{1}{c'); - if o.showVlines - fprintf(fid, '|'); - elseif o.vlineAfterEndOfPeriod && j == size(period, 2) - fprintf(fid, '|'); - elseif ~isempty(o.vlineAfter) - for k=1:length(o.vlineAfter) - if o.vlineAfter{k}.time(1) == thdr{i} && ... - o.vlineAfter{k}.time(2) == period(j) - fprintf(fid, '|'); + for i=1:length(rhscols) + fprintf(fid, ' & %s', rhscols{i}); + end + else + thdr{1, 2} = datedata(:, 2)'; + if size(thdr, 1) > 1 + for i=2:size(thdr, 1) + split = find(thdr{i-1, 2} == dates.freq, 1, 'first'); + assert(~isempty(split), '@report_table.writeTableFile: Shouldn''t arrive here'); + thdr{i, 2} = thdr{i-1, 2}(split+1:end); + thdr{i-1, 2} = thdr{i-1, 2}(1:split); + end + end + for i=1:size(thdr, 1) + fprintf(fid, ' & \\multicolumn{%d}{c}{%d}', size(thdr{i,2}, 2), thdr{i,1}); + end + for i=1:length(rhscols) + fprintf(fid, ' & %s', rhscols{i}); + end + fprintf(fid, '\\\\\n'); + switch dates.freq + case 4 + sep = 'Q'; + case 12 + sep = 'M'; + case 52 + sep = 'W'; + otherwise + error('@report_table.writeTableFile: Invalid frequency.'); + end + for i=1:size(thdr, 1) + period = thdr{i, 2}; + for j=1:size(period, 2) + fprintf(fid, ' & \\multicolumn{1}{c'); + if o.showVlines + fprintf(fid, '|'); + elseif o.vlineAfterEndOfPeriod && j == size(period, 2) + fprintf(fid, '|'); + elseif ~isempty(o.vlineAfter) + for k=1:length(o.vlineAfter) + if o.vlineAfter{k}.time(1) == thdr{i} && ... + o.vlineAfter{k}.time(2) == period(j) + fprintf(fid, '|'); + end end end + fprintf(fid, '}{%s%d}', sep, period(j)); end - fprintf(fid, '}{%s%d}', sep, period(j)); end end +else + fprintf(fid, '\\begin{tabular}{|'); + for i = 1:length(o.column_names) + if isempty(o.column_names{i}) + fprintf(fid, 'l'); + else + fprintf(fid, 'r'); + end + fprintf(fid, '|'); + end + fprintf(fid,'}'); end -fprintf(fid, '\\\\[-2pt]%%\n'); -fprintf(fid, '\\hline%%\n'); -fprintf(fid, '%%\n'); % Write Report_Table Data -if o.writeCSV - csvseries = dseries(); -end -for i=1:ne - o.series{i}.writeSeriesForTable(fid, o.range, o.precision, ncols, o.highlightRows{mod(i,length(o.highlightRows))+1}); +if ~is_data_table + fprintf(fid, '\\\\[-2pt]%%\n'); + fprintf(fid, '\\hline%%\n'); + fprintf(fid, '%%\n'); if o.writeCSV - if isempty(o.series{i}.tableSubSectionHeader) - csvseries = [csvseries ... - o.series{i}.data(dates).set_names([... - num2str(i) '_' ... - o.series{i}.data.name{:}])]; + csvseries = dseries(); + end + for i=1:ne + o.series{i}.writeSeriesForTable(fid, o.range, o.precision, ncols, o.highlightRows{mod(i,length(o.highlightRows))+1}); + if o.writeCSV + if isempty(o.series{i}.tableSubSectionHeader) + csvseries = [csvseries ... + o.series{i}.data(dates).set_names([... + num2str(i) '_' ... + o.series{i}.data.name{:}])]; + end + end + if o.showHlines + fprintf(fid, '\\hline\n'); end end - if o.showHlines - fprintf(fid, '\\hline\n'); + if o.writeCSV + csvseries.save(strrep(o.tableName, '.tex', ''), 'csv'); end -end -if o.writeCSV - csvseries.save(strrep(o.tableName, '.tex', ''), 'csv'); +else + fprintf(fid, '%%\n'); + fprintf(fid, '\\hline%%\n'); + fprintf(fid, '%%\n'); + for i = 1:length(o.column_names) + if ~isempty(o.column_names{i}) + fprintf(fid, '%s', o.column_names{i}); + end + if i ~= length(o.column_names) + fprintf(fid, ' & '); + end + end + fprintf(fid, '\\\\[-2pt]%%\n'); + fprintf(fid, '\\hline%%\n'); + o.table_data{1}.writeDataForTable(fid, o.precision); end fprintf(fid, '\\bottomrule\n'); fprintf(fid, '\\end{tabular}\\setlength{\\parindent}{0pt}\n \\par \\medskip\n\n');