diff --git a/doc/dynare.texi b/doc/dynare.texi index d866f3af4eb80204534ee015493407cc4544374c..366bf810dd0a6c7d853797eb9f5c31a49d7aa36d 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -10665,10 +10665,10 @@ Computes yearly differences or growth rates. Dynare provides a simple interface for creating @LaTeX{} reports, comprised of @LaTeX{} tables and @code{PGFPLOTS/TikZ/PGF} graphs. You can use the report as created through Dynare or pick out the pieces -you want for inclusion in your own paper. Though Dynare provides a -subset of options available through @code{PGFPLOTS}, you can easily -modify the graphs created by Dynare using the options available in the -@code{PGFPLOTS} manual. +(tables and graphs) you want for inclusion in your own paper. Though +Dynare provides a subset of options available through @code{PGFPLOTS}, +you can easily modify the graphs created by Dynare using the options +available in the @code{PGFPLOTS} manual. Reports are created and modified by calling methods on class objects. The objects are hierarchical, with the following order (from @@ -10794,11 +10794,12 @@ The @code{dseries} that provides the data for the graph. Default: @code{none} @item figname, @code{STRING} -The name to use when saving this figure. Default: something of the form @code{pg1_sec2_row1_col3.tex} +The name to use when saving this figure. Default: something of the +form @code{graph_pg1_sec2_row1_col3.tex} @item figDirName, @code{STRING} The name of the folder in which to store this figure. Default: -@code{tmpFigDir} +@code{tmpRepDir} @item graphSize, @code{NUMERICAL_VECTOR} The width and height to be passed to the third and fourth elements of @@ -10903,7 +10904,7 @@ Display a solid black line at @math{y = 0}. Default: @code{false} @end table @end defmethod -@defmethod Report addTable data, showHlines, precision, range, seriesToUse, title, titleFormat, vlineAfter, vlineAfterEndOfPeriod, showVlines +@defmethod Report addTable data, showHlines, precision, range, seriesToUse, tablename, tableDirName, title, titleFormat, vlineAfter, vlineAfterEndOfPeriod, showVlines Adds a @code{Table} to a @code{Section}. @optionshead @table @code @@ -10923,6 +10924,14 @@ The date range of the data to be displayed. Default: @code{all} @item seriesToUse, @code{CELL_ARRAY_STRINGS} @xref{seriesToUse}. +@item tablename, @code{STRING} +The name to use when saving this table. Default: something of the +form @code{table_pg1_sec2_row1_col3.tex} + +@item figDirName, @code{STRING} +The name of the folder in which to store this table. Default: +@code{tmpRepDir} + @item title, @code{STRING} Same as @ref{title}, just for tables. diff --git a/matlab/reports/@graph/graph.m b/matlab/reports/@graph/graph.m index 46d03ee2bc9fb6d6695afe2480ce30584c76f6cc..8b650bab1f7ab1b7ce0f14153e32511225641c0f 100644 --- a/matlab/reports/@graph/graph.m +++ b/matlab/reports/@graph/graph.m @@ -40,7 +40,7 @@ o.titleFormat = ''; o.ylabel = ''; o.xlabel = ''; -o.figDirName = 'tmpFigDir'; +o.figDirName = 'tmpRepDir'; o.figname = ''; o.data = ''; o.seriesToUse = ''; diff --git a/matlab/reports/@graph/writeGraphFile.m b/matlab/reports/@graph/writeGraphFile.m index 6d8931d2bf09aa3da32aef9a23d8d16202b723df..a78600fc59bd65112a6cdd94184582f7fdf4ef75 100644 --- a/matlab/reports/@graph/writeGraphFile.m +++ b/matlab/reports/@graph/writeGraphFile.m @@ -39,7 +39,7 @@ if ne < 1 end if isempty(o.figname) - o.figname = sprintf('%s/pg%d_sec%d_row%d_col%d.tex', o.figDirName, pg, sec, row, col); + o.figname = sprintf('%s/graph_pg%d_sec%d_row%d_col%d.tex', o.figDirName, pg, sec, row, col); else o.figname = [o.figDirName '/' o.figname]; end diff --git a/matlab/reports/@report_table/report_table.m b/matlab/reports/@report_table/report_table.m index 79e77cdc5336617f943bb026188bc914ea91b318..6679ec0331ffca68507339a1b4c21e68752d968c 100644 --- a/matlab/reports/@report_table/report_table.m +++ b/matlab/reports/@report_table/report_table.m @@ -31,6 +31,9 @@ function o = report_table(varargin) o = struct; +o.tableDirName = 'tmpRepDir'; +o.tablename = ''; + o.series = {}; o.title = {''}; @@ -110,6 +113,8 @@ assert(iscellstr(o.title), ... '@report_table.report_table: title must be a cell array of string(s)'); assert(iscellstr(o.titleFormat), ... '@report_table.report_table: titleFormat must be a cell array of string(s)'); +assert(ischar(o.tablename), '@report_table.report_table: tablename must be a string'); +assert(ischar(o.tableDirName), '@report_table.report_table: tableDirName must be a string'); % using o.seriesToUse, create series objects and put them in o.series if ~isempty(o.data) diff --git a/matlab/reports/@report_table/write.m b/matlab/reports/@report_table/write.m index b5292369d68a7b17f9205990c0e9d4d8dfe6e908..6e1fda6db3782153dab11797ac769de80e68719b 100644 --- a/matlab/reports/@report_table/write.m +++ b/matlab/reports/@report_table/write.m @@ -1,13 +1,17 @@ function o = write(o, fid, pg, sec, row, col) %function o = write(o, fid, pg, sec, row, col) -% Write a Report_Table object +% Write a Table object % % INPUTS -% o [report_table] report_table object -% fid [integer] file id +% o [table] table object +% fid [integer] file id +% pg [integer] this page number +% sec [integer] this section number +% row [integer] this row number +% col [integer] this col number % % OUTPUTS -% o [report_table] report_table object +% o [table] table object % % SPECIAL REQUIREMENTS % none @@ -30,135 +34,6 @@ function o = write(o, fid, pg, sec, row, col) % along with Dynare. If not, see <http://www.gnu.org/licenses/>. assert(fid ~= -1); -ne = length(o.series); -if ne == 0 - warning('@report_table.write: no series to plot, returning'); - return; -end - -%number of left-hand columns, 1 until we allow the user to group data, -% e.g.: GDP Europe -% GDP France -% GDP Germany -% this example would be two lh columns, with GDP Europe spanning both -nlhc = 1; - -if isempty(o.range) - dates = getMaxRange(o.series); -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'); - -for i=1:ndates - if o.showVlines - fprintf(fid, 'r|'); - else - fprintf(fid, 'r'); - if o.vlineAfterEndOfPeriod - if dates(i).time(2) == dates(i).freq - fprintf(fid, '|'); - end - end - if ~isempty(o.vlineAfter) - for j=1:length(o.vlineAfter) - if dates(i) == o.vlineAfter{j} - if ~(o.vlineAfterEndOfPeriod && dates(i).time(2) == dates(i).freq) - fprintf(fid, '|'); - end - 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', ''); - end -else - rhscols = {}; -end -for i=1:length(rhscols) - fprintf(fid, 'r'); - if o.showVlines - fprintf(fid, '|'); - 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', ... - ncols, o.titleFormat{i}, o.title{i}); - end -end -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.write: 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, '\\\\\\cline{%d-%d}%%\n', nlhc+1, ncols); - switch dates.freq - case 4 - sep = 'Q'; - case 12 - sep = 'M'; - case 52 - sep = 'W'; - otherwise - error('@report_table.write: Invalid frequency.'); - end - for i=1:size(thdr, 1) - period = thdr{i, 2}; - for j=1:size(period, 2) - fprintf(fid, ' & \\multicolumn{1}{c}{%s%d}', sep, period(j)); - end - end -end -fprintf(fid, '\\\\[-2pt]%%\n'); -fprintf(fid, '\\hline%%\n'); -fprintf(fid, '%%\n'); - -% Write Report_Table Data -for i=1:ne - o.series{i}.writeSeriesForTable(fid, o.range, o.precision); - if o.showHlines - fprintf(fid, '\\hline\n'); - end -end - -fprintf(fid, '\\bottomrule\n'); -fprintf(fid, '\\end{tabular}\\setlength{\\parindent}{0pt}\n \\par \\medskip\n\n'); -fprintf(fid, '%% End Report_Table Object\n'); +o = writeTableFile(o, pg, sec, row, col); +fprintf(fid, '\\input{%s}', o.tablename); end diff --git a/matlab/reports/@report_table/writeTableFile.m b/matlab/reports/@report_table/writeTableFile.m new file mode 100644 index 0000000000000000000000000000000000000000..bf0943432d52600af875e1962dc288a9ce6bd5f5 --- /dev/null +++ b/matlab/reports/@report_table/writeTableFile.m @@ -0,0 +1,178 @@ +function o = writeTableFile(o, pg, sec, row, col) +%function o = writeTableFile(o, pg, sec, row, col) +% Write a Report_Table object +% +% INPUTS +% o [report_table] report_table object +% pg [integer] this page number +% sec [integer] this section number +% row [integer] this row number +% col [integer] this col number +% +% OUTPUTS +% o [report_table] report_table object +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2013-2014 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/>. + +ne = length(o.series); +if length(o.series) == 0 + warning('@report_table.write: no series to plot, returning'); + return; +end + +if isempty(o.tablename) + o.tablename = sprintf('%s/table_pg%d_sec%d_row%d_col%d.tex', o.tableDirName, pg, sec, row, col); +end + +[fid, msg] = fopen(o.tablename, 'w'); +if fid == -1 + error(['@report_table.writeTableFile: ' msg]); +end + +%number of left-hand columns, 1 until we allow the user to group data, +% e.g.: GDP Europe +% GDP France +% GDP Germany +% this example would be two lh columns, with GDP Europe spanning both +nlhc = 1; + +if isempty(o.range) + dates = getMaxRange(o.series); +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'); + +for i=1:ndates + if o.showVlines + fprintf(fid, 'r|'); + else + fprintf(fid, 'r'); + if o.vlineAfterEndOfPeriod + if dates(i).time(2) == dates(i).freq + fprintf(fid, '|'); + end + end + if ~isempty(o.vlineAfter) + for j=1:length(o.vlineAfter) + if dates(i) == o.vlineAfter{j} + if ~(o.vlineAfterEndOfPeriod && dates(i).time(2) == dates(i).freq) + fprintf(fid, '|'); + end + 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', ''); + end +else + rhscols = {}; +end +for i=1:length(rhscols) + fprintf(fid, 'r'); + if o.showVlines + fprintf(fid, '|'); + 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', ... + ncols, o.titleFormat{i}, o.title{i}); + end +end +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); + 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, '\\\\\\cline{%d-%d}%%\n', nlhc+1, ncols); + 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}{%s%d}', sep, period(j)); + end + end +end +fprintf(fid, '\\\\[-2pt]%%\n'); +fprintf(fid, '\\hline%%\n'); +fprintf(fid, '%%\n'); + +% Write Report_Table Data +for i=1:ne + o.series{i}.writeSeriesForTable(fid, o.range, o.precision); + if o.showHlines + fprintf(fid, '\\hline\n'); + end +end + +fprintf(fid, '\\bottomrule\n'); +fprintf(fid, '\\end{tabular}\\setlength{\\parindent}{0pt}\n \\par \\medskip\n\n'); +fprintf(fid, '%% End Report_Table Object\n'); +if fclose(fid) == -1 + error('@report_table.writeTableFile: closing %s\n', o.filename); +end +end