1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
//! Info dictionary of a PDF document

extern crate lopdf;
extern crate chrono;

use PdfConformance;

/// "Info" dictionary of a PDF document.
/// Actual data is contained in `DocumentMetadata`, to keep it in sync with the `XmpMetadata`
/// (if the timestamps / settings are not in sync, Preflight will complain)
#[derive(Default, Debug, Copy, Clone)]
pub struct DocumentInfo {
    // DocumentInfo is older than XmpMetadata
    // The following is a list of things available to the DocumentInfo dictionary.
    // These keys don't have to be set:

    /*
    /Author ( Craig J. Hogan )
    /Subject ( doi:10.1038/445037a )
    /Keywords ( cosmology infrared protogalaxy starlight )
    /Identifier ( doi:10.1038/445037a )
    /Creator ( … )
    /Producer ( … )
    */

    // The more modern approach is to put them into the XmpMetadata struct:
    // This struct is merely a wrapper around those types that HAVE to be in a PDF/X-conform
    // document.

    /*
    <rdf:Description rdf:about=“” xmlns:dc=“http://purl.org/dc/elements/1.1/">
            <dc:creator>Craig J. Hogan</dc:creator>
            <dc:title>Cosmology: Ripples of early starlight</dc:title>
            <dc:identifier>doi:10.1038/445037a</dc:identifier>
            <dc:source>Nature 445, 37 (2007)</dc:source>
            <dc:date>2007-01-04</dc:date>
            <dc:format>application/pdf</dc:format>
            <dc:publisher>Nature Publishing Group</dc:publisher>
            <dc:language>en<dc:language>
            <dc:rights>© 2007 Nature Publishing Group</dc:rights>
    </rdf:Description>
    <rdf:Description rdf:about=“” xmlns:prism=“http://prismstandard.org/namespaces/1.2/basic/">
        <prism:publicationName>Nature</prism:publicationName>
        <prism:issn>0028-0836</prism:issn>
        <prism:eIssn>1476-4679</prism:eIssn>
        <prism:publicationDate>2007-01-04</prism:publicationDate>
        <prism:copyright>© 2007 Nature Publishing Group</prism:copyright>
        <prism:rightsAgent>permissions@nature.com</prism:rightsAgent>
        <prism:volume>445</prism:volume> <prism:number>7123</prism:number>
        <prism:startingPage>37</prism:startingPage>
        <prism:endingPage>37</prism:endingPage>
        <prism:section>News and Views</prism:section>
    </rdf:Description>
    */
}

impl DocumentInfo {

    /// Create a new doucment info dictionary from a document
    pub fn new()
    -> Self
    {
        Self::default()
    }

    /// This functions is similar to the IntoPdfObject trait method,
    /// but takes additional arguments in order to delay the setting
    pub(in types) fn into_obj<S>(self,
                                 document_title: S,
                                 trapping: bool,
                                 conformance: PdfConformance,
                                 creation_date: chrono::DateTime<chrono::Local>,
                                 modification_date: chrono::DateTime<chrono::Local>)
    -> lopdf::Object where S: Into<String>
    {
        use lopdf::Dictionary as LoDictionary;
        use lopdf::Object::*;
        use lopdf::StringFormat::Literal;
        use std::iter::FromIterator;

        let trapping = if trapping { "True" } else { "False" };
        let gts_pdfx_version = conformance.get_identifier_string();

        // mod_date timestamp format: D:20170505150224+02'00'
        let info_mod_date = to_pdf_time_stamp_metadata(modification_date);
        let info_create_date = to_pdf_time_stamp_metadata(creation_date);

        Dictionary(LoDictionary::from_iter(vec![
            ("Trapped", trapping.into()),
            ("CreationDate", String(info_create_date.into_bytes(), Literal)),
            ("ModDate", String(info_mod_date.into_bytes(), Literal)),
            ("GTS_PDFXVersion", String(gts_pdfx_version.into(), Literal)),
            ("Title", String(document_title.into().as_bytes().to_vec(), Literal))
        ]))
    }
}

fn to_pdf_time_stamp_metadata(date: chrono::DateTime<chrono::Local>)
-> String
{
    let time_zone = date.format("%z").to_string();
    let mod_date = date.format("D:%Y%m%d%H%M%S");
    format!("{}{}'{}'", mod_date,
                        time_zone.chars().take(3).collect::<String>(),
                        time_zone.chars().rev().take(2).collect::<String>())
}