Skip to content

Commit

Permalink
WIP: Add XMP metadata to ZUGFeRD
Browse files Browse the repository at this point in the history
  • Loading branch information
apardods committed Dec 20, 2024
1 parent 7bb8736 commit da7011e
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
57 changes: 57 additions & 0 deletions assets/zugferd.xmp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xpacket begin=""?>
<x:xmpmeta xmlns:x="adobe:ns:meta/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:RDF>
<rdf:Description xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
xmlns:pdfaField="http://www.aiim.org/pdfa/ns/field#"
xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"
xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
xmlns:pdfaType="http://www.aiim.org/pdfa/ns/type#"
rdf:about="">
<pdfaExtension:schemas>
<rdf:Bag>
<rdf:li rdf:parseType="Resource">
<pdfaSchema:schema>ZUGFeRD PDFA Extension Schema</pdfaSchema:schema>
<pdfaSchema:namespaceURI>urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#</pdfaSchema:namespaceURI>
<pdfaSchema:prefix>fx</pdfaSchema:prefix>
<pdfaSchema:property>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
<pdfaProperty:name>DocumentFileName</pdfaProperty:name>
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
<pdfaProperty:category>external</pdfaProperty:category>
<pdfaProperty:description>name of the embedded XML invoice file</pdfaProperty:description>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<pdfaProperty:name>DocumentType</pdfaProperty:name>
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
<pdfaProperty:category>external</pdfaProperty:category>
<pdfaProperty:description>INVOICE</pdfaProperty:description>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<pdfaProperty:name>Version</pdfaProperty:name>
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
<pdfaProperty:category>external</pdfaProperty:category>
<pdfaProperty:description>The actual version of the ZUGFeRD data</pdfaProperty:description>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<pdfaProperty:name>ConformanceLevel</pdfaProperty:name>
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
<pdfaProperty:category>external</pdfaProperty:category>
<pdfaProperty:description>The conformance level of the ZUGFeRD data</pdfaProperty:description>
</rdf:li>
</rdf:Seq>
</pdfaSchema:property>
</rdf:li>
</rdf:Bag>
</pdfaExtension:schemas>
</rdf:Description>
<rdf:Description xmlns:fx="urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#"
fx:ConformanceLevel="EN 16931"
fx:DocumentFileName="zugferd-invoice.xml"
fx:DocumentType="INVOICE"
fx:Version="1p0"
rdf:about=""/>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>
26 changes: 26 additions & 0 deletions pkg/pdf/pdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"fmt"
"io/fs"
"os"
"path/filepath"
)

Expand All @@ -24,6 +25,7 @@ type options struct {
metadata *Metadata
styles []*Stylesheet
attachments []*Attachment
xmpMetadata *XMPMetadata
}

// Metadata contains additional information to add to the PDF
Expand All @@ -49,6 +51,12 @@ type Attachment struct {
Description string
}

// XMPMetadata is used to add XMP metadata to the PDF.
type XMPMetadata struct {
Data []byte
Filename string
}

// WithURL sets the URL to use for the connection to a remote server if needed.
func WithURL(url string) Config {
return func(in any) {
Expand Down Expand Up @@ -104,6 +112,16 @@ func WithAttachment(a *Attachment) Option {
}
}

// WithXMPMetadata adds the XMP metadata to the conversion request.
func WithXMPMetadata() Option {
return func(o *options) {
o.xmpMetadata = &XMPMetadata{
Data: loadXMP(),
Filename: "zugferd.xmp",
}
}
}

// Convertor defines the interface expected to be able to convert sources into PDF
type Convertor interface {
// HTML is the default implementation that takes a raw HTML file and converts it
Expand Down Expand Up @@ -134,3 +152,11 @@ func prepareOptions(opts []Option) *options {
}
return o
}

func loadXMP() []byte {
data, err := os.ReadFile("assets/zugferd.xmp")
if err != nil {
panic(err)
}
return data
}
13 changes: 13 additions & 0 deletions pkg/pdf/prince.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,18 @@ func (pc *princeConvertor) HTML(_ context.Context, data []byte, opts ...Option)
}
}

if o.xmpMetadata != nil {
xmpFilename := "metadata.xmp"
j.Files[xmpFilename] = o.xmpMetadata.Data
if j.PDF == nil {
j.PDF = new(princepdf.PDF)
}
j.PDF.Attach = append(j.PDF.Attach, &princepdf.Attachment{
URL: xmpFilename,
Filename: xmpFilename,
Description: "XMP Metadata File",
})
}

return pc.client.Run(j)
}

0 comments on commit da7011e

Please sign in to comment.