oapi-profile-builder 3.3.0__tar.gz → 3.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {oapi_profile_builder-3.3.0/src/oapi_profile_builder.egg-info → oapi_profile_builder-3.4.1}/PKG-INFO +49 -2
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/README.md +48 -1
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/pyproject.toml +1 -1
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/cover.py +11 -7
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/generate.py +215 -3
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/models.py +35 -5
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1/src/oapi_profile_builder.egg-info}/PKG-INFO +49 -2
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/LICENSE +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/setup.cfg +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/__init__.py +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/cite.py +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/cite_features.py +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/cli.py +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/compile.py +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/server_validation.py +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder.egg-info/SOURCES.txt +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder.egg-info/dependency_links.txt +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder.egg-info/entry_points.txt +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder.egg-info/requires.txt +0 -0
- {oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder.egg-info/top_level.txt +0 -0
{oapi_profile_builder-3.3.0/src/oapi_profile_builder.egg-info → oapi_profile_builder-3.4.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: oapi-profile-builder
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.1
|
|
4
4
|
Summary: Authoritative tooling for creating OGC API Service Profiles (EDR, Features)
|
|
5
5
|
Author-email: Shane Mill <shane.mill@noaa.gov>
|
|
6
6
|
License: Apache License
|
|
@@ -239,15 +239,21 @@ Everything about the document — cover, title-page metadata, legal page, footer
|
|
|
239
239
|
| PDF colours (titles, tables, cover, backgrounds) | `document_metadata.colors` | `:presentation-metadata-color-*:` |
|
|
240
240
|
| Page-ii legal text (copyright / license / notice) | `document_metadata.boilerplate` | `:boilerplate-authority:` |
|
|
241
241
|
| Footer organisation name | `document_metadata.copyright_holder` | `:copyright-holder:` |
|
|
242
|
+
| Cover layout (logo size/position, tagline/title size, bold edition) | `document_metadata.cover.{logo_width, logo_y, tagline_font_size, title_font_size, bold_edition}` | Generated cover image |
|
|
243
|
+
| Cover date | `document_metadata.doc_pub_date` | Long-format date on the generated cover + `:published-date:` |
|
|
242
244
|
| Remove the OGC logo from the legal page | `document_metadata.suppress_flavor_logo` | targeted `:pdf-stylesheet-override:` |
|
|
243
245
|
| Remove OGC design (crossing lines, circled numbers, rules, navy divider pages) | `document_metadata.suppress_design_elements` (or the individual `suppress_crossing_lines` / `plain_section_numbers` / `suppress_title_underlines`) | `:pdf-stylesheet-override:` + colour attributes |
|
|
246
|
+
| Remove the standalone section-divider pages | `document_metadata.suppress_section_divider_pages` | `:pdf-stylesheet-override:` |
|
|
247
|
+
| Inline section headings (`1 Scope` in one line, no circle) | `document_metadata.inline_section_headers` | `:pdf-stylesheet-override:` |
|
|
248
|
+
| Flatten reference hanging indent (title under authors) | `document_metadata.suppress_bibliography_indent` | `:pdf-stylesheet-override:` |
|
|
244
249
|
| Every-page DRAFT-style watermark (over content) | `document_metadata.page_watermark` | `:pdf-stylesheet-override:` (footer overlay) |
|
|
245
250
|
| Requirement / conformance identifier namespace | `spec_uri_base` | derives `req_uri` / `conf_uri` |
|
|
246
251
|
| Submitter table, notice paragraph, normative refs, extra terms | `document_metadata.{submitters, notice, normative_references, terms}` | Metanorma attributes / sections |
|
|
252
|
+
| Features `/items` paging (`limit` parameter) | `paging.{enabled, default_limit, max_limit}` | OpenAPI query parameter |
|
|
247
253
|
|
|
248
254
|
Custom branding requires Pillow for the cover image: `pip install 'oapi-profile-builder[pdf]'`. Field-by-field detail is in the [`document_metadata`](#document_metadata) reference below; [`examples/nwp_radar.yaml`](examples/nwp_radar.yaml) is a complete DGIWG-branded example. Omit all of these fields and the output keeps the standard OGC house style.
|
|
249
255
|
|
|
250
|
-
> The `suppress_flavor_logo`, `suppress_design_elements`/`suppress_*`, and `page_watermark` overrides reach into the OGC Metanorma flavor's XSL templates (e.g. `insertLogoPreface`, `insertCrossingLines`, `insertSectionNumInCircle`, `insertFooter`) and are coupled to that flavor. Everything else uses documented Metanorma attributes. mn2pdf merges our same-named templates over the flavor's at equal precedence (via `merge_override.xsl`), which is what makes these work; a future metanorma-ogc release could require refreshing the template names. For long-term SDO adoption, a dedicated Metanorma "taste"/flavor is the most durable path.
|
|
256
|
+
> The `suppress_flavor_logo`, `suppress_design_elements`/`suppress_*`, `suppress_section_divider_pages`, `inline_section_headers`, `suppress_bibliography_indent`, and `page_watermark` overrides reach into the OGC Metanorma flavor's XSL templates (e.g. `insertLogoPreface`, `insertCrossingLines`, `insertSectionNumInCircle`, `insertFooter`, the `sections` mode, `fmt-title`, and `bibitem-normative-style`) and are coupled to that flavor. Everything else uses documented Metanorma attributes. mn2pdf merges our same-named templates over the flavor's at equal precedence (via `merge_override.xsl`), which is what makes these work; a future metanorma-ogc release could require refreshing the template names. For long-term SDO adoption, a dedicated Metanorma "taste"/flavor is the most durable path.
|
|
251
257
|
|
|
252
258
|
---
|
|
253
259
|
|
|
@@ -341,6 +347,7 @@ abstract_tests: []
|
|
|
341
347
|
| `abstract_tests` | list | no | Conformance tests — each must reference a valid requirement `id` |
|
|
342
348
|
| `pubsub` | object | no | OGC API - EDR Part 2 PubSub config — generates `asyncapi.yaml` |
|
|
343
349
|
| `collection_examples` | object | no | `{collectionId: {instanceId: "..."}}` — used by `validate-server` |
|
|
350
|
+
| `paging` | object | no | Features `/items` paging — adds a validated `limit` query parameter to the generated OpenAPI (see below) |
|
|
344
351
|
| `document_metadata` | object | no | Metanorma PDF header — doc number/type/subtype, status, editors, submitters, dates, notice, normative references (see below) |
|
|
345
352
|
|
|
346
353
|
---
|
|
@@ -624,6 +631,21 @@ Generates: `/processes/compute-difference`, `/processes/compute-difference/execu
|
|
|
624
631
|
|
|
625
632
|
---
|
|
626
633
|
|
|
634
|
+
### `paging`
|
|
635
|
+
|
|
636
|
+
Controls Features `/items` paging in the generated OpenAPI. When enabled (the default), a validated `limit` query parameter is added to every `/items` endpoint (collection-level and instance-level).
|
|
637
|
+
|
|
638
|
+
```yaml
|
|
639
|
+
paging:
|
|
640
|
+
enabled: true # default true; set false to omit the limit parameter
|
|
641
|
+
default_limit: 10 # OpenAPI schema default for limit (default 10)
|
|
642
|
+
max_limit: 100 # OpenAPI schema maximum for limit (default 10000)
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
The emitted parameter is `limit` (`in: query`, `type: integer`, `minimum: 1`, `maximum: <max_limit>`, `default: <default_limit>`).
|
|
646
|
+
|
|
647
|
+
---
|
|
648
|
+
|
|
627
649
|
### `pubsub`
|
|
628
650
|
|
|
629
651
|
When present, generates `asyncapi.yaml` alongside `openapi.yaml`.
|
|
@@ -669,6 +691,8 @@ document_metadata:
|
|
|
669
691
|
submission_date: "2026-05-01" # → :received-date:
|
|
670
692
|
approval_date: "2026-06-15" # → :issued-date:
|
|
671
693
|
publication_date: "2026-07-01" # → :published-date:
|
|
694
|
+
doc_pub_date: "2026-07-16" # optional; overrides publication_date for the cover
|
|
695
|
+
# (long-format "16 July 2026") and :published-date:
|
|
672
696
|
# Custom notice paragraph rendered in the front matter. Note: the OGC cover-page
|
|
673
697
|
# legal notice itself is generated by Metanorma from doc_type/status.
|
|
674
698
|
notice: >
|
|
@@ -707,6 +731,12 @@ document_metadata:
|
|
|
707
731
|
font_bold: "Source Sans Pro" # optional bold face; derived from font_regular when unset
|
|
708
732
|
font_italic: "Source Sans Pro" # optional italic face for the tagline
|
|
709
733
|
watermark: "DRAFT" # optional diagonal watermark stamped on the cover
|
|
734
|
+
# --- cover layout (all optional) ---
|
|
735
|
+
logo_width: 200 # target logo width in px (default 420)
|
|
736
|
+
logo_y: 100 # logo vertical offset from top in px (default 180)
|
|
737
|
+
tagline_font_size: 20 # tagline point size (default 30)
|
|
738
|
+
title_font_size: 40 # title point size (default 54)
|
|
739
|
+
bold_edition: true # render the "Edition X" line in bold (default false)
|
|
710
740
|
colors:
|
|
711
741
|
text: "#000000" # body text
|
|
712
742
|
cover_text: "#1F3864" # cover text / section numbers / ToC
|
|
@@ -763,6 +793,23 @@ With `cover` + `colors` + `copyright_holder` + `boilerplate` + `suppress_flavor_
|
|
|
763
793
|
|
|
764
794
|
> These design-element overrides (and the `page_watermark` footer overlay) reach into the OGC Metanorma flavor's XSL template names and are coupled to that flavor; a future metanorma-ogc release could require refreshing them.
|
|
765
795
|
|
|
796
|
+
#### Structural layout changes (divider pages, inline headers, references)
|
|
797
|
+
|
|
798
|
+
`suppress_design_elements` only changes *decorative* styling — it keeps the document's structure (standalone section-divider pages, the standard heading layout, and the reference hanging indent) intact. The following are **independent, opt-in** structural changes, so the default OGC output is unaffected unless you set them:
|
|
799
|
+
|
|
800
|
+
- **`suppress_section_divider_pages: true`** — removes the standalone full-page section dividers, so each section's content follows its heading directly.
|
|
801
|
+
- **`inline_section_headers: true`** — renders Level 1/2 headings inline with the title (e.g. `1 Scope`, `i Abstract`) rather than the OGC circled-number layout.
|
|
802
|
+
- **`suppress_bibliography_indent: true`** — flattens both the Normative References and the Bibliography so each entry is a single flush paragraph, removing the hanging indent that placed the title under the authors.
|
|
803
|
+
|
|
804
|
+
```yaml
|
|
805
|
+
document_metadata:
|
|
806
|
+
suppress_section_divider_pages: true
|
|
807
|
+
inline_section_headers: true
|
|
808
|
+
suppress_bibliography_indent: true
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
Additionally, when `copyright_holder` is set to a non-OGC organisation, the flavor's auto-generated "Submitting Organizations" sentence ("…submitted this Document to the Open Geospatial Consortium (OGC)") is rebranded to name that organisation instead, so no residual OGC text remains in the preface.
|
|
812
|
+
|
|
766
813
|
#### Extending Terms and Definitions
|
|
767
814
|
|
|
768
815
|
Add profile-specific terms (e.g. EDR Part 3 or Pub/Sub terms) appended after the base terms in the Terms and Definitions section:
|
|
@@ -192,15 +192,21 @@ Everything about the document — cover, title-page metadata, legal page, footer
|
|
|
192
192
|
| PDF colours (titles, tables, cover, backgrounds) | `document_metadata.colors` | `:presentation-metadata-color-*:` |
|
|
193
193
|
| Page-ii legal text (copyright / license / notice) | `document_metadata.boilerplate` | `:boilerplate-authority:` |
|
|
194
194
|
| Footer organisation name | `document_metadata.copyright_holder` | `:copyright-holder:` |
|
|
195
|
+
| Cover layout (logo size/position, tagline/title size, bold edition) | `document_metadata.cover.{logo_width, logo_y, tagline_font_size, title_font_size, bold_edition}` | Generated cover image |
|
|
196
|
+
| Cover date | `document_metadata.doc_pub_date` | Long-format date on the generated cover + `:published-date:` |
|
|
195
197
|
| Remove the OGC logo from the legal page | `document_metadata.suppress_flavor_logo` | targeted `:pdf-stylesheet-override:` |
|
|
196
198
|
| Remove OGC design (crossing lines, circled numbers, rules, navy divider pages) | `document_metadata.suppress_design_elements` (or the individual `suppress_crossing_lines` / `plain_section_numbers` / `suppress_title_underlines`) | `:pdf-stylesheet-override:` + colour attributes |
|
|
199
|
+
| Remove the standalone section-divider pages | `document_metadata.suppress_section_divider_pages` | `:pdf-stylesheet-override:` |
|
|
200
|
+
| Inline section headings (`1 Scope` in one line, no circle) | `document_metadata.inline_section_headers` | `:pdf-stylesheet-override:` |
|
|
201
|
+
| Flatten reference hanging indent (title under authors) | `document_metadata.suppress_bibliography_indent` | `:pdf-stylesheet-override:` |
|
|
197
202
|
| Every-page DRAFT-style watermark (over content) | `document_metadata.page_watermark` | `:pdf-stylesheet-override:` (footer overlay) |
|
|
198
203
|
| Requirement / conformance identifier namespace | `spec_uri_base` | derives `req_uri` / `conf_uri` |
|
|
199
204
|
| Submitter table, notice paragraph, normative refs, extra terms | `document_metadata.{submitters, notice, normative_references, terms}` | Metanorma attributes / sections |
|
|
205
|
+
| Features `/items` paging (`limit` parameter) | `paging.{enabled, default_limit, max_limit}` | OpenAPI query parameter |
|
|
200
206
|
|
|
201
207
|
Custom branding requires Pillow for the cover image: `pip install 'oapi-profile-builder[pdf]'`. Field-by-field detail is in the [`document_metadata`](#document_metadata) reference below; [`examples/nwp_radar.yaml`](examples/nwp_radar.yaml) is a complete DGIWG-branded example. Omit all of these fields and the output keeps the standard OGC house style.
|
|
202
208
|
|
|
203
|
-
> The `suppress_flavor_logo`, `suppress_design_elements`/`suppress_*`, and `page_watermark` overrides reach into the OGC Metanorma flavor's XSL templates (e.g. `insertLogoPreface`, `insertCrossingLines`, `insertSectionNumInCircle`, `insertFooter`) and are coupled to that flavor. Everything else uses documented Metanorma attributes. mn2pdf merges our same-named templates over the flavor's at equal precedence (via `merge_override.xsl`), which is what makes these work; a future metanorma-ogc release could require refreshing the template names. For long-term SDO adoption, a dedicated Metanorma "taste"/flavor is the most durable path.
|
|
209
|
+
> The `suppress_flavor_logo`, `suppress_design_elements`/`suppress_*`, `suppress_section_divider_pages`, `inline_section_headers`, `suppress_bibliography_indent`, and `page_watermark` overrides reach into the OGC Metanorma flavor's XSL templates (e.g. `insertLogoPreface`, `insertCrossingLines`, `insertSectionNumInCircle`, `insertFooter`, the `sections` mode, `fmt-title`, and `bibitem-normative-style`) and are coupled to that flavor. Everything else uses documented Metanorma attributes. mn2pdf merges our same-named templates over the flavor's at equal precedence (via `merge_override.xsl`), which is what makes these work; a future metanorma-ogc release could require refreshing the template names. For long-term SDO adoption, a dedicated Metanorma "taste"/flavor is the most durable path.
|
|
204
210
|
|
|
205
211
|
---
|
|
206
212
|
|
|
@@ -294,6 +300,7 @@ abstract_tests: []
|
|
|
294
300
|
| `abstract_tests` | list | no | Conformance tests — each must reference a valid requirement `id` |
|
|
295
301
|
| `pubsub` | object | no | OGC API - EDR Part 2 PubSub config — generates `asyncapi.yaml` |
|
|
296
302
|
| `collection_examples` | object | no | `{collectionId: {instanceId: "..."}}` — used by `validate-server` |
|
|
303
|
+
| `paging` | object | no | Features `/items` paging — adds a validated `limit` query parameter to the generated OpenAPI (see below) |
|
|
297
304
|
| `document_metadata` | object | no | Metanorma PDF header — doc number/type/subtype, status, editors, submitters, dates, notice, normative references (see below) |
|
|
298
305
|
|
|
299
306
|
---
|
|
@@ -577,6 +584,21 @@ Generates: `/processes/compute-difference`, `/processes/compute-difference/execu
|
|
|
577
584
|
|
|
578
585
|
---
|
|
579
586
|
|
|
587
|
+
### `paging`
|
|
588
|
+
|
|
589
|
+
Controls Features `/items` paging in the generated OpenAPI. When enabled (the default), a validated `limit` query parameter is added to every `/items` endpoint (collection-level and instance-level).
|
|
590
|
+
|
|
591
|
+
```yaml
|
|
592
|
+
paging:
|
|
593
|
+
enabled: true # default true; set false to omit the limit parameter
|
|
594
|
+
default_limit: 10 # OpenAPI schema default for limit (default 10)
|
|
595
|
+
max_limit: 100 # OpenAPI schema maximum for limit (default 10000)
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
The emitted parameter is `limit` (`in: query`, `type: integer`, `minimum: 1`, `maximum: <max_limit>`, `default: <default_limit>`).
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
580
602
|
### `pubsub`
|
|
581
603
|
|
|
582
604
|
When present, generates `asyncapi.yaml` alongside `openapi.yaml`.
|
|
@@ -622,6 +644,8 @@ document_metadata:
|
|
|
622
644
|
submission_date: "2026-05-01" # → :received-date:
|
|
623
645
|
approval_date: "2026-06-15" # → :issued-date:
|
|
624
646
|
publication_date: "2026-07-01" # → :published-date:
|
|
647
|
+
doc_pub_date: "2026-07-16" # optional; overrides publication_date for the cover
|
|
648
|
+
# (long-format "16 July 2026") and :published-date:
|
|
625
649
|
# Custom notice paragraph rendered in the front matter. Note: the OGC cover-page
|
|
626
650
|
# legal notice itself is generated by Metanorma from doc_type/status.
|
|
627
651
|
notice: >
|
|
@@ -660,6 +684,12 @@ document_metadata:
|
|
|
660
684
|
font_bold: "Source Sans Pro" # optional bold face; derived from font_regular when unset
|
|
661
685
|
font_italic: "Source Sans Pro" # optional italic face for the tagline
|
|
662
686
|
watermark: "DRAFT" # optional diagonal watermark stamped on the cover
|
|
687
|
+
# --- cover layout (all optional) ---
|
|
688
|
+
logo_width: 200 # target logo width in px (default 420)
|
|
689
|
+
logo_y: 100 # logo vertical offset from top in px (default 180)
|
|
690
|
+
tagline_font_size: 20 # tagline point size (default 30)
|
|
691
|
+
title_font_size: 40 # title point size (default 54)
|
|
692
|
+
bold_edition: true # render the "Edition X" line in bold (default false)
|
|
663
693
|
colors:
|
|
664
694
|
text: "#000000" # body text
|
|
665
695
|
cover_text: "#1F3864" # cover text / section numbers / ToC
|
|
@@ -716,6 +746,23 @@ With `cover` + `colors` + `copyright_holder` + `boilerplate` + `suppress_flavor_
|
|
|
716
746
|
|
|
717
747
|
> These design-element overrides (and the `page_watermark` footer overlay) reach into the OGC Metanorma flavor's XSL template names and are coupled to that flavor; a future metanorma-ogc release could require refreshing them.
|
|
718
748
|
|
|
749
|
+
#### Structural layout changes (divider pages, inline headers, references)
|
|
750
|
+
|
|
751
|
+
`suppress_design_elements` only changes *decorative* styling — it keeps the document's structure (standalone section-divider pages, the standard heading layout, and the reference hanging indent) intact. The following are **independent, opt-in** structural changes, so the default OGC output is unaffected unless you set them:
|
|
752
|
+
|
|
753
|
+
- **`suppress_section_divider_pages: true`** — removes the standalone full-page section dividers, so each section's content follows its heading directly.
|
|
754
|
+
- **`inline_section_headers: true`** — renders Level 1/2 headings inline with the title (e.g. `1 Scope`, `i Abstract`) rather than the OGC circled-number layout.
|
|
755
|
+
- **`suppress_bibliography_indent: true`** — flattens both the Normative References and the Bibliography so each entry is a single flush paragraph, removing the hanging indent that placed the title under the authors.
|
|
756
|
+
|
|
757
|
+
```yaml
|
|
758
|
+
document_metadata:
|
|
759
|
+
suppress_section_divider_pages: true
|
|
760
|
+
inline_section_headers: true
|
|
761
|
+
suppress_bibliography_indent: true
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
Additionally, when `copyright_holder` is set to a non-OGC organisation, the flavor's auto-generated "Submitting Organizations" sentence ("…submitted this Document to the Open Geospatial Consortium (OGC)") is rebranded to name that organisation instead, so no residual OGC text remains in the preface.
|
|
765
|
+
|
|
719
766
|
#### Extending Terms and Definitions
|
|
720
767
|
|
|
721
768
|
Add profile-specific terms (e.g. EDR Part 3 or Pub/Sub terms) appended after the base terms in the Terms and Definitions section:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "oapi-profile-builder"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.4.1"
|
|
8
8
|
description = "Authoritative tooling for creating OGC API Service Profiles (EDR, Features)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -173,12 +173,12 @@ def build_cover_image(profile, output_dir: Path) -> str | None:
|
|
|
173
173
|
draw.text(((_PAGE_W - tw) / 2, y), text, font=font, fill=fill)
|
|
174
174
|
return y + th
|
|
175
175
|
|
|
176
|
-
y = 180
|
|
176
|
+
y = getattr(cover, "logo_y", 180)
|
|
177
177
|
|
|
178
178
|
# --- Logo (centered, scaled to a target width) ---
|
|
179
179
|
logo = Image.open(logo_path).convert("RGBA")
|
|
180
|
-
target_logo_w =
|
|
181
|
-
max_logo_w = 520
|
|
180
|
+
target_logo_w = getattr(cover, "logo_width", 420)
|
|
181
|
+
max_logo_w = max(520, target_logo_w)
|
|
182
182
|
max_upscale = 3.0 # don't upscale tiny logos beyond this (avoids heavy blur)
|
|
183
183
|
desired = min(target_logo_w, int(logo.width * max_upscale), max_logo_w)
|
|
184
184
|
if logo.width != desired:
|
|
@@ -190,7 +190,8 @@ def build_cover_image(profile, output_dir: Path) -> str | None:
|
|
|
190
190
|
|
|
191
191
|
# --- Tagline (italic) ---
|
|
192
192
|
if cover.tagline:
|
|
193
|
-
|
|
193
|
+
tagline_fs = getattr(cover, "tagline_font_size", 30)
|
|
194
|
+
y = centered(cover.tagline, fonts.italic_font(tagline_fs), y, fg) + 60
|
|
194
195
|
|
|
195
196
|
# --- Document number ---
|
|
196
197
|
if m and m.doc_number:
|
|
@@ -199,16 +200,19 @@ def build_cover_image(profile, output_dir: Path) -> str | None:
|
|
|
199
200
|
# --- Edition ---
|
|
200
201
|
edition = getattr(profile, "version", None)
|
|
201
202
|
if edition:
|
|
202
|
-
|
|
203
|
+
bold_ed = bool(getattr(cover, "bold_edition", False))
|
|
204
|
+
y = centered(f"Edition {edition}", fonts.regular_font(28, bold=bold_ed), y, fg) + 24
|
|
203
205
|
|
|
204
206
|
# --- Date ---
|
|
205
|
-
|
|
207
|
+
pub_date = (m.doc_pub_date or m.publication_date) if m else None
|
|
208
|
+
date_str = _format_date(pub_date)
|
|
206
209
|
if date_str:
|
|
207
210
|
y = centered(f"Dated {date_str}", fonts.regular_font(28), y, fg) + 80
|
|
208
211
|
|
|
209
212
|
# --- Title (large, bold, wrapped) ---
|
|
210
213
|
title = getattr(profile, "title", "") or ""
|
|
211
|
-
|
|
214
|
+
title_fs = getattr(cover, "title_font_size", 54)
|
|
215
|
+
title_font = fonts.regular_font(title_fs, bold=True)
|
|
212
216
|
for line in _wrap(draw, title, title_font, _PAGE_W - 240):
|
|
213
217
|
y = centered(line, title_font, y, fg) + 16
|
|
214
218
|
|
{oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/generate.py
RENAMED
|
@@ -761,6 +761,35 @@ def _params_with_default_f(params: list[dict], profile: "ServiceProfile | None",
|
|
|
761
761
|
return [f_param if p is _F else p for p in params]
|
|
762
762
|
|
|
763
763
|
|
|
764
|
+
def _paging_limit_param(profile: "ServiceProfile | None") -> dict | None:
|
|
765
|
+
"""Return the `limit` query parameter for feature paging, or None when disabled."""
|
|
766
|
+
if not (profile and profile.paging and profile.paging.enabled):
|
|
767
|
+
return None
|
|
768
|
+
return {
|
|
769
|
+
"name": "limit",
|
|
770
|
+
"in": "query",
|
|
771
|
+
"required": False,
|
|
772
|
+
"description": "Limits the number of features returned in the response.",
|
|
773
|
+
"schema": {
|
|
774
|
+
"type": "integer",
|
|
775
|
+
"minimum": 1,
|
|
776
|
+
"maximum": profile.paging.max_limit,
|
|
777
|
+
"default": profile.paging.default_limit,
|
|
778
|
+
},
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
def _with_paging_limit(params: list[dict], profile: "ServiceProfile | None") -> list[dict]:
|
|
783
|
+
"""Append the paging `limit` param to a copy of *params* if enabled and absent."""
|
|
784
|
+
limit_param = _paging_limit_param(profile)
|
|
785
|
+
if limit_param is None:
|
|
786
|
+
return params
|
|
787
|
+
out = list(params)
|
|
788
|
+
if not any(isinstance(p, dict) and p.get("name") == "limit" for p in out):
|
|
789
|
+
out.append(limit_param)
|
|
790
|
+
return out
|
|
791
|
+
|
|
792
|
+
|
|
764
793
|
def _collection_paths(coll: Collection, examples: dict | None = None,
|
|
765
794
|
profile: ServiceProfile | None = None) -> dict:
|
|
766
795
|
paths: dict = {}
|
|
@@ -793,12 +822,14 @@ def _collection_paths(coll: Collection, examples: dict | None = None,
|
|
|
793
822
|
}}
|
|
794
823
|
|
|
795
824
|
# Always generate Features paths (items, queryables, schema)
|
|
825
|
+
items_params = _with_paging_limit([_F, _LANG], profile)
|
|
826
|
+
|
|
796
827
|
paths[f"{base}/items"] = {"get": {
|
|
797
828
|
"summary": f"Get {coll.title or coll.id} items",
|
|
798
829
|
"description": desc,
|
|
799
830
|
"operationId": _operation_id("get", coll.id, "Features"),
|
|
800
831
|
"tags": [tag],
|
|
801
|
-
"parameters":
|
|
832
|
+
"parameters": items_params,
|
|
802
833
|
"responses": {
|
|
803
834
|
"200": _R200_FEATURES,
|
|
804
835
|
"400": _ERR_400, "404": _ERR_404, "500": _ERR_500,
|
|
@@ -863,6 +894,8 @@ def _collection_paths(coll: Collection, examples: dict | None = None,
|
|
|
863
894
|
# instance-level query sub-paths — GET + optional POST
|
|
864
895
|
for sub_qt in (active - {"instances"}):
|
|
865
896
|
sub_params = _params_with_default_f(_QUERY_PARAMS.get(sub_qt, []), profile, _vars(sub_qt))
|
|
897
|
+
if sub_qt == "items":
|
|
898
|
+
sub_params = _with_paging_limit(sub_params, profile)
|
|
866
899
|
get_op = {
|
|
867
900
|
"summary": f"query {coll.id} instance by {sub_qt}",
|
|
868
901
|
"description": desc,
|
|
@@ -877,12 +910,13 @@ def _collection_paths(coll: Collection, examples: dict | None = None,
|
|
|
877
910
|
paths[f"{base}/instances/{{instanceId}}/{sub_qt}"] = path_ops
|
|
878
911
|
|
|
879
912
|
elif qt == "items":
|
|
913
|
+
items_params = _with_paging_limit(params, profile)
|
|
880
914
|
get_op = {
|
|
881
915
|
"summary": f"query {coll.id} by items",
|
|
882
916
|
"description": desc,
|
|
883
917
|
"operationId": _operation_id("queryItems", coll.id),
|
|
884
918
|
"tags": [tag],
|
|
885
|
-
"parameters":
|
|
919
|
+
"parameters": items_params,
|
|
886
920
|
"responses": cov_resp,
|
|
887
921
|
}
|
|
888
922
|
path_ops = {"get": get_op}
|
|
@@ -1376,6 +1410,135 @@ def _individual_test_adoc(profile: ServiceProfile, test_id: str) -> str:
|
|
|
1376
1410
|
|
|
1377
1411
|
_PDF_OVERRIDE_FILENAME = "pdf_override.xsl"
|
|
1378
1412
|
|
|
1413
|
+
_OVERRIDE_SUPPRESS_SECTION_DIVIDERS = """
|
|
1414
|
+
<!-- Suppress section-divider pages by rendering only the main content flow. -->
|
|
1415
|
+
<xsl:template match="node()" mode="sections">
|
|
1416
|
+
<xsl:param name="num"/>
|
|
1417
|
+
<xsl:param name="initial-page-number"/>
|
|
1418
|
+
<fo:page-sequence xsl:use-attribute-sets="page-sequence-main">
|
|
1419
|
+
<xsl:call-template name="refine_page-sequence-main"/>
|
|
1420
|
+
<xsl:call-template name="insertFootnoteSeparator"/>
|
|
1421
|
+
<xsl:call-template name="insertHeaderFooter">
|
|
1422
|
+
<xsl:with-param name="num" select="$num"/>
|
|
1423
|
+
</xsl:call-template>
|
|
1424
|
+
<fo:flow flow-name="xsl-region-body">
|
|
1425
|
+
<fo:block line-height="125%">
|
|
1426
|
+
<xsl:choose>
|
|
1427
|
+
<xsl:when test=".//mn:indexsect">
|
|
1428
|
+
<xsl:apply-templates select=".//mn:indexsect" mode="index"/>
|
|
1429
|
+
</xsl:when>
|
|
1430
|
+
<xsl:otherwise>
|
|
1431
|
+
<xsl:apply-templates/>
|
|
1432
|
+
</xsl:otherwise>
|
|
1433
|
+
</xsl:choose>
|
|
1434
|
+
</fo:block>
|
|
1435
|
+
</fo:flow>
|
|
1436
|
+
</fo:page-sequence>
|
|
1437
|
+
</xsl:template>
|
|
1438
|
+
"""
|
|
1439
|
+
|
|
1440
|
+
_OVERRIDE_FLATTEN_BIBLIOGRAPHY = """
|
|
1441
|
+
<!-- Remove the hanging indent on Normative References: the OGC flavor uses
|
|
1442
|
+
start-indent 25mm / text-indent -25mm so continuation lines (the title)
|
|
1443
|
+
sit indented under the authors. Flatten both to 0 so every line aligns at
|
|
1444
|
+
the left margin. -->
|
|
1445
|
+
<xsl:attribute-set name="bibitem-normative-style">
|
|
1446
|
+
<xsl:attribute name="margin-bottom">12pt</xsl:attribute>
|
|
1447
|
+
<xsl:attribute name="start-indent">0mm</xsl:attribute>
|
|
1448
|
+
<xsl:attribute name="text-indent">0mm</xsl:attribute>
|
|
1449
|
+
<xsl:attribute name="line-height">115%</xsl:attribute>
|
|
1450
|
+
</xsl:attribute-set>
|
|
1451
|
+
|
|
1452
|
+
<!-- Same for the non-normative Bibliography section: render the citation tag
|
|
1453
|
+
inline with the title as one flush block (wrapped lines align at the left
|
|
1454
|
+
margin instead of being indented under the authors). -->
|
|
1455
|
+
<xsl:template match="mn:references[not(@normative='true')]/mn:bibitem" name="bibitem_non_normative" priority="2">
|
|
1456
|
+
<xsl:param name="skip"/>
|
|
1457
|
+
<xsl:call-template name="setNamedDestination"/>
|
|
1458
|
+
<fo:block id="{@id}" margin-bottom="12pt" role="SKIP">
|
|
1459
|
+
<fo:inline role="SKIP">
|
|
1460
|
+
<xsl:apply-templates select="mn:biblio-tag">
|
|
1461
|
+
<xsl:with-param name="biblio_tag_part">first</xsl:with-param>
|
|
1462
|
+
</xsl:apply-templates>
|
|
1463
|
+
</fo:inline>
|
|
1464
|
+
<xsl:text> </xsl:text>
|
|
1465
|
+
<xsl:call-template name="processBibitem">
|
|
1466
|
+
<xsl:with-param name="biblio_tag_part">last</xsl:with-param>
|
|
1467
|
+
</xsl:call-template>
|
|
1468
|
+
</fo:block>
|
|
1469
|
+
</xsl:template>
|
|
1470
|
+
"""
|
|
1471
|
+
|
|
1472
|
+
_OVERRIDE_INLINE_SECTION_HEADERS = """
|
|
1473
|
+
<!-- Inline Level 1 section titles (e.g. '1. Scope' in a single block, no circles, no table). -->
|
|
1474
|
+
<xsl:template match="mn:fmt-title" name="title">
|
|
1475
|
+
<xsl:variable name="level"><xsl:call-template name="getLevel"/></xsl:variable>
|
|
1476
|
+
<xsl:variable name="element-name">
|
|
1477
|
+
<xsl:choose>
|
|
1478
|
+
<xsl:when test="../@inline-header = 'true'">fo:inline</xsl:when>
|
|
1479
|
+
<xsl:otherwise>fo:block</xsl:otherwise>
|
|
1480
|
+
</xsl:choose>
|
|
1481
|
+
</xsl:variable>
|
|
1482
|
+
<xsl:call-template name="setNamedDestination"/>
|
|
1483
|
+
<xsl:variable name="title_styles">
|
|
1484
|
+
<styles xsl:use-attribute-sets="title-style">
|
|
1485
|
+
<xsl:call-template name="refine_title-style"/>
|
|
1486
|
+
</styles>
|
|
1487
|
+
</xsl:variable>
|
|
1488
|
+
|
|
1489
|
+
<xsl:choose>
|
|
1490
|
+
<xsl:when test="$level = 1">
|
|
1491
|
+
<fo:block>
|
|
1492
|
+
<xsl:copy-of select="xalan:nodeset($title_styles)/styles/@*[local-name() = 'space-before' or local-name() = 'margin-bottom' or local-name() = 'keep-with-next' or local-name() = 'role']"/>
|
|
1493
|
+
<xsl:call-template name="setIDforNamedDestinationInline"/>
|
|
1494
|
+
<xsl:variable name="title">
|
|
1495
|
+
<xsl:choose>
|
|
1496
|
+
<xsl:when test="mn:tab">
|
|
1497
|
+
<xsl:copy-of select="mn:tab[1]/following-sibling::node()"/>
|
|
1498
|
+
</xsl:when>
|
|
1499
|
+
<xsl:otherwise><xsl:copy-of select="."/></xsl:otherwise>
|
|
1500
|
+
</xsl:choose>
|
|
1501
|
+
</xsl:variable>
|
|
1502
|
+
<xsl:variable name="section" select="mn:tab[1]/preceding-sibling::node()"/>
|
|
1503
|
+
<xsl:call-template name="insertSectionTitle">
|
|
1504
|
+
<xsl:with-param name="section" select="$section"/>
|
|
1505
|
+
<xsl:with-param name="title" select="$title"/>
|
|
1506
|
+
<xsl:with-param name="level" select="$level"/>
|
|
1507
|
+
</xsl:call-template>
|
|
1508
|
+
</fo:block>
|
|
1509
|
+
</xsl:when>
|
|
1510
|
+
<xsl:when test="$level = 2">
|
|
1511
|
+
<fo:block>
|
|
1512
|
+
<xsl:copy-of select="xalan:nodeset($title_styles)/styles/@*[local-name() = 'space-before' or local-name() = 'margin-bottom' or local-name() = 'keep-with-next' or local-name() = 'role']"/>
|
|
1513
|
+
<xsl:call-template name="setIDforNamedDestinationInline"/>
|
|
1514
|
+
<xsl:variable name="title">
|
|
1515
|
+
<xsl:choose>
|
|
1516
|
+
<xsl:when test="mn:tab">
|
|
1517
|
+
<xsl:copy-of select="mn:tab[1]/following-sibling::node()"/>
|
|
1518
|
+
</xsl:when>
|
|
1519
|
+
<xsl:otherwise><xsl:copy-of select="."/></xsl:otherwise>
|
|
1520
|
+
</xsl:choose>
|
|
1521
|
+
</xsl:variable>
|
|
1522
|
+
<xsl:variable name="section" select="mn:tab[1]/preceding-sibling::node()"/>
|
|
1523
|
+
<xsl:call-template name="insertSectionTitle">
|
|
1524
|
+
<xsl:with-param name="section" select="$section"/>
|
|
1525
|
+
<xsl:with-param name="title" select="$title"/>
|
|
1526
|
+
<xsl:with-param name="level" select="$level"/>
|
|
1527
|
+
</xsl:call-template>
|
|
1528
|
+
</fo:block>
|
|
1529
|
+
</xsl:when>
|
|
1530
|
+
<xsl:otherwise>
|
|
1531
|
+
<xsl:element name="{$element-name}">
|
|
1532
|
+
<xsl:copy-of select="xalan:nodeset($title_styles)/styles/@*"/>
|
|
1533
|
+
<xsl:call-template name="setIDforNamedDestinationInline"/>
|
|
1534
|
+
<xsl:apply-templates/>
|
|
1535
|
+
<xsl:apply-templates select="following-sibling::*[1][self::mn:variant-title][@type = 'sub']" mode="subtitle"/>
|
|
1536
|
+
</xsl:element>
|
|
1537
|
+
</xsl:otherwise>
|
|
1538
|
+
</xsl:choose>
|
|
1539
|
+
</xsl:template>
|
|
1540
|
+
"""
|
|
1541
|
+
|
|
1379
1542
|
# Individual template overrides for the OGC Metanorma flavor's PDF XSL. Each is
|
|
1380
1543
|
# keyed to a real template name in metanorma-ogc's ogc.standard.xsl and merged
|
|
1381
1544
|
# in via :pdf-stylesheet-override:. These are coupled to the OGC flavor.
|
|
@@ -1519,10 +1682,19 @@ def _effective_pdf_config(m) -> dict:
|
|
|
1519
1682
|
(default white) background with dark, readable numbers/titles so they no
|
|
1520
1683
|
longer carry the OGC navy house style.
|
|
1521
1684
|
"""
|
|
1685
|
+
# suppress_design_elements ("debrand") controls only the OGC *decorative*
|
|
1686
|
+
# motifs — the blue crossing lines, the circular clause-number badges and the
|
|
1687
|
+
# short rule under titles — plus the section-divider page recolouring. It does
|
|
1688
|
+
# NOT remove the section-divider pages, inline the headers, or reflow the
|
|
1689
|
+
# bibliography: those are structural/layout choices left as independent opt-ins
|
|
1690
|
+
# so the default OGC document keeps its divider pages and standard layout.
|
|
1522
1691
|
debrand = bool(getattr(m, "suppress_design_elements", False))
|
|
1523
1692
|
crossing = debrand or bool(getattr(m, "suppress_crossing_lines", False))
|
|
1524
1693
|
underlines = debrand or bool(getattr(m, "suppress_title_underlines", False))
|
|
1525
1694
|
plain_nums = debrand or bool(getattr(m, "plain_section_numbers", False))
|
|
1695
|
+
suppress_divs = bool(getattr(m, "suppress_section_divider_pages", False))
|
|
1696
|
+
inline_headers = bool(getattr(m, "inline_section_headers", False))
|
|
1697
|
+
biblio_indent = bool(getattr(m, "suppress_bibliography_indent", False))
|
|
1526
1698
|
|
|
1527
1699
|
colors = getattr(m, "colors", None)
|
|
1528
1700
|
page_bg = getattr(colors, "page_background", None) if colors else None
|
|
@@ -1548,6 +1720,9 @@ def _effective_pdf_config(m) -> dict:
|
|
|
1548
1720
|
"crossing": crossing,
|
|
1549
1721
|
"underlines": underlines,
|
|
1550
1722
|
"plain_nums": plain_nums,
|
|
1723
|
+
"suppress_divs": suppress_divs,
|
|
1724
|
+
"inline_headers": inline_headers,
|
|
1725
|
+
"biblio_indent": biblio_indent,
|
|
1551
1726
|
"body_font": getattr(m, "body_font", None),
|
|
1552
1727
|
"watermark": getattr(m, "page_watermark", None),
|
|
1553
1728
|
"divider_bg": divider_bg,
|
|
@@ -1555,6 +1730,32 @@ def _effective_pdf_config(m) -> dict:
|
|
|
1555
1730
|
}
|
|
1556
1731
|
|
|
1557
1732
|
|
|
1733
|
+
def _submitting_orgs_text_override(org_name: str) -> str:
|
|
1734
|
+
"""Rebrand the OGC flavor's auto-generated 'Submitting Organizations' sentence.
|
|
1735
|
+
|
|
1736
|
+
The OGC Metanorma flavor hardcodes "...submitted this Document to the Open
|
|
1737
|
+
Geospatial Consortium (OGC):" in its presentation stage (not the i18n YAML),
|
|
1738
|
+
so it lands in the presentation XML as the text of the
|
|
1739
|
+
``clause[@type='submitting_orgs']`` paragraph. We replace just that text node
|
|
1740
|
+
with the rebranded SDO name, leaving the paragraph's styling intact.
|
|
1741
|
+
|
|
1742
|
+
Fragile by nature: coupled to the exact sentence the OGC flavor emits. If the
|
|
1743
|
+
flavor changes that wording, this literal will no longer match and should be
|
|
1744
|
+
updated.
|
|
1745
|
+
"""
|
|
1746
|
+
org = _xml_escape(org_name)
|
|
1747
|
+
return f"""
|
|
1748
|
+
<!-- Rebrand the flavor's auto-generated 'Submitting Organizations' sentence
|
|
1749
|
+
(the OGC flavor injects 'the Open Geospatial Consortium (OGC)' at its
|
|
1750
|
+
presentation stage). Match the clause's paragraph element specifically —
|
|
1751
|
+
more specific than the base mn:p template, so mn2pdf's merge appends this
|
|
1752
|
+
and it wins for that paragraph only, leaving all other paragraphs alone. -->
|
|
1753
|
+
<xsl:template match="mn:clause[@type='submitting_orgs']/mn:p">
|
|
1754
|
+
<fo:block xsl:use-attribute-sets="p-style" role="P">The following organizations submitted this Document to {org}:</fo:block>
|
|
1755
|
+
</xsl:template>
|
|
1756
|
+
"""
|
|
1757
|
+
|
|
1758
|
+
|
|
1558
1759
|
def _pdf_override_flags(m) -> list[str]:
|
|
1559
1760
|
"""Return the override snippets enabled by document_metadata, in order."""
|
|
1560
1761
|
if not m:
|
|
@@ -1569,6 +1770,17 @@ def _pdf_override_flags(m) -> list[str]:
|
|
|
1569
1770
|
parts.append(_OVERRIDE_SUPPRESS_TITLE_UNDERLINES)
|
|
1570
1771
|
if cfg["plain_nums"]:
|
|
1571
1772
|
parts.append(_plain_section_numbers_override(cfg["divider_fg"]))
|
|
1773
|
+
if cfg["suppress_divs"]:
|
|
1774
|
+
parts.append(_OVERRIDE_SUPPRESS_SECTION_DIVIDERS)
|
|
1775
|
+
if cfg["inline_headers"]:
|
|
1776
|
+
parts.append(_OVERRIDE_INLINE_SECTION_HEADERS)
|
|
1777
|
+
if cfg["biblio_indent"]:
|
|
1778
|
+
parts.append(_OVERRIDE_FLATTEN_BIBLIOGRAPHY)
|
|
1779
|
+
# Rebrand the flavor's auto-generated "Submitting Organizations" sentence to
|
|
1780
|
+
# name the copyright holder (e.g. DGIWG) instead of OGC, when rebranding.
|
|
1781
|
+
holder = getattr(m, "copyright_holder", None)
|
|
1782
|
+
if holder and holder.strip().upper() not in ("OGC", "OPEN GEOSPATIAL CONSORTIUM"):
|
|
1783
|
+
parts.append(_submitting_orgs_text_override(holder))
|
|
1572
1784
|
# When the divider background is rebranded (light), force the big title
|
|
1573
1785
|
# colour too — the flavor inherits white text, invisible on a light page.
|
|
1574
1786
|
if cfg["divider_bg"] is not None:
|
|
@@ -1699,7 +1911,7 @@ def _build_document_adoc(profile: ServiceProfile) -> str:
|
|
|
1699
1911
|
":committee: technical",
|
|
1700
1912
|
f":docnumber: {m.doc_number if m else profile.name}",
|
|
1701
1913
|
f":copyright-year: {year}",
|
|
1702
|
-
f":published-date: {(m.publication_date if m and m.publication_date else default_date)}",
|
|
1914
|
+
f":published-date: {((m.doc_pub_date or m.publication_date) if m and (m.doc_pub_date or m.publication_date) else default_date)}",
|
|
1703
1915
|
f":issued-date: {(m.approval_date if m and m.approval_date else default_date)}",
|
|
1704
1916
|
f":received-date: {(m.submission_date if m and m.submission_date else default_date)}",
|
|
1705
1917
|
]
|
{oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/models.py
RENAMED
|
@@ -472,6 +472,11 @@ class CoverPage(BaseModel):
|
|
|
472
472
|
"Note: this marks the cover only; an every-page watermark requires the Metanorma layer."
|
|
473
473
|
),
|
|
474
474
|
)
|
|
475
|
+
logo_width: int = Field(default=420, description="Target logo width on cover page")
|
|
476
|
+
logo_y: int = Field(default=180, description="Logo y-offset from top of cover page")
|
|
477
|
+
tagline_font_size: int = Field(default=30, description="Font size of cover page tagline")
|
|
478
|
+
title_font_size: int = Field(default=54, description="Font size of cover page title")
|
|
479
|
+
bold_edition: bool = Field(default=False, description="When true, render edition in bold font")
|
|
475
480
|
|
|
476
481
|
@field_validator("background", "text_color")
|
|
477
482
|
@classmethod
|
|
@@ -599,6 +604,18 @@ class DocumentMetadata(BaseModel):
|
|
|
599
604
|
"the flavor's built-in text via :boilerplate-authority:."
|
|
600
605
|
),
|
|
601
606
|
)
|
|
607
|
+
doc_pub_date: str | None = Field(default=None, description="Alternative field for publication date (YYYY-MM-DD)")
|
|
608
|
+
suppress_section_divider_pages: bool = Field(default=False, description="When true, completely remove section-divider pages from the PDF")
|
|
609
|
+
inline_section_headers: bool = Field(default=False, description="When true, render Level 1 headings inline without circles or table formatting")
|
|
610
|
+
suppress_bibliography_indent: bool = Field(
|
|
611
|
+
default=False,
|
|
612
|
+
description=(
|
|
613
|
+
"When true, remove the OGC flavor's hanging indent on non-normative "
|
|
614
|
+
"bibliography/reference entries so the citation tag and title render as a "
|
|
615
|
+
"single flush paragraph (wrapped lines align at the left margin instead of "
|
|
616
|
+
"being indented under the authors). Coupled to the OGC Metanorma flavor."
|
|
617
|
+
),
|
|
618
|
+
)
|
|
602
619
|
suppress_flavor_logo: bool = Field(
|
|
603
620
|
default=False,
|
|
604
621
|
description=(
|
|
@@ -651,10 +668,15 @@ class DocumentMetadata(BaseModel):
|
|
|
651
668
|
default=False,
|
|
652
669
|
description=(
|
|
653
670
|
"When true, strip the OGC flavor's decorative PDF design elements — the "
|
|
654
|
-
"blue 'crossing lines' motif, the circular badges around clause numbers,
|
|
655
|
-
"the short rule under clause titles — via a targeted PDF stylesheet
|
|
656
|
-
"
|
|
657
|
-
"DGIWG) that don't use the OGC house style.
|
|
671
|
+
"blue 'crossing lines' motif, the circular badges around clause numbers, "
|
|
672
|
+
"and the short rule under clause titles — via a targeted PDF stylesheet "
|
|
673
|
+
"override, and recolour the section-divider pages to a clean light "
|
|
674
|
+
"background for SDOs (e.g. DGIWG) that don't use the OGC house style. "
|
|
675
|
+
"This affects only decorative styling: it does NOT remove the "
|
|
676
|
+
"section-divider pages, inline the section headers, or reflow the "
|
|
677
|
+
"bibliography — use suppress_section_divider_pages, inline_section_headers "
|
|
678
|
+
"and suppress_bibliography_indent for those structural changes. Coupled to "
|
|
679
|
+
"the OGC Metanorma flavor."
|
|
658
680
|
),
|
|
659
681
|
)
|
|
660
682
|
page_watermark: str | None = Field(
|
|
@@ -666,7 +688,7 @@ class DocumentMetadata(BaseModel):
|
|
|
666
688
|
),
|
|
667
689
|
)
|
|
668
690
|
|
|
669
|
-
@field_validator("submission_date", "approval_date", "publication_date")
|
|
691
|
+
@field_validator("submission_date", "approval_date", "publication_date", "doc_pub_date")
|
|
670
692
|
@classmethod
|
|
671
693
|
def _valid_date(cls, v: str | None) -> str | None:
|
|
672
694
|
if v is not None and not _DATE_RE.match(v):
|
|
@@ -700,6 +722,13 @@ class PubSubConfig(BaseModel):
|
|
|
700
722
|
collection_filters: dict[str, CollectionPubSub] = Field(default_factory=dict, description="Per-collection filter overrides")
|
|
701
723
|
|
|
702
724
|
|
|
725
|
+
class PagingConfig(BaseModel):
|
|
726
|
+
"""Optional pagination parameters config."""
|
|
727
|
+
enabled: bool = Field(default=True, description="When true, include standard limit parameter in /items endpoint")
|
|
728
|
+
default_limit: int = Field(default=10, description="Default number of features to return", ge=1)
|
|
729
|
+
max_limit: int = Field(default=10000, description="Maximum allowed limit for features returned", ge=1)
|
|
730
|
+
|
|
731
|
+
|
|
703
732
|
# ---------------------------------------------------------------------------
|
|
704
733
|
# Root model — the authoritative profile definition
|
|
705
734
|
# ---------------------------------------------------------------------------
|
|
@@ -767,6 +796,7 @@ class ServiceProfile(BaseModel):
|
|
|
767
796
|
pubsub: PubSubConfig | None = None
|
|
768
797
|
processes: list[dict] = Field(default_factory=list)
|
|
769
798
|
document_metadata: DocumentMetadata | None = None
|
|
799
|
+
paging: PagingConfig = Field(default_factory=PagingConfig)
|
|
770
800
|
|
|
771
801
|
# OGC API - EDR Part 3 specific fields
|
|
772
802
|
required_conformance_classes: list[str] = Field(
|
{oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1/src/oapi_profile_builder.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: oapi-profile-builder
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.1
|
|
4
4
|
Summary: Authoritative tooling for creating OGC API Service Profiles (EDR, Features)
|
|
5
5
|
Author-email: Shane Mill <shane.mill@noaa.gov>
|
|
6
6
|
License: Apache License
|
|
@@ -239,15 +239,21 @@ Everything about the document — cover, title-page metadata, legal page, footer
|
|
|
239
239
|
| PDF colours (titles, tables, cover, backgrounds) | `document_metadata.colors` | `:presentation-metadata-color-*:` |
|
|
240
240
|
| Page-ii legal text (copyright / license / notice) | `document_metadata.boilerplate` | `:boilerplate-authority:` |
|
|
241
241
|
| Footer organisation name | `document_metadata.copyright_holder` | `:copyright-holder:` |
|
|
242
|
+
| Cover layout (logo size/position, tagline/title size, bold edition) | `document_metadata.cover.{logo_width, logo_y, tagline_font_size, title_font_size, bold_edition}` | Generated cover image |
|
|
243
|
+
| Cover date | `document_metadata.doc_pub_date` | Long-format date on the generated cover + `:published-date:` |
|
|
242
244
|
| Remove the OGC logo from the legal page | `document_metadata.suppress_flavor_logo` | targeted `:pdf-stylesheet-override:` |
|
|
243
245
|
| Remove OGC design (crossing lines, circled numbers, rules, navy divider pages) | `document_metadata.suppress_design_elements` (or the individual `suppress_crossing_lines` / `plain_section_numbers` / `suppress_title_underlines`) | `:pdf-stylesheet-override:` + colour attributes |
|
|
246
|
+
| Remove the standalone section-divider pages | `document_metadata.suppress_section_divider_pages` | `:pdf-stylesheet-override:` |
|
|
247
|
+
| Inline section headings (`1 Scope` in one line, no circle) | `document_metadata.inline_section_headers` | `:pdf-stylesheet-override:` |
|
|
248
|
+
| Flatten reference hanging indent (title under authors) | `document_metadata.suppress_bibliography_indent` | `:pdf-stylesheet-override:` |
|
|
244
249
|
| Every-page DRAFT-style watermark (over content) | `document_metadata.page_watermark` | `:pdf-stylesheet-override:` (footer overlay) |
|
|
245
250
|
| Requirement / conformance identifier namespace | `spec_uri_base` | derives `req_uri` / `conf_uri` |
|
|
246
251
|
| Submitter table, notice paragraph, normative refs, extra terms | `document_metadata.{submitters, notice, normative_references, terms}` | Metanorma attributes / sections |
|
|
252
|
+
| Features `/items` paging (`limit` parameter) | `paging.{enabled, default_limit, max_limit}` | OpenAPI query parameter |
|
|
247
253
|
|
|
248
254
|
Custom branding requires Pillow for the cover image: `pip install 'oapi-profile-builder[pdf]'`. Field-by-field detail is in the [`document_metadata`](#document_metadata) reference below; [`examples/nwp_radar.yaml`](examples/nwp_radar.yaml) is a complete DGIWG-branded example. Omit all of these fields and the output keeps the standard OGC house style.
|
|
249
255
|
|
|
250
|
-
> The `suppress_flavor_logo`, `suppress_design_elements`/`suppress_*`, and `page_watermark` overrides reach into the OGC Metanorma flavor's XSL templates (e.g. `insertLogoPreface`, `insertCrossingLines`, `insertSectionNumInCircle`, `insertFooter`) and are coupled to that flavor. Everything else uses documented Metanorma attributes. mn2pdf merges our same-named templates over the flavor's at equal precedence (via `merge_override.xsl`), which is what makes these work; a future metanorma-ogc release could require refreshing the template names. For long-term SDO adoption, a dedicated Metanorma "taste"/flavor is the most durable path.
|
|
256
|
+
> The `suppress_flavor_logo`, `suppress_design_elements`/`suppress_*`, `suppress_section_divider_pages`, `inline_section_headers`, `suppress_bibliography_indent`, and `page_watermark` overrides reach into the OGC Metanorma flavor's XSL templates (e.g. `insertLogoPreface`, `insertCrossingLines`, `insertSectionNumInCircle`, `insertFooter`, the `sections` mode, `fmt-title`, and `bibitem-normative-style`) and are coupled to that flavor. Everything else uses documented Metanorma attributes. mn2pdf merges our same-named templates over the flavor's at equal precedence (via `merge_override.xsl`), which is what makes these work; a future metanorma-ogc release could require refreshing the template names. For long-term SDO adoption, a dedicated Metanorma "taste"/flavor is the most durable path.
|
|
251
257
|
|
|
252
258
|
---
|
|
253
259
|
|
|
@@ -341,6 +347,7 @@ abstract_tests: []
|
|
|
341
347
|
| `abstract_tests` | list | no | Conformance tests — each must reference a valid requirement `id` |
|
|
342
348
|
| `pubsub` | object | no | OGC API - EDR Part 2 PubSub config — generates `asyncapi.yaml` |
|
|
343
349
|
| `collection_examples` | object | no | `{collectionId: {instanceId: "..."}}` — used by `validate-server` |
|
|
350
|
+
| `paging` | object | no | Features `/items` paging — adds a validated `limit` query parameter to the generated OpenAPI (see below) |
|
|
344
351
|
| `document_metadata` | object | no | Metanorma PDF header — doc number/type/subtype, status, editors, submitters, dates, notice, normative references (see below) |
|
|
345
352
|
|
|
346
353
|
---
|
|
@@ -624,6 +631,21 @@ Generates: `/processes/compute-difference`, `/processes/compute-difference/execu
|
|
|
624
631
|
|
|
625
632
|
---
|
|
626
633
|
|
|
634
|
+
### `paging`
|
|
635
|
+
|
|
636
|
+
Controls Features `/items` paging in the generated OpenAPI. When enabled (the default), a validated `limit` query parameter is added to every `/items` endpoint (collection-level and instance-level).
|
|
637
|
+
|
|
638
|
+
```yaml
|
|
639
|
+
paging:
|
|
640
|
+
enabled: true # default true; set false to omit the limit parameter
|
|
641
|
+
default_limit: 10 # OpenAPI schema default for limit (default 10)
|
|
642
|
+
max_limit: 100 # OpenAPI schema maximum for limit (default 10000)
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
The emitted parameter is `limit` (`in: query`, `type: integer`, `minimum: 1`, `maximum: <max_limit>`, `default: <default_limit>`).
|
|
646
|
+
|
|
647
|
+
---
|
|
648
|
+
|
|
627
649
|
### `pubsub`
|
|
628
650
|
|
|
629
651
|
When present, generates `asyncapi.yaml` alongside `openapi.yaml`.
|
|
@@ -669,6 +691,8 @@ document_metadata:
|
|
|
669
691
|
submission_date: "2026-05-01" # → :received-date:
|
|
670
692
|
approval_date: "2026-06-15" # → :issued-date:
|
|
671
693
|
publication_date: "2026-07-01" # → :published-date:
|
|
694
|
+
doc_pub_date: "2026-07-16" # optional; overrides publication_date for the cover
|
|
695
|
+
# (long-format "16 July 2026") and :published-date:
|
|
672
696
|
# Custom notice paragraph rendered in the front matter. Note: the OGC cover-page
|
|
673
697
|
# legal notice itself is generated by Metanorma from doc_type/status.
|
|
674
698
|
notice: >
|
|
@@ -707,6 +731,12 @@ document_metadata:
|
|
|
707
731
|
font_bold: "Source Sans Pro" # optional bold face; derived from font_regular when unset
|
|
708
732
|
font_italic: "Source Sans Pro" # optional italic face for the tagline
|
|
709
733
|
watermark: "DRAFT" # optional diagonal watermark stamped on the cover
|
|
734
|
+
# --- cover layout (all optional) ---
|
|
735
|
+
logo_width: 200 # target logo width in px (default 420)
|
|
736
|
+
logo_y: 100 # logo vertical offset from top in px (default 180)
|
|
737
|
+
tagline_font_size: 20 # tagline point size (default 30)
|
|
738
|
+
title_font_size: 40 # title point size (default 54)
|
|
739
|
+
bold_edition: true # render the "Edition X" line in bold (default false)
|
|
710
740
|
colors:
|
|
711
741
|
text: "#000000" # body text
|
|
712
742
|
cover_text: "#1F3864" # cover text / section numbers / ToC
|
|
@@ -763,6 +793,23 @@ With `cover` + `colors` + `copyright_holder` + `boilerplate` + `suppress_flavor_
|
|
|
763
793
|
|
|
764
794
|
> These design-element overrides (and the `page_watermark` footer overlay) reach into the OGC Metanorma flavor's XSL template names and are coupled to that flavor; a future metanorma-ogc release could require refreshing them.
|
|
765
795
|
|
|
796
|
+
#### Structural layout changes (divider pages, inline headers, references)
|
|
797
|
+
|
|
798
|
+
`suppress_design_elements` only changes *decorative* styling — it keeps the document's structure (standalone section-divider pages, the standard heading layout, and the reference hanging indent) intact. The following are **independent, opt-in** structural changes, so the default OGC output is unaffected unless you set them:
|
|
799
|
+
|
|
800
|
+
- **`suppress_section_divider_pages: true`** — removes the standalone full-page section dividers, so each section's content follows its heading directly.
|
|
801
|
+
- **`inline_section_headers: true`** — renders Level 1/2 headings inline with the title (e.g. `1 Scope`, `i Abstract`) rather than the OGC circled-number layout.
|
|
802
|
+
- **`suppress_bibliography_indent: true`** — flattens both the Normative References and the Bibliography so each entry is a single flush paragraph, removing the hanging indent that placed the title under the authors.
|
|
803
|
+
|
|
804
|
+
```yaml
|
|
805
|
+
document_metadata:
|
|
806
|
+
suppress_section_divider_pages: true
|
|
807
|
+
inline_section_headers: true
|
|
808
|
+
suppress_bibliography_indent: true
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
Additionally, when `copyright_holder` is set to a non-OGC organisation, the flavor's auto-generated "Submitting Organizations" sentence ("…submitted this Document to the Open Geospatial Consortium (OGC)") is rebranded to name that organisation instead, so no residual OGC text remains in the preface.
|
|
812
|
+
|
|
766
813
|
#### Extending Terms and Definitions
|
|
767
814
|
|
|
768
815
|
Add profile-specific terms (e.g. EDR Part 3 or Pub/Sub terms) appended after the base terms in the Terms and Definitions section:
|
|
File without changes
|
|
File without changes
|
{oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/cite_features.py
RENAMED
|
File without changes
|
|
File without changes
|
{oapi_profile_builder-3.3.0 → oapi_profile_builder-3.4.1}/src/oapi_profile_builder/compile.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|