Skip to main content

xmp_writer/
pdfa.rs

1//! PDF/A extension schema description.
2//!
3//! Enabled by the `pdfa` feature (enabled by default).
4
5use crate::{deref, Array, Namespace, RdfCollectionType, Struct};
6
7/// Write a extension schema description.
8///
9/// Created by [`PdfAExtSchemasWriter::add_schema`].
10pub struct PdfAExtSchemaWriter<'a, 'n: 'a> {
11    stc: Struct<'a, 'n>,
12}
13
14impl<'a, 'n: 'a> PdfAExtSchemaWriter<'a, 'n> {
15    fn start(stc: Struct<'a, 'n>) -> Self {
16        Self { stc }
17    }
18
19    /// Write the `pdfaSchema:schema`, `pdfaSchema:namespaceURI`, and
20    /// `pdfaSchema:prefix` properties.
21    ///
22    /// The values are extracted from the given namespace.
23    pub fn namespace(&mut self, namespace: Namespace<'n>) -> &mut Self {
24        self.schema(&format!("{} schema", namespace.name()));
25        self.namespace_uri(namespace.url());
26        self.prefix(namespace.prefix());
27        self
28    }
29
30    /// Write the `pdfaSchema:schema` property.
31    ///
32    /// Description of the extension schema.
33    fn schema(&mut self, schema: &str) -> &mut Self {
34        self.stc.element("schema", Namespace::PdfASchema).value(schema);
35        self
36    }
37
38    /// Write the `pdfaSchema:namespaceURI` property.
39    ///
40    /// The namespace URI of the extension schema.
41    fn namespace_uri(&mut self, uri: &str) -> &mut Self {
42        self.stc.element("namespaceURI", Namespace::PdfASchema).value(uri);
43        self
44    }
45
46    /// Write the `pdfaSchema:prefix` property.
47    ///
48    /// The prefix of the extension schema.
49    fn prefix(&mut self, prefix: &str) -> &mut Self {
50        self.stc.element("prefix", Namespace::PdfASchema).value(prefix);
51        self
52    }
53
54    /// Start writing the `pdfaSchema:property` sequence.
55    ///
56    /// Describes the properties of the extension schema.
57    pub fn properties(&mut self) -> PdfAExtPropertiesWriter<'_, 'n> {
58        PdfAExtPropertiesWriter::start(
59            self.stc
60                .element("property", Namespace::PdfASchema)
61                .array(RdfCollectionType::Seq),
62        )
63    }
64
65    /// Start writing the `pdfaSchema:valueType` sequence.
66    ///
67    /// Describes the value types of the extension schema.
68    pub fn value_types(&mut self) -> PdfAExtTypesWriter<'_, 'n> {
69        PdfAExtTypesWriter::start(
70            self.stc
71                .element("valueType", Namespace::PdfASchema)
72                .array(RdfCollectionType::Seq),
73        )
74    }
75}
76
77deref!('a, 'n, PdfAExtSchemaWriter<'a, 'n> => Struct<'a, 'n>, stc);
78
79/// Write a property of an extension schema.
80///
81/// Created by [`PdfAExtPropertiesWriter::add_property`].
82pub struct PdfAExtPropertyWriter<'a, 'n: 'a> {
83    stc: Struct<'a, 'n>,
84}
85
86impl<'a, 'n: 'a> PdfAExtPropertyWriter<'a, 'n> {
87    fn start(stc: Struct<'a, 'n>) -> Self {
88        Self { stc }
89    }
90
91    /// Write the `pdfaProperty:name` property.
92    ///
93    /// Name of the property.
94    pub fn name(&mut self, name: &str) -> &mut Self {
95        self.stc.element("name", Namespace::PdfAProperty).value(name);
96        self
97    }
98
99    /// Write the `pdfaProperty:valueType` property.
100    ///
101    /// The value type of the property. Shall either be defined in the XMP
102    /// specification or in the extension schema.
103    pub fn value_type(&mut self, value_type: &str) -> &mut Self {
104        self.stc
105            .element("valueType", Namespace::PdfAProperty)
106            .value(value_type);
107        self
108    }
109
110    /// Write the `pdfaProperty:category` property.
111    ///
112    /// Whether the property is generated through the document's contents
113    /// (`internal` is true) or input by the user (`internal` is false).
114    pub fn category(&mut self, internal: bool) -> &mut Self {
115        self.stc
116            .element("category", Namespace::PdfAProperty)
117            .value(if internal { "internal" } else { "external" });
118        self
119    }
120
121    /// Write the `pdfaProperty:description` property.
122    ///
123    /// Description of the property.
124    pub fn description(&mut self, description: &str) -> &mut Self {
125        self.stc
126            .element("description", Namespace::PdfAProperty)
127            .value(description);
128        self
129    }
130}
131
132deref!('a, 'n, PdfAExtPropertyWriter<'a, 'n> => Struct<'a, 'n>, stc);
133
134/// Write a value type of an extension schema.
135///
136/// Created by [`PdfAExtTypesWriter::add_value_type`].
137pub struct PdfAExtTypeWriter<'a, 'n: 'a> {
138    stc: Struct<'a, 'n>,
139}
140
141impl<'a, 'n: 'a> PdfAExtTypeWriter<'a, 'n> {
142    fn start(stc: Struct<'a, 'n>) -> Self {
143        Self { stc }
144    }
145
146    /// Write the `pdfaType:type` property.
147    ///
148    /// The name of the value type.
149    pub fn name(&mut self, name: &str) -> &mut Self {
150        self.stc.element("type", Namespace::PdfAType).value(name);
151        self
152    }
153
154    /// Write the `pdfaType:namespaceURI` and `pdfaType:prefix` properties.
155    pub fn namespace(&mut self, namespace: Namespace<'n>) -> &mut Self {
156        self.namespace_uri(namespace.url());
157        self.prefix(namespace.prefix());
158        self
159    }
160
161    /// Write the `pdfaType:namespaceURI` property.
162    ///
163    /// The namespace URI of the value type. Consider calling
164    /// [`Self::namespace`] instead.
165    pub fn namespace_uri(&mut self, uri: &str) -> &mut Self {
166        self.stc.element("namespaceURI", Namespace::PdfAType).value(uri);
167        self
168    }
169
170    /// Write the `pdfaType:prefix` property.
171    ///
172    /// The prefix of the value type. Consider calling [`Self::namespace`]
173    /// instead.
174    pub fn prefix(&mut self, prefix: &str) -> &mut Self {
175        self.stc.element("prefix", Namespace::PdfAType).value(prefix);
176        self
177    }
178
179    /// Write the `pdfaType:description` property.
180    ///
181    /// Human-readable description of the value type.
182    pub fn description(&mut self, description: &str) -> &mut Self {
183        self.stc
184            .element("description", Namespace::PdfAType)
185            .value(description);
186        self
187    }
188
189    /// Start writing the `pdfaType:field` sequence.
190    ///
191    /// Describes the fields of the value type.
192    pub fn fields(&mut self) -> PdfAExtTypeFieldsWriter<'_, 'n> {
193        PdfAExtTypeFieldsWriter::start(
194            self.stc
195                .element("field", Namespace::PdfAType)
196                .array(RdfCollectionType::Seq),
197        )
198    }
199}
200
201deref!('a, 'n, PdfAExtTypeWriter<'a, 'n> => Struct<'a, 'n>, stc);
202
203/// Write a field of an extension schema value type.
204///
205/// Created by [`PdfAExtTypeFieldsWriter::add_field`].
206pub struct PdfAExtTypeFieldWriter<'a, 'n: 'a> {
207    stc: Struct<'a, 'n>,
208}
209
210impl<'a, 'n: 'a> PdfAExtTypeFieldWriter<'a, 'n> {
211    fn start(stc: Struct<'a, 'n>) -> Self {
212        Self { stc }
213    }
214
215    /// Write the `pdfaField:name` property.
216    ///
217    /// Name of the field in the type.
218    pub fn name(&mut self, name: &str) -> &mut Self {
219        self.stc.element("name", Namespace::PdfAField).value(name);
220        self
221    }
222
223    /// Write the `pdfaField:valueType` property.
224    ///
225    /// The value type of the field. Shall either be defined in the XMP
226    /// specification or in the extension schema.
227    pub fn value_type(&mut self, value_type: &str) -> &mut Self {
228        self.stc.element("valueType", Namespace::PdfAField).value(value_type);
229        self
230    }
231
232    /// Write the `pdfaField:category` property.
233    ///
234    /// Human-readable description of the field in the type.
235    pub fn description(&mut self, description: &str) -> &mut Self {
236        self.stc
237            .element("description", Namespace::PdfAField)
238            .value(description);
239        self
240    }
241}
242
243deref!('a, 'n, PdfAExtTypeFieldWriter<'a, 'n> => Struct<'a, 'n>, stc);
244
245/// Write an array of extension schema value type fields.
246///
247/// Created by [`PdfAExtTypeWriter::fields`].
248pub struct PdfAExtTypeFieldsWriter<'a, 'n: 'a> {
249    array: Array<'a, 'n>,
250}
251
252impl<'a, 'n: 'a> PdfAExtTypeFieldsWriter<'a, 'n> {
253    fn start(array: Array<'a, 'n>) -> Self {
254        Self { array }
255    }
256
257    /// Start writing a field.
258    pub fn add_field(&mut self) -> PdfAExtTypeFieldWriter<'_, 'n> {
259        PdfAExtTypeFieldWriter::start(self.array.element().obj())
260    }
261}
262
263deref!('a, 'n, PdfAExtTypeFieldsWriter<'a, 'n> => Array<'a, 'n>, array);
264
265/// Write an array of extension schema properties.
266///
267/// Created by [`PdfAExtSchemaWriter::properties`].
268pub struct PdfAExtPropertiesWriter<'a, 'n: 'a> {
269    array: Array<'a, 'n>,
270}
271
272impl<'a, 'n: 'a> PdfAExtPropertiesWriter<'a, 'n> {
273    fn start(array: Array<'a, 'n>) -> Self {
274        Self { array }
275    }
276
277    /// Add a property.
278    pub fn add_property(&mut self) -> PdfAExtPropertyWriter<'_, 'n> {
279        PdfAExtPropertyWriter::start(self.array.element().obj())
280    }
281}
282
283deref!('a, 'n, PdfAExtPropertiesWriter<'a, 'n> => Array<'a, 'n>, array);
284
285/// Write an array of extension schema value types.
286///
287/// Created by [`PdfAExtSchemaWriter::value_types`].
288pub struct PdfAExtTypesWriter<'a, 'n: 'a> {
289    array: Array<'a, 'n>,
290}
291
292impl<'a, 'n: 'a> PdfAExtTypesWriter<'a, 'n> {
293    fn start(array: Array<'a, 'n>) -> Self {
294        Self { array }
295    }
296
297    /// Start writing a value type.
298    pub fn add_value_type(&mut self) -> PdfAExtTypeWriter<'_, 'n> {
299        PdfAExtTypeWriter::start(self.array.element().obj())
300    }
301}
302
303/// Write a set of extension schema descriptions.
304///
305/// Created by [`crate::XmpWriter::extension_schemas`]. Check PDF/A-1 TechNote
306/// 0008 to learn which schemas and properties need to be described.
307pub struct PdfAExtSchemasWriter<'a, 'n: 'a> {
308    array: Array<'a, 'n>,
309}
310
311impl<'a, 'n: 'a> PdfAExtSchemasWriter<'a, 'n> {
312    pub(crate) fn start(array: Array<'a, 'n>) -> Self {
313        Self { array }
314    }
315
316    /// Start writing a schema.
317    pub fn add_schema(&mut self) -> PdfAExtSchemaWriter<'_, 'n> {
318        PdfAExtSchemaWriter::start(self.array.element().obj())
319    }
320
321    /// Describe the `pdfaid` schema.
322    ///
323    /// If `corrigendum` is true, the `pdfaid:corr` property is added.
324    pub fn pdfaid(&mut self, corrigendum: bool) -> &mut Self {
325        {
326            let mut schema = self.add_schema();
327            schema.namespace(Namespace::PdfAId);
328            let mut properties = schema.properties();
329
330            properties
331                .add_property()
332                .category(true)
333                .description("Part of PDF/A standard")
334                .name("part")
335                .value_type("Integer");
336
337            properties
338                .add_property()
339                .category(true)
340                .description("Amendment of PDF/A standard")
341                .name("amd")
342                .value_type("Text");
343
344            if corrigendum {
345                properties
346                    .add_property()
347                    .category(true)
348                    .description("Corrigendum of PDF/A standard")
349                    .name("corr")
350                    .value_type("Text");
351            }
352
353            properties
354                .add_property()
355                .category(true)
356                .description("Conformance level of PDF/A standard")
357                .name("conformance")
358                .value_type("Text");
359        }
360        self
361    }
362
363    /// Start describing the `pdfuaid` schema.
364    pub fn pdfua_id(&mut self) -> PdfUAIdSchemaWriter<'_, 'n> {
365        PdfUAIdSchemaWriter::start(self.add_schema())
366    }
367
368    /// Start describing the `pdf` schema.
369    pub fn pdf(&mut self) -> AdobePdfDescsWriter<'_, 'n> {
370        AdobePdfDescsWriter::start(self.add_schema())
371    }
372
373    /// Start describing the `xmp` schema.
374    pub fn xmp(&mut self) -> XmpDescsWriter<'_, 'n> {
375        XmpDescsWriter::start(self.add_schema())
376    }
377
378    /// Start describing the `xmpMM` schema.
379    pub fn xmp_media_management(&mut self) -> XmpMMDescsWriter<'_, 'n> {
380        XmpMMDescsWriter::start(self.add_schema())
381    }
382
383    /// Start describing the `xmpTPg` schema.
384    pub fn paged_text(&mut self) -> PagedTextDescsWriter<'_, 'n> {
385        PagedTextDescsWriter::start(self.add_schema())
386    }
387
388    /// Start describing the `stEvt` auxiliary schema.
389    pub fn resource_event(&mut self) -> ResourceEventDescsWriter<'_, 'n> {
390        ResourceEventDescsWriter::start(self.add_schema())
391    }
392
393    /// Start describing the `xmpGImg` schema.
394    pub fn thumbnail(&mut self) -> ThumbnailSchemaWriter<'_, 'n> {
395        ThumbnailSchemaWriter::start(self.add_schema())
396    }
397}
398
399deref!('a, 'n, PdfAExtSchemasWriter<'a, 'n> => Array<'a, 'n>, array);
400
401/// Writer for the property descriptions of the `xmp` schema.
402///
403/// Only contains methods for properties that are defined in XMP 2005 or later.
404/// Created by [`XmpDescsWriter::properties`].
405pub struct XmpPropertiesWriter<'a, 'n: 'a> {
406    props: PdfAExtPropertiesWriter<'a, 'n>,
407}
408
409impl<'a, 'n: 'a> XmpPropertiesWriter<'a, 'n> {
410    fn start(props: PdfAExtPropertiesWriter<'a, 'n>) -> Self {
411        Self { props }
412    }
413
414    /// Describe the `xmp:Label` property.
415    pub fn describe_label(&mut self) -> &mut Self {
416        self.add_property()
417            .category(false)
418            .description("A user-defined label for the resource")
419            .name("Label")
420            .value_type("Text");
421        self
422    }
423
424    /// Describe the `xmp:Rating` property.
425    pub fn describe_rating(&mut self) -> &mut Self {
426        self.add_property()
427            .category(false)
428            .description("A user-assigned rating of the resource")
429            .name("Rating")
430            .value_type("Integer");
431        self
432    }
433
434    /// Describe all properties of the `xmp` schema.
435    pub fn describe_all(mut self) {
436        self.describe_label().describe_rating();
437    }
438}
439
440deref!('a, 'n, XmpPropertiesWriter<'a, 'n> => PdfAExtPropertiesWriter<'a, 'n>, props);
441
442/// Writer for describing the XMP schema.
443///
444/// Created by [`PdfAExtSchemasWriter::xmp`].
445pub struct XmpDescsWriter<'a, 'n: 'a> {
446    schema: PdfAExtSchemaWriter<'a, 'n>,
447}
448
449impl<'a, 'n: 'a> XmpDescsWriter<'a, 'n> {
450    fn start(mut schema: PdfAExtSchemaWriter<'a, 'n>) -> Self {
451        schema.namespace(Namespace::Xmp);
452        Self { schema }
453    }
454
455    /// Start describing the properties of the `xmp` schema.
456    pub fn properties(&mut self) -> XmpPropertiesWriter<'_, 'n> {
457        XmpPropertiesWriter::start(self.schema.properties())
458    }
459}
460
461deref!('a, 'n, XmpDescsWriter<'a, 'n> => PdfAExtSchemaWriter<'a, 'n>, schema);
462
463/// Writer for the property descriptions of the `xmpMM` schema.
464///
465/// Created by [`XmpMMDescsWriter::properties`].
466pub struct XmpMMPropertiesWriter<'a, 'n: 'a> {
467    props: PdfAExtPropertiesWriter<'a, 'n>,
468}
469
470impl<'a, 'n: 'a> XmpMMPropertiesWriter<'a, 'n> {
471    fn start(props: PdfAExtPropertiesWriter<'a, 'n>) -> Self {
472        Self { props }
473    }
474
475    /// Describe the `xmpMM:InstanceID` property.
476    pub fn describe_instance_id(&mut self) -> &mut Self {
477        self.add_property()
478            .category(true)
479            .description("UUID based identifier for specific incarnation of a document")
480            .name("InstanceID")
481            .value_type("Text");
482        self
483    }
484
485    /// Describe the `xmpMM:Ingredients` property.
486    pub fn describe_ingredients(&mut self) -> &mut Self {
487        self.add_property()
488            .category(true)
489            .description("List of ingredients that were used to create a document")
490            .name("Ingredients")
491            .value_type("ResourceRef");
492        self
493    }
494
495    /// Describe the `xmpMM:OriginalDocumentID` property.
496    pub fn describe_original_doc_id(&mut self) -> &mut Self {
497        self.add_property()
498            .category(true)
499            .description("UUID based identifier for original document from which a document is derived")
500            .name("OriginalDocumentID")
501            .value_type("Text");
502        self
503    }
504
505    /// Describe the `xmpMM:Pantry` property.
506    pub fn describe_pantry(&mut self) -> &mut Self {
507        self.add_property()
508            .category(true)
509            .description("List of ingredients that were used to create a document")
510            .name("Pantry")
511            .value_type("ResourceRef");
512        self
513    }
514
515    /// Describe all properties of the `xmpMM` schema.
516    pub fn describe_all(mut self) {
517        self.describe_instance_id()
518            .describe_ingredients()
519            .describe_original_doc_id()
520            .describe_pantry();
521    }
522}
523
524deref!('a, 'n, XmpMMPropertiesWriter<'a, 'n> => PdfAExtPropertiesWriter<'a, 'n>, props);
525
526/// Writer for describing the XMP Media Management schema.
527///
528/// Created by [`PdfAExtSchemasWriter::xmp_media_management`].
529pub struct XmpMMDescsWriter<'a, 'n: 'a> {
530    schema: PdfAExtSchemaWriter<'a, 'n>,
531}
532
533impl<'a, 'n: 'a> XmpMMDescsWriter<'a, 'n> {
534    fn start(mut schema: PdfAExtSchemaWriter<'a, 'n>) -> Self {
535        schema.namespace(Namespace::XmpMedia);
536        Self { schema }
537    }
538
539    /// Start describing the properties of the `xmpMM` schema.
540    pub fn properties(&mut self) -> XmpMMPropertiesWriter<'_, 'n> {
541        XmpMMPropertiesWriter::start(self.schema.properties())
542    }
543}
544
545deref!('a, 'n, XmpMMDescsWriter<'a, 'n> => PdfAExtSchemaWriter<'a, 'n>, schema);
546
547/// Writer for the property descriptions of the `pdf` schema.
548///
549/// Created by [`AdobePdfDescsWriter::properties`].
550pub struct AdobePdfPropertiesWriter<'a, 'n: 'a> {
551    props: PdfAExtPropertiesWriter<'a, 'n>,
552}
553
554impl<'a, 'n: 'a> AdobePdfPropertiesWriter<'a, 'n> {
555    fn start(props: PdfAExtPropertiesWriter<'a, 'n>) -> Self {
556        Self { props }
557    }
558
559    /// Describe the `pdf:Keywords` property.
560    ///
561    /// Optional even if present, see PDF/A-1 TechNote 0008.
562    pub fn describe_keywords(&mut self) -> &mut Self {
563        self.add_property()
564            .category(false)
565            .description("Keywords associated with the document")
566            .name("Keywords")
567            .value_type("Text");
568        self
569    }
570
571    /// Describe the `pdf:PDFVersion` property.
572    ///
573    /// Optional even if present, see PDF/A-1 TechNote 0008.
574    pub fn describe_pdf_version(&mut self) -> &mut Self {
575        self.add_property()
576            .category(true)
577            .description(
578                "Version of the PDF specification to which the document conforms",
579            )
580            .name("PDFVersion")
581            .value_type("Text");
582        self
583    }
584
585    /// Describe the `pdf:Producer` property.
586    ///
587    /// Optional even if present, see PDF/A-1 TechNote 0008.
588    pub fn describe_producer(&mut self) -> &mut Self {
589        self.add_property()
590            .category(true)
591            .description("Name of the application that created the PDF document")
592            .name("Producer")
593            .value_type("Text");
594        self
595    }
596
597    /// Describe the `pdf:Trapped` property.
598    pub fn describe_trapped(&mut self) -> &mut Self {
599        self.add_property()
600            .category(true)
601            .description("Whether the document has been trapped")
602            .name("Trapped")
603            .value_type("Text");
604        self
605    }
606
607    /// Describe all properties of the `pdf` schema.
608    pub fn describe_all(mut self) {
609        self.describe_keywords()
610            .describe_pdf_version()
611            .describe_producer()
612            .describe_trapped();
613    }
614}
615
616deref!('a, 'n, AdobePdfPropertiesWriter<'a, 'n> => PdfAExtPropertiesWriter<'a, 'n>, props);
617
618/// Writer for describing the Adobe PDF extension schema.
619///
620/// Created by [`PdfAExtSchemasWriter::pdf`].
621pub struct AdobePdfDescsWriter<'a, 'n: 'a> {
622    schema: PdfAExtSchemaWriter<'a, 'n>,
623}
624
625impl<'a, 'n: 'a> AdobePdfDescsWriter<'a, 'n> {
626    fn start(mut schema: PdfAExtSchemaWriter<'a, 'n>) -> Self {
627        schema.namespace(Namespace::AdobePdf);
628        Self { schema }
629    }
630
631    /// Start describing the properties of the `pdf` schema.
632    pub fn properties(&mut self) -> AdobePdfPropertiesWriter<'_, 'n> {
633        AdobePdfPropertiesWriter::start(self.schema.properties())
634    }
635}
636
637deref!('a, 'n, AdobePdfDescsWriter<'a, 'n> => PdfAExtSchemaWriter<'a, 'n>, schema);
638
639/// Writer for describing the Paged Text extension schema.
640///
641/// Created by [`PdfAExtSchemasWriter::paged_text`].
642pub struct PagedTextDescsWriter<'a, 'n: 'a> {
643    schema: PdfAExtSchemaWriter<'a, 'n>,
644}
645
646impl<'a, 'n: 'a> PagedTextDescsWriter<'a, 'n> {
647    fn start(mut schema: PdfAExtSchemaWriter<'a, 'n>) -> Self {
648        schema.namespace(Namespace::XmpPaged);
649        Self { schema }
650    }
651
652    /// Start describing the properties of the `xmpTPg` schema.
653    pub fn properties(&mut self) -> PagedTextPropertiesWriter<'_, 'n> {
654        PagedTextPropertiesWriter::start(self.schema.properties())
655    }
656}
657
658deref!('a, 'n, PagedTextDescsWriter<'a, 'n> => PdfAExtSchemaWriter<'a, 'n>, schema);
659
660/// Writer for the property descriptions of the `xmpTPg` schema.
661///
662/// Created by [`PagedTextDescsWriter::properties`].
663pub struct PagedTextPropertiesWriter<'a, 'n: 'a> {
664    props: PdfAExtPropertiesWriter<'a, 'n>,
665}
666
667impl<'a, 'n: 'a> PagedTextPropertiesWriter<'a, 'n> {
668    fn start(props: PdfAExtPropertiesWriter<'a, 'n>) -> Self {
669        Self { props }
670    }
671
672    /// Describe the `xmpTPg:Colorants` property.
673    pub fn describe_keywords(&mut self) -> &mut Self {
674        self.add_property()
675            .category(true)
676            .description("Colorants / swatches used in the document and its children")
677            .name("Colorants")
678            .value_type("Colorant");
679        self
680    }
681
682    /// Describe the `xmpTPg:Fonts` property.
683    pub fn describe_fonts(&mut self) -> &mut Self {
684        self.add_property()
685            .category(true)
686            .description("Fonts used in the document and its children")
687            .name("Fonts")
688            .value_type("Font");
689        self
690    }
691
692    /// Describe the `xmpTPg:PlateNames` property.
693    pub fn describe_plate_names(&mut self) -> &mut Self {
694        self.add_property()
695            .category(true)
696            .description("Plate names used in the document and its children")
697            .name("PlateNames")
698            .value_type("Text");
699        self
700    }
701
702    /// Describe all properties of the `xmpTPg` schema.
703    pub fn describe_all(mut self) {
704        self.describe_keywords().describe_fonts().describe_plate_names();
705    }
706}
707
708deref!('a, 'n, PagedTextPropertiesWriter<'a, 'n> => PdfAExtPropertiesWriter<'a, 'n>, props);
709
710/// Writer for the auxiliary ResourceEvent extension schema.
711///
712/// Created by [`PdfAExtSchemasWriter::resource_event`].
713pub struct ResourceEventDescsWriter<'a, 'n: 'a> {
714    schema: PdfAExtSchemaWriter<'a, 'n>,
715}
716
717impl<'a, 'n: 'a> ResourceEventDescsWriter<'a, 'n> {
718    fn start(mut schema: PdfAExtSchemaWriter<'a, 'n>) -> Self {
719        schema.namespace(Namespace::XmpResourceEvent);
720        Self { schema }
721    }
722
723    /// Start describing the properties of the `stEvt` schema.
724    pub fn properties(&mut self) -> ResourceEventPropertiesWriter<'_, 'n> {
725        ResourceEventPropertiesWriter::start(self.schema.properties())
726    }
727}
728
729deref!('a, 'n, ResourceEventDescsWriter<'a, 'n> => PdfAExtSchemaWriter<'a, 'n>, schema);
730
731/// Writer for the property descriptions of the `stEvt` schema.
732///     
733/// Created by [`ResourceEventDescsWriter::properties`].
734pub struct ResourceEventPropertiesWriter<'a, 'n: 'a> {
735    props: PdfAExtPropertiesWriter<'a, 'n>,
736}
737
738impl<'a, 'n: 'a> ResourceEventPropertiesWriter<'a, 'n> {
739    fn start(props: PdfAExtPropertiesWriter<'a, 'n>) -> Self {
740        Self { props }
741    }
742
743    /// Describe the `stEvt:changed` property.
744    pub fn describe_changed(&mut self) -> &mut Self {
745        self.add_property()
746            .category(false)
747            .description("semicolon-delimited list of the parts of the resource that were changed since the previous event history")
748            .name("changed")
749            .value_type("Text");
750        self
751    }
752}
753
754deref!('a, 'n, ResourceEventPropertiesWriter<'a, 'n> => PdfAExtPropertiesWriter<'a, 'n>, props);
755
756/// Writer for the thumbnail extension schema.
757///
758/// Created by [`PdfAExtSchemasWriter::thumbnail`].
759pub struct ThumbnailSchemaWriter<'a, 'n: 'a> {
760    schema: PdfAExtSchemaWriter<'a, 'n>,
761}
762
763impl<'a, 'n: 'a> ThumbnailSchemaWriter<'a, 'n> {
764    fn start(mut schema: PdfAExtSchemaWriter<'a, 'n>) -> Self {
765        schema.namespace(Namespace::XmpImage);
766        Self { schema }
767    }
768
769    /// Start describing the properties of the `xmpGImg` schema.
770    pub fn properties(&mut self) -> ThumbnailPropertiesWriter<'_, 'n> {
771        ThumbnailPropertiesWriter::start(self.schema.properties())
772    }
773}
774
775deref!('a, 'n, ThumbnailSchemaWriter<'a, 'n> => PdfAExtSchemaWriter<'a, 'n>, schema);
776
777/// Writer for the property descriptions of the `xmpGImg` schema.
778///
779/// Created by [`ThumbnailSchemaWriter::properties`].
780pub struct ThumbnailPropertiesWriter<'a, 'n: 'a> {
781    props: PdfAExtPropertiesWriter<'a, 'n>,
782}
783
784impl<'a, 'n: 'a> ThumbnailPropertiesWriter<'a, 'n> {
785    fn start(props: PdfAExtPropertiesWriter<'a, 'n>) -> Self {
786        Self { props }
787    }
788
789    /// Describe the `xmpGImg:height` property.
790    pub fn describe_height(&mut self) -> &mut Self {
791        self.add_property()
792            .category(true)
793            .description("Height of the image in pixels")
794            .name("height")
795            .value_type("Integer");
796        self
797    }
798
799    /// Describe the `xmpGImg:image` property.
800    pub fn describe_image(&mut self) -> &mut Self {
801        self.add_property()
802            .category(false)
803            .description("Thumbnail image data in base64 encoding")
804            .name("image")
805            .value_type("Text");
806        self
807    }
808
809    /// Describe the `xmpGImg:width` property.
810    pub fn describe_width(&mut self) -> &mut Self {
811        self.add_property()
812            .category(true)
813            .description("Width of the image in pixels")
814            .name("width")
815            .value_type("Integer");
816        self
817    }
818
819    /// Describe the `xmpGImg:format` property.
820    pub fn describe_format(&mut self) -> &mut Self {
821        self.add_property()
822            .category(true)
823            .description("The image encoding, i.e. JPEG")
824            .name("format")
825            .value_type("Closed Choice");
826        self
827    }
828
829    /// Describe all properties of the `xmpGImg` schema.
830    pub fn describe_all(mut self) {
831        self.describe_height()
832            .describe_image()
833            .describe_width()
834            .describe_format();
835    }
836}
837
838deref!('a, 'n, ThumbnailPropertiesWriter<'a, 'n> => PdfAExtPropertiesWriter<'a, 'n>, props);
839
840/// Writer for the PDF/UA ID extension schema.
841///
842/// Created by [`PdfAExtSchemasWriter::pdfua_id`].
843pub struct PdfUAIdSchemaWriter<'a, 'n: 'a> {
844    schema: PdfAExtSchemaWriter<'a, 'n>,
845}
846
847impl<'a, 'n: 'a> PdfUAIdSchemaWriter<'a, 'n> {
848    fn start(mut schema: PdfAExtSchemaWriter<'a, 'n>) -> Self {
849        schema.namespace(Namespace::PdfUAId);
850        Self { schema }
851    }
852
853    /// Start describing the properties of the `pdfuaId` schema.
854    pub fn properties(&mut self) -> PdfUAIdPropertiesWriter<'_, 'n> {
855        PdfUAIdPropertiesWriter::start(self.schema.properties())
856    }
857}
858
859deref!('a, 'n, PdfUAIdSchemaWriter<'a, 'n> => PdfAExtSchemaWriter<'a, 'n>, schema);
860
861/// Writer for the property descriptions of the `pdfuaid` schema.
862///
863/// Created by [`PdfUAIdSchemaWriter::properties`].
864pub struct PdfUAIdPropertiesWriter<'a, 'n: 'a> {
865    props: PdfAExtPropertiesWriter<'a, 'n>,
866}
867
868impl<'a, 'n: 'a> PdfUAIdPropertiesWriter<'a, 'n> {
869    fn start(props: PdfAExtPropertiesWriter<'a, 'n>) -> Self {
870        Self { props }
871    }
872
873    /// Describe the `pdfuaid:part` property.
874    pub fn describe_part(&mut self) -> &mut Self {
875        self.add_property()
876            .category(true)
877            .description("Part Number of ISO 14289 (PDF/UA)")
878            .name("part")
879            .value_type("Integer");
880        self
881    }
882
883    /// Describe the `pdfuaid:amd` property.
884    pub fn describe_amd(&mut self) -> &mut Self {
885        self.add_property()
886            .category(true)
887            .description("Amendment Number, Colon, and four-digit year of the publication of ISO 14289 (PDF/UA)")
888            .name("amd")
889            .value_type("Text");
890        self
891    }
892
893    /// Describe the `pdfuaid:corr` property.
894    pub fn describe_corr(&mut self) -> &mut Self {
895        self.add_property()
896            .category(true)
897            .description("Number of the technical corrigendum to ISO 14289 (PDF/UA)")
898            .name("corr")
899            .value_type("Text");
900        self
901    }
902
903    /// Describe the `pdfuaid:rev` property.
904    pub fn describe_rev(&mut self) -> &mut Self {
905        self.add_property()
906            .category(true)
907            .description("Revision of ISO 14289 (PDF/UA) as a four-digit year")
908            .name("rev")
909            .value_type("Integer");
910        self
911    }
912
913    /// Describe the applicable properties of the `pdfuaid` schema.
914    pub fn describe_all(mut self, mode: PdfUAIdDescriptionMode) {
915        let writer = self.describe_part();
916
917        match mode {
918            PdfUAIdDescriptionMode::UA1 => writer.describe_amd(),
919            PdfUAIdDescriptionMode::UA2 => writer.describe_rev(),
920            PdfUAIdDescriptionMode::AllAlive => writer.describe_amd().describe_rev(),
921            PdfUAIdDescriptionMode::All => {
922                writer.describe_amd().describe_corr().describe_rev()
923            }
924        };
925    }
926}
927
928/// Which properties of the `pdfuaid` schema to describe.
929#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
930pub enum PdfUAIdDescriptionMode {
931    /// Only describe properties defined by PDF/UA-1. This omits `pdfuaid:corr`
932    /// since no technical corrigenda to PDF/UA exist and ISO discontinued
933    /// publishing any.
934    UA1,
935    /// Only describe properties defined by PDF/UA-2.
936    UA2,
937    /// Describe all properties of the `pdfuaid` schema, except for
938    /// `pdfuaid:corr`, since no technical corrigenda to PDF/UA exist and ISO
939    /// discontinued publishing any.
940    #[default]
941    AllAlive,
942    /// Describe all properties of the `pdfuaid` schema, including `pdfuaid:corr`.
943    All,
944}
945
946deref!('a, 'n, PdfUAIdPropertiesWriter<'a, 'n> => PdfAExtPropertiesWriter<'a, 'n>, props);