www.gusucode.com > rptgen 工具箱matlab源码程序 > rptgen/zipTemplate.m

    function varargout = zipTemplate(templateFilename, varargin)
%ZIPTEMPLATE Package a DOM HTML template.
%   zipTemplate('ZIPPED_TEMPLATE_PATH', 'UNZIPPED_TEMPLATE_PATH',
%   'MAIN_DOCUMENT', 'PART_TEMPLATES') creates a compressed DOM template
%   file at the location specified by ZIPPED_TEMPLATE_PATH from the
%   unzipped template specified by UNZIPPED_TEMPLATE_PATH, including files
%   stored in subdirectories of the specified directory.  The resulting
%   compressed template preserves the directory structure of the
%   uncompressed template. The unzipped directory must contain a main
%   document name MAIN_DOCUMENT.html where MAIN_DOCUMENT is the root name
%   of the file, e.g., report.html. It must also contain a document part
%   template library file named PART_TEMPLATES.html, where PART_TEMPLATES
%   is the root name of the file, e.g., docpart_templates.html.
%
%   The zipped template file contains metafiles generated by this command
%   that enable the DOM API to determine the location of the template's
%   main document and document part template library.
% 
%   The command optionally can include metadata that defines the location
%   of the template's image directory. To enable this option include a text
%   file named _imgprefix in the unzipped template's images directory. The
%   _imgprefix may optionally include a prefix to be used by the DOM to
%   generate the names of images appended to documents based on the
%   template. For example, if the _imgprefix file contains the prefix
%   image, the DOM API generates image names of the form imageN.ext, e.g.,
%   image1.png, image2.png, etc. If the _imgprefix file is empty, the
%   generated metadata specifies the image prefix to be image.
%
%   The DOM API assumes by default that images are located in a
%   subdirectory named images of the template's root directory. Thus, you
%   do not need to include an _imgprefix file in an unzipped template whose
%   image directory is named TEMPLATE_ROOT/images.
%   
%   zipTemplate('ZIPPED_TEMPLATE_PATH', 'UNZIPPED_TEMPLATE_PATH',
%   'MAIN_DOCUMENT') assumes that the name of the document part template
%   library, if present in the unzipped template, is
%   docpart_templates.html.
%   
%   zipTemplate('ZIPPED_TEMPLATE_PATH', 'UNZIPPED_TEMPLATE_PATH') 
%   assumes that the name of the main document file is report.html. A file
%   of that name must be present in the unzipped template.
%   
%   zipTemplate('TEMPLATE_PATH') creates a compressed DOM template file.
%   The TEMPLATE_PATH argument may specify the path of the uncompressed
%   template directory or the path of the resulting template file including
%   its extension. If TEMPLATE_PATH specifies a directory, the resulting
%   template has the path TEMPLATE_PATH.htmtx. If TEMPLATE_PATH ends in an
%   extension (e.g., mytemplate.zip), the resulting compressed template has
%   the specified extension and the uncompressed template is assumed to
%   reside in a directory specified by TEMPLATE_PATH minus the extenion,
%   e.g., mytemplate).
%
%   Examples
%   --------
%   zipTemplate('myTemplate');
%   zipTemplate('myTemplate.htmtx');
%   zipTemplate('myTemplate.htmtx', 'myTemplate', ...
%        'mainpart.html', 'documentpart_templates.html');
%
%   See also unzipTemplate

%   Copyright 2014 The MathWorks, Inc.


% Check number of arguments
narginchk(1, 3);
nargoutchk(0, 1);

% Relationship and ContentType for HTMTX
HTML_MAIN_RS = 'http://schemas.mathworks.com/mlreportgen.dom/2013/relationships/htmx/main';
HTML_MAIN_CT = 'application/vnd.mathworks.mlreportgen.dom.htmx.template.main+xml';
HTML_DOCPART_CT = 'application/vnd.mathworks.mlreportgen.dom.htmx.template.library+xml';
HTML_DOCPART_RS = 'http://schemas.mathworks.com/mlreportgen.dom/2013/relationships/htmx/library';
OPC_CORE_PROPERTIES_RS = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties';
OPC_CORE_PROPERTIES_CT = 'application/vnd.openxmlformats-package.core-properties+xml';

% Entries to be removed
CT_XML = '[Content_Types].xml';
RELS_EXT = '.rels';
IMAGE_PREFIX = '_imageprefix';

% calculate zipFilename
[~, archiveFilename, archiveExt] = fileparts(templateFilename);
% if doesn't have an extension, add extension htmtx
if isempty(archiveExt)
    zipFilename = [archiveFilename '.htmtx'];
else
    zipFilename = templateFilename;
end

% calculate files
if numel(varargin) == 0
    files = {archiveFilename};
else
    files = varargin{1};
    if ischar(files)
        files = {files};
    end
end

mainPartName = 'report.html';
docpartName = 'docpart_templates.html';
backwardMainPartName = 'root.html';
backwardSupport = true;
corePropertiesPartName = 'coreProperties.xml';

% calculate mainPartName
if numel(varargin) >= 2
    mainPartName = varargin{2};
    % get filename.ext of main part
    [~, base, ext] = fileparts(mainPartName);
    mainPartName = [base ext];
    % if user provides an specific mainPartName, won't check backward
    backwardSupport = false;
    if numel(varargin) >= 3
        docpartName = varargin{3};
        % get filename.ext of docpart part
        [~, base, ext] = fileparts(docpartName);
        docpartName = [base ext];
    end
end


% Create a structure of the inputs.
entries = getArchiveEntries(files);

parts = mlreportgen.dom.OPCPart.empty(1,0);
mainPart = [];
docpartPart = [];
corePropertiesPart = [];
mainPartPosition = 0;
imageDirectory = [];
imagePrefix = [];
for i=1:length(entries)
    entry = entries(i);
    [~, base, ext] = fileparts(entry.file);
    filename = [base ext];
    
    if strcmp(CT_XML, filename) || strcmp(RELS_EXT, ext)
        continue
    end
    
    if ~isempty(entry.fileDir)
        entry.entry = entry.entry(1+length(entry.fileDir):end);
    end
    if ~strcmp(entry.entry(1), '/')
        entry.entry = ['/' entry.entry];
    end
    
    if strcmp(IMAGE_PREFIX, filename)
        [imageDirectory, ~, ~] = fileparts(entry.entry);
        imagePrefix = textread(entry.file, '%s'); %#ok<DTXTRD>
        if isempty(imagePrefix) 
            imagePrefix = 'image';
        else
            if iscell(imagePrefix)
                imagePrefix = imagePrefix{1};
            end
        end
        continue
    end
    
    parts(end+1) = mlreportgen.dom.OPCPart(entry.entry, entry.file); %#ok<AGROW>
    
    if strcmp(mainPartName, filename)
        mainPart = parts(end);
        mainPartPosition = length(parts);
    elseif strcmp(docpartName, filename)
        docpartPart = parts(end);
    elseif strcmp(corePropertiesPartName, filename)
        corePropertiesPart = parts(end);
    elseif backwardSupport
        if strcmp(backwardMainPartName, filename)
            mainPart = parts(end);
            mainPartPosition = length(parts);
        end
    end
end

if isempty(mainPart)
    % {0} main document is missing.
    error('rptgen:rptgen:missingMainDocument','%s',getString(message('rptgen:rptgen:missingMainDocument',mainPartName)));    
end

% Process Main Part
mainPart.ContentType = HTML_MAIN_CT;
mainPart.RelationshipType = HTML_MAIN_RS;
for i=1:length(parts)
    part = parts(i);
    if part ~= mainPart
        part.RelatedPart = mainPart.Name;
    end
end

if ~isempty(docpartPart)
    docpartPart.ContentType = HTML_DOCPART_CT;
    docpartPart.RelationshipType = HTML_DOCPART_RS;
    % docpart_templates.html must be a related part of the root package
    docpartPart.RelatedPart = '';
end

if ~isempty(corePropertiesPart)
    corePropertiesPart.ContentType = OPC_CORE_PROPERTIES_CT;
    corePropertiesPart.RelationshipType = OPC_CORE_PROPERTIES_RS;
    % coreProperties.xml must be a related part of the root package
    corePropertiesPart.RelatedPart = '';
end

% Create the archive
mlreportgen.dom.Document.createPackage(zipFilename);
if ~isempty(parts)
    % main part should be created first
    if ~isempty(mainPart) && parts(1) ~= mainPart
        parts(mainPartPosition) = parts(1);
        parts(1) = mainPart;
    end
    mlreportgen.dom.Document.addPackage(zipFilename, parts);
end

% set imagePrefix
if ~isempty(imageDirectory)
    mlreportgen.dom.Document.setImageDirectory(zipFilename, imageDirectory, 'html');
end
if ~isempty(imagePrefix)
    mlreportgen.dom.Document.setImagePrefix(zipFilename, imagePrefix, 'html');
end

varargout{1} = zipFilename;
end

%--------------------------------------------------------------------------
function entries = getArchiveEntries(files)
    % Only process unique files.
    [~, ia] = unique(files);
    files = files(sort(ia));

    % Create the inputs structure.
    if ~isempty(files)
        inputs = struct('file','','fileDir','');
        inputs(numel(files)) = inputs(1);
    end

    % Create a structure of the inputs, parsing the file's directory and name.
    for i = 1:length(files)
        filename = files{i};
        [fileIsDir, ~] = isDirectory(filename);
        if fileIsDir
            inputs(i).fileDir = filename;
        else
            % {0} is not a directory
            error('rptgen:rptgen:notADirectory','%s',getString(message('rptgen:rptgen:notADirectory',filename)));
        end

        inputs(i).file = filename;
    end

    % Build up list of return entries.
    entries = [];

    % Process each of the inputs
    while ~isempty(inputs)

        % Pop the next input off the stack.
        file    = inputs(1).file;
        fileDir = inputs(1).fileDir;
        inputs(1) = [];

        % Check if the file is a directory and obtain its contents.
        [fileIsDir, dirContents] = isDirectory(file);

        if fileIsDir
            % The input is a directory, add the directory listing.
            inputs = addDirectory(inputs, dirContents, file, fileDir);
        else
            % Add the fullFileName and the base and extension name to
            % the entries structure.
            entries(end+1).file = file; %#ok<AGROW>
            entries(end).entry = convertSlash(file);
            entries(end).fileDir = fileDir;
        end
    end
end

%--------------------------------------------------------------------------
function [fileIsDir, dirContents] = isDirectory(filename)
    % Check if filename exists and is a directory.

    dirContents = dir(filename);
    dirContents = {dirContents.name};
    fileIsDir = numel(dirContents) > 1;
    if fileIsDir
        dirContents = setdiff(dirContents,{'.','..'});
    end
end

%--------------------------------------------------------------------------
function inputs = addDirectory(inputs, dirContents, file, fileDir)
    % Add a directory listing to inputs.

    % Push all matches onto the stack.
    for i = 1:length(dirContents)
        inputs(end+1).file = fullfile(file, dirContents{i}); %#ok<AGROW>
        inputs(end).fileDir = fileDir;
    end
end
        
%--------------------------------------------------------------------------
function name = convertSlash(name)
    name = strrep(name, '\', '/');
    if strncmp(name,'./',2)
        % Remove first occurrence of './'
        name = name(3:end);
    end
end