Initial commit
This commit is contained in:
20
skills/ppt/.claude/settings.local.json
Executable file
20
skills/ppt/.claude/settings.local.json
Executable file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"WebFetch(domain:www.npmjs.com)",
|
||||
"WebSearch",
|
||||
"Bash(node -e \"const pptx = require\\('pptxgenjs'\\); console.log\\(Object.keys\\(pptx.prototype || pptx\\).slice\\(0,5\\)\\); const p = new pptx\\(\\); console.log\\(p.presLayout\\); console.log\\(typeof p.ShapeType\\);\")",
|
||||
"Bash(node:*)",
|
||||
"Bash(python3:*)",
|
||||
"Bash(ls /share/hc/utils/superz/test_beam6/ppt_normal_zh_66/download/ppt-workspace/*.html)",
|
||||
"Bash(sort -t_ -k4 -n)",
|
||||
"Bash(ls /share/hc/utils/superz/test_beam6/ppt_normal_zh_79/download/ppt-workspace/*.html)",
|
||||
"Bash(ls /share/hc/utils/superz/test_beam6/ppt_normal_zh_78/download/ppt-workspace/*.html)",
|
||||
"Bash(xargs -I{} head -3 {})",
|
||||
"Bash(npm root:*)",
|
||||
"Read(//root/.nvm/versions/node/v24.14.1/lib/node_modules/**)",
|
||||
"Read(//usr/**)",
|
||||
"Bash(NODE_PATH=/share/hc/utils/superz/p-p-p-x/ppt0403/node_modules node:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
13
skills/ppt/LICENSE.txt
Executable file
13
skills/ppt/LICENSE.txt
Executable file
@@ -0,0 +1,13 @@
|
||||
Copyright (c) 2026 Z.ai All rights reserved.
|
||||
|
||||
Permission is granted for personal, educational, and non-commercial use only.
|
||||
|
||||
Commercial use is strictly prohibited without prior written permission from the author.
|
||||
|
||||
Unauthorized copying, modification, or distribution of the software for commercial purposes is prohibited.
|
||||
|
||||
The author reserves the right to make the final determination of what constitutes "commercial use".
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM THE USE OF THE SOFTWARE.
|
||||
436
skills/ppt/SKILL.md
Executable file
436
skills/ppt/SKILL.md
Executable file
@@ -0,0 +1,436 @@
|
||||
---
|
||||
name: ppt
|
||||
metadata:
|
||||
author: Z.AI
|
||||
version: "1.0"
|
||||
description: "Presentation creation, editing, and analysis for .pptx files: (1) Creating new presentations, (2) Modifying or editing content, (3) Working with layouts, (4) Adding comments or speaker notes. Academic/paper-based presentations use the embedded Beamer module at end of this file (PDF output only)."
|
||||
license: Proprietary. LICENSE.txt has complete terms
|
||||
---
|
||||
|
||||
# PPT creation, editing, and analysis
|
||||
|
||||
## Quick Setup
|
||||
|
||||
```bash
|
||||
bash "$SKILL_DIR/setup.sh" # Interactive environment check + install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Routing: Academic / Paper-Based Presentations → Beamer
|
||||
|
||||
> **STOP — check this before doing any work.**
|
||||
>
|
||||
> If the request matches **any** trigger below, **skip the PPTX workflow entirely**.
|
||||
> Read **[`beamer.md`](beamer.md)** in this directory and follow its instructions.
|
||||
|
||||
| Trigger | Typical phrasing |
|
||||
|---------|-----------------|
|
||||
| Reading / summarizing a paper to make slides | "read this PDF and make slides", "make slides from this paper" |
|
||||
| Academic / scientific / research presentation | "conference talk", "research presentation", "academic presentation" |
|
||||
| Thesis or dissertation defense | "thesis defense", "proposal defense", "defense slides" |
|
||||
| Any scholarly audience presentation | "academic PPT", "paper presentation", "research talk" |
|
||||
| STEM / science courseware | "STEM slides", "science lecture", "math/physics/chemistry courseware" |
|
||||
| User mentions a "paper" or "thesis" in any language | "present this paper", "talk about this thesis", "summarize this article into slides" |
|
||||
| Uploaded file is clearly an academic paper | "make slides from this", "help me present this" — where the uploaded PDF contains academic indicators (abstract, keywords, references, DOI, author affiliations, journal name) in the first 3 pages |
|
||||
|
||||
|
||||
> **Beamer output format: PDF-style slides only.**
|
||||
>
|
||||
> **Routing decision rule:** The trigger table above applies to **all languages**. For non-English requests, match by semantic meaning — mentally translate the user's intent into English and check against the triggers.
|
||||
>
|
||||
> **Important:** In many languages (e.g., Chinese, Japanese, Korean), "PPT" is a generic colloquial word for "slides" or "presentation" — it does NOT indicate a preference for `.pptx` format. Only route to the PPTX workflow when the user **explicitly** requests `.pptx` format (e.g., "I need a .pptx file", "export as pptx") or the content is clearly non-academic (e.g., marketing, business, teaching children).
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
A user may ask you to create, edit, or analyze the contents of a .pptx file. A .pptx file is essentially a ZIP archive containing XML files and other resources that you can read or edit. You have different tools and workflows available for different tasks.
|
||||
|
||||
## Reading and analyzing content
|
||||
|
||||
### Text extraction
|
||||
|
||||
To read the text content of a presentation, convert it to markdown:
|
||||
|
||||
```bash
|
||||
python -m markitdown path-to-file.pptx
|
||||
```
|
||||
|
||||
### Raw XML access
|
||||
|
||||
For comments, speaker notes, slide layouts, animations, design elements, or complex formatting, unpack the presentation and inspect its raw XML.
|
||||
|
||||
#### Unpacking a file
|
||||
|
||||
```
|
||||
python ooxml/scripts/unpack.py <office_file> <output_dir>
|
||||
```
|
||||
|
||||
**Note**: `unpack.py` is at `skills/pptx/ooxml/scripts/unpack.py` relative to the project root. If not found, run `find . -name "unpack.py"` to locate it.
|
||||
|
||||
#### Key file structures
|
||||
|
||||
| Path | Contents |
|
||||
|------|----------|
|
||||
| `ppt/presentation.xml` | Main metadata and slide references |
|
||||
| `ppt/slides/slide{N}.xml` | Per-slide content |
|
||||
| `ppt/notesSlides/notesSlide{N}.xml` | Speaker notes |
|
||||
| `ppt/comments/modernComment_*.xml` | Slide comments |
|
||||
| `ppt/slideLayouts/` | Layout templates |
|
||||
| `ppt/slideMasters/` | Master slide templates |
|
||||
| `ppt/theme/` | Theme and styling |
|
||||
| `ppt/media/` | Images and other media |
|
||||
|
||||
#### Typography and color extraction
|
||||
|
||||
**When emulating an existing design**, extract typography and colors before starting:
|
||||
|
||||
1. **Theme file** — `ppt/theme/theme1.xml`: colors (`<a:clrScheme>`), fonts (`<a:fontScheme>`)
|
||||
2. **Slide content** — `ppt/slides/slide1.xml`: actual font usage (`<a:rPr>`) and colors
|
||||
3. **Global search** — grep for `<a:solidFill>`, `<a:srgbClr>`, and font references across all XML files
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Creating a new PowerPoint presentation **using a template**
|
||||
|
||||
When the user upload a pptx file,and do not ask you to create a fully new pptx,you must create a presentation that follows an existing template's design, you'll need to duplicate and re-arrange template slides before then replacing placeholder content.
|
||||
|
||||
### Workflow
|
||||
1. **Extract template text AND create visual thumbnail grid**:
|
||||
* Extract text: `python -m markitdown template.pptx > template-content.md`
|
||||
* Read `template-content.md`: Read the entire file. **NEVER set any range limits.**
|
||||
* Create thumbnail grids: `python scripts/thumbnail.py template.pptx`
|
||||
* See [Creating Thumbnail Grids](#creating-thumbnail-grids) section for details
|
||||
|
||||
2. **Analyze template and save inventory to a file**:
|
||||
* **Visual Analysis**: Review thumbnail grid(s) to understand layouts and design patterns
|
||||
* Create and save `template-inventory.md` containing:
|
||||
```markdown
|
||||
# Template Inventory Analysis
|
||||
**Total Slides: [count]**
|
||||
**IMPORTANT: Slides are 0-indexed (first slide = 0, last slide = count-1)**
|
||||
|
||||
## [Category Name]
|
||||
- Slide 0: [Layout code if available] - Description/purpose
|
||||
- Slide 1: [Layout code] - Description/purpose
|
||||
[... EVERY slide must be listed ...]
|
||||
```
|
||||
|
||||
3. **Create presentation outline based on template inventory**:
|
||||
* Choose layouts that match your content structure
|
||||
* **CRITICAL: Match layout structure to actual content**:
|
||||
- Single-column layouts: Use for unified narrative or single topic
|
||||
- Two-column layouts: Use ONLY when you have exactly 2 distinct items
|
||||
- Three-column layouts: Use ONLY when you have exactly 3 distinct items
|
||||
- Image + text layouts: Use ONLY when you have actual images
|
||||
- Count your actual content pieces BEFORE selecting layout
|
||||
* Save `outline.md` with content AND template mapping
|
||||
|
||||
4. **Duplicate, reorder, and delete slides using `rearrange.py`**:
|
||||
```bash
|
||||
python scripts/rearrange.py template.pptx working.pptx 0,34,34,50,52
|
||||
```
|
||||
|
||||
5. **Extract ALL text using the `inventory.py` script**:
|
||||
```bash
|
||||
python scripts/inventory.py working.pptx text-inventory.json
|
||||
```
|
||||
Read `text-inventory.json` entirely. **NEVER set range limits.**
|
||||
|
||||
6. **Generate replacement text and save to JSON file**:
|
||||
- Verify which shapes exist in inventory — only reference shapes that are present
|
||||
- Add `"paragraphs"` field to shapes that need content
|
||||
- **ALL text shapes from inventory will be cleared** unless you provide "paragraphs"
|
||||
- Paragraphs with bullets are automatically left-aligned
|
||||
- **Do NOT include bullet symbols** (bullet, -, *) in text — they're added automatically
|
||||
- Save to `replacement-text.json`
|
||||
|
||||
**CRITICAL — JSON generation rules (learned from practice):**
|
||||
- **Always use `json.dump()` to write the file** — never write raw JSON strings in Python code.
|
||||
Raw strings may embed unescaped `"` characters (e.g. `"三遥"`, `"线上+线下"`) that silently
|
||||
break JSON parsing. `json.dump(data, f, ensure_ascii=False, indent=2)` handles all escaping
|
||||
automatically.
|
||||
- **Respect small box character limits** — check `width` and `font_size` from inventory before
|
||||
writing text for numeric/label shapes. A box of `width ≤ 0.7"` at `font_size ≥ 16pt` can hold
|
||||
roughly 3–4 characters max. Keep percentage values like `"99.7%"` to ≤ 4 chars, or shorten
|
||||
(e.g. `"100%"` instead of `"99.96%"`).
|
||||
- **Match replacement length to original** — for body text boxes, count characters in the
|
||||
original inventory text. Replacements significantly longer than the original will overflow.
|
||||
When in doubt, err shorter rather than longer.
|
||||
- **Test incrementally** — validate with a 5-slide subset before writing the full deck.
|
||||
`replace.py` blocks on overflow errors; fix them slide-by-slide rather than all at once.
|
||||
|
||||
7. **Apply replacements**:
|
||||
```bash
|
||||
python scripts/replace.py working.pptx replacement-text.json output.pptx
|
||||
```
|
||||
|
||||
## Creating a new PowerPoint presentation **without a template**
|
||||
|
||||
When creating a new PowerPoint presentation from scratch, use the **Design System + Component** workflow.
|
||||
|
||||
### Step 0 — Scene Classification (MANDATORY)
|
||||
|
||||
Before ANY design work, classify the presentation into one of the five scenes below:
|
||||
|
||||
| Scene | Keywords / Triggers |
|
||||
|-------|-------------------|
|
||||
| **Teaching / Training** | course, teaching, training, lecture, courseware, knowledge points, lesson plan |
|
||||
| **Work Report / Review** | report, review, summary, retrospective, OKR, KPI, quarterly, annual |
|
||||
| **Proposal / Pitch** | proposal, plan, pitch, investor, roadshow, business plan |
|
||||
| **Thesis Defense / Academic** | thesis, defense, research, academic, topic, graduation project — **→ if source is a paper/PDF or audience is academic, read [`beamer.md`](beamer.md) instead** |
|
||||
| **General** | None of the above, or user did not specify |
|
||||
|
||||
### Step 1 — Select Theme (MANDATORY)
|
||||
|
||||
Read [`themes.md`](themes.md) and select a theme based on scene and content tone.
|
||||
|
||||
**Output**: State your chosen theme name, your chosen **accent variant** (A/B/C), and the full color palette (primary-80, primary-90, primary-5, accent, etc.) before writing any code.
|
||||
|
||||
**Accent variant selection**: Each theme offers 3 accent colors (A = default, B, C). Choose the variant that best matches the content tone. You may also mix — e.g., use accent-A for most slides and accent-B for emphasis pages — but keep the primary palette constant.
|
||||
|
||||
Theme selection tips:
|
||||
- Work report → Ocean or Graphite
|
||||
- Proposal / pitch → Ocean, Sandstone, or Twilight
|
||||
- Teaching / courseware → Forest or Ocean
|
||||
- Thesis defense → read [`beamer.md`](beamer.md) (PDF output); if `.pptx` is explicitly required, use Graphite or Forest
|
||||
- Tech keynote / product launch → Deep Mineral or Mono
|
||||
- Cultural / lifestyle / brand → Warm Retro
|
||||
- ESG / sustainability → Deep Forest or Forest
|
||||
- Consumer / lifestyle / female audience → Coral
|
||||
- Healthcare / wellness / eco → Mint
|
||||
- SaaS / AI / onboarding → Azure
|
||||
- Annual events / launches / high-energy → Ember
|
||||
- General → any theme that fits the content
|
||||
|
||||
**After selecting a theme, note its Image Keywords and Mask Color** — you will need them in Step 5.5.
|
||||
|
||||
### Step 2 — Read Design System (MANDATORY)
|
||||
|
||||
Read [`design-system.md`](design-system.md). Understand the color system (mandatory) and creative principles (guidelines). The color scale is the only hard constraint — everything else (spacing, font sizes, layout) is flexible.
|
||||
|
||||
### Step 3 — Read HTML-to-PPTX Guide (MANDATORY)
|
||||
|
||||
Read [`html2pptx.md`](html2pptx.md) completely from start to finish. **NEVER set any range limits when reading this file.**
|
||||
|
||||
### Step 4 — Plan Slide Sequence
|
||||
|
||||
For each slide, decide:
|
||||
1. Which **component** from [`components.md`](components.md) to use as a starting point (or design from scratch)
|
||||
2. What **content** to fill in — **be generous with content; fill the slide**
|
||||
3. How to **remix** the component — change spacing, font sizes, card styles, backgrounds, proportions to create variety
|
||||
|
||||
**KEY PRINCIPLES**:
|
||||
- Read [`components.md`](components.md) for available starting points
|
||||
- Also read [`data-viz-components.md`](data-viz-components.md) for data visualization components
|
||||
- **Adjacent slides MUST look distinctly different** — vary layout structure, background, card treatment
|
||||
- **Fill the slide**: Avoid large empty areas. If content is sparse, use larger typography, more generous spacing, bigger visual elements, or add decorative elements to create visual richness
|
||||
- **Every content slide should have at least one non-text visual element** (color block, stat number, chart, icon, accent bar, photo, shape)
|
||||
- Alternate between high-density and low-density pages for rhythm
|
||||
- Use data visualization components when content contains numbers, comparisons, percentages
|
||||
- **Tables are a great way to enrich content** — use `content-table*` or `content-chart-*` from components.md whenever content involves structured data, feature comparisons, schedules, or multi-attribute lists
|
||||
|
||||
**Anti-whitespace strategies** (use when a slide feels empty):
|
||||
- Increase font sizes (e.g., body from 15pt to 17pt, headings from 22pt to 26pt)
|
||||
- Add colored background blocks or sections
|
||||
- Use a darker or tinted background instead of pure white
|
||||
- Add decorative elements (accent bars, shapes, gradient bands)
|
||||
- Expand card padding and spacing
|
||||
- Use a photo background with mask overlay
|
||||
- Switch from a text-heavy layout to a visual-heavy one
|
||||
|
||||
**Note: Not all whitespace is bad.** KPI pages, quote pages, and big-number focus pages are *designed* to have generous whitespace — that's intentional emphasis. Only fix whitespace on content-heavy pages (bullet lists, card grids, text blocks) where it looks accidental. See design-system.md §2.2 for the full distinction.
|
||||
|
||||
**Slide sequence pattern** (recommended):
|
||||
```
|
||||
1. Cover → PREFER cover-photo-mask (with downloaded photo + theme mask)
|
||||
→ Fallback: cover-dark-hero (no photo needed) or cover-split
|
||||
2. TOC → toc-card-grid (surface bg) / toc-big-number (visual variety)
|
||||
3. Section divider (optional) → divider-photo-mask (different photo from cover)
|
||||
→ or divider-gradient / divider-bold-center
|
||||
4. Content page A → light background, visually rich component
|
||||
5. Content page B → ★ DARK BACKGROUND ★ (content-dark-bullets / dark-kpi / dark-split)
|
||||
6. Section divider (optional) → different variant from #3
|
||||
7. Content page C → image-based (split-text-visual, photo-cards, etc.)
|
||||
8. Content page D → data-focused (kpi-row, big-number-focus, etc.)
|
||||
9. Closing → dark background echoing cover color
|
||||
|
||||
Background rhythm target: ~40% white, ~25% surface/tinted, ~20% dark, ~15% photo
|
||||
```
|
||||
|
||||
### Step 5 — Generate HTML from Components
|
||||
|
||||
For each slide:
|
||||
1. Start from a component template in `components.md`, or design from scratch
|
||||
2. Replace all `${variable}` placeholders with actual theme color values
|
||||
3. Replace placeholder text with actual content
|
||||
4. Adjust element count (add/remove cards, list items) as needed
|
||||
5. **Before writing each slide's HTML**: Check the **Card Style Cookbook** at the top of components.md. Pick a different card style from the previous slide. Also check if this slide should use a **Dark Background Content Template**.
|
||||
6. **Be creative**: Freely modify spacing, font sizes, card styles, proportions, background treatments, and decorative elements across pages. The only hard constraints are the html2pptx engine limitations (no flex-wrap, no negative margins, no DIV background-image, no CSS gradients). Use the design-system.md Quick Reference for suggested ranges, but treat them as starting points, not limits.
|
||||
- **Card styles**: Use the **Card Style Cookbook** in components.md to swap between shadow/outline/solid/accent-bar/dark card styles. No 2 adjacent slides should use the same card style.
|
||||
- **Title bars**: All content slides must use the **same header style** — pick one title bar variant from components.md and apply it consistently across every content page.
|
||||
- **Dark pages**: Use the **Dark Background Content Templates** in components.md for rhythm-breaking dark slides. Aim for at least 1 dark content page per 4 slides.
|
||||
6. **Fill the slide**: If there's visible empty space, increase font sizes, add visual elements, expand padding, or use a colored/photo background. A well-filled slide looks professional; excessive whitespace looks unfinished.
|
||||
|
||||
|
||||
### Step 5.8 — Visual Diversity Check (RECOMMENDED)
|
||||
|
||||
Before converting to PPTX, do a quick scan of your slide sequence:
|
||||
- Are adjacent slides visually distinct (different layout, background, card style)?
|
||||
- Is there enough variety across the deck (multiple layout structures, card treatments, background approaches)?
|
||||
- Is there at least one dramatic "rhythm breaker" page?
|
||||
- Do real photographs appear on covers and at least one other slide?
|
||||
|
||||
If the answer to any is "no", revise before proceeding.
|
||||
|
||||
### Step 6 — Convert and Validate
|
||||
|
||||
1. Create and run a JavaScript file using [`html2pptx.js`](scripts/html2pptx.js) to convert HTML slides to PowerPoint:
|
||||
```javascript
|
||||
const pptxgen = require('pptxgenjs');
|
||||
const html2pptx = require('./html2pptx');
|
||||
|
||||
const pptx = new pptxgen();
|
||||
pptx.layout = 'LAYOUT_16x9';
|
||||
|
||||
// Optional: custom font configuration
|
||||
const fontConfig = { cjk: 'Microsoft YaHei', latin: 'Corbel' };
|
||||
|
||||
// Process ALL slides with warnings collection
|
||||
const allWarnings = [];
|
||||
for (const htmlFile of slideFiles) {
|
||||
const { slide, placeholders, warnings } = await html2pptx(htmlFile, pptx, { fontConfig });
|
||||
allWarnings.push(...warnings);
|
||||
}
|
||||
|
||||
// Add charts to placeholder areas if any
|
||||
if (placeholders.length > 0) {
|
||||
slide.addChart(pptx.charts.LINE, chartData, placeholders[0]);
|
||||
}
|
||||
|
||||
await pptx.writeFile('output.pptx');
|
||||
```
|
||||
|
||||
2. **Check warnings**: Review `warnings` output. **Blocking issues** (overflow, font < 11pt) must be fixed. **Non-blocking warnings** (bounds, balance, density) are suggestions — use judgment on whether to fix them.
|
||||
|
||||
3. **Visual validation**: Generate thumbnails and inspect for layout issues:
|
||||
```bash
|
||||
python scripts/thumbnail.py output.pptx workspace/thumbnails --cols 4
|
||||
```
|
||||
- Read and carefully examine the thumbnail image for:
|
||||
- **Text cutoff**: Text being cut off by header bars, shapes, or slide edges
|
||||
- **Text overlap**: Text overlapping with other text or shapes
|
||||
- **Positioning issues**: Content too close to slide boundaries or other elements
|
||||
- **Contrast issues**: Insufficient contrast between text and backgrounds
|
||||
- **Consistency check**: All body text same font and size? All page margins consistent? All content slides use the same header style?
|
||||
- If issues found, adjust HTML and regenerate
|
||||
- Repeat until all slides are visually correct
|
||||
|
||||
### Step 6.5 — Final Quality Check (RECOMMENDED)
|
||||
|
||||
Before finalizing, do a quick visual quality scan:
|
||||
|
||||
- ✅ Real photographs used (cover + at least 1 other slide)
|
||||
- ✅ Background variety (at least 3 different treatments)
|
||||
- ✅ No 2 consecutive slides look the same
|
||||
- ✅ Multiple layout structures used (aim for 5+)
|
||||
- ✅ Card styles vary across pages
|
||||
- ✅ Every slide has a clear visual focal point
|
||||
- ✅ At least 1 dramatic full-bleed or dark page exists
|
||||
- ✅ All referenced image files exist and are > 10KB
|
||||
|
||||
If major issues are found, fix and regenerate. Minor imperfections are acceptable — don't over-optimize at the cost of creativity.
|
||||
|
||||
### Design Hard Rules (ALWAYS ENFORCED)
|
||||
|
||||
These rules are split into **engine constraints** (violating them causes broken output) and **design principles** (ensuring quality).
|
||||
|
||||
**Engine Constraints (technical — cannot be violated):**
|
||||
```
|
||||
[ENGINE] Slide canvas is 720×405pt — content exceeding this overflows
|
||||
[ENGINE] All colors must come from the theme color scale — no arbitrary grays (#666 #999 #DDD)
|
||||
[ENGINE] font-family must include a CJK font name to trigger correct mapping
|
||||
[ENGINE] Do not use flex-wrap — multi-row layouts must use separate flex containers
|
||||
[ENGINE] Do not use negative margins — they cause text stacking in PPT
|
||||
[ENGINE] Multi-column equal-width cards must use fixed width + flex-shrink:0, not flex:1
|
||||
[ENGINE] Background images only work on <body>, not <div> — DIV background-image is not supported
|
||||
[ENGINE] Images must be local file paths, not URLs
|
||||
[ENGINE] Titles and short labels (<10 characters) should use white-space:nowrap
|
||||
[ENGINE] Numeric sequences (e.g. 01/02/03, $12M) should use white-space:nowrap
|
||||
```
|
||||
|
||||
**Design Principles (creative quality — strongly encouraged):**
|
||||
```
|
||||
[DESIGN] Adjacent slides should use different layouts, backgrounds, and card styles
|
||||
[DESIGN] Every content slide should have at least one visual focal point
|
||||
[DESIGN] Cover and closing page should echo each other
|
||||
[DESIGN] Prefer cutting content over shrinking fonts — only when a slide is already well-filled and overflow is imminent; never cut content preemptively
|
||||
[DESIGN] Aim for 5+ layout structures, 3+ card styles, 3+ background treatments across the deck
|
||||
[DESIGN] Insert a rhythm-breaking page every 3-4 slides
|
||||
[DESIGN] Background images should have a mask overlay for text readability
|
||||
[DESIGN] Content should be vertically balanced, not crammed at the top
|
||||
[DESIGN] Accent colors must have HSL saturation ≤ 65% — high-saturation colors look garish on projection
|
||||
[DESIGN] Large color blocks (>15% page area) should use S ≤ 50% — only small accents can be vivid
|
||||
[DESIGN] All content slides must use the same header style — pick one title bar variant and apply it consistently across all content pages
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Editing an existing PowerPoint presentation
|
||||
|
||||
When editing slides in an existing PowerPoint presentation, work with raw Office Open XML (OOXML) format.
|
||||
|
||||
### Workflow
|
||||
1. **MANDATORY - READ ENTIRE FILE**: Read [`ooxml.md`](ooxml.md) (~500 lines) completely from start to finish. **NEVER set any range limits when reading this file.**
|
||||
2. Unpack the presentation: `python ooxml/scripts/unpack.py <office_file> <output_dir>`
|
||||
3. Edit the XML files (primarily `ppt/slides/slide{N}.xml` and related files)
|
||||
4. **CRITICAL**: Validate immediately after each edit: `python ooxml/scripts/validate.py <dir> --original <file>`
|
||||
5. Pack the final presentation: `python ooxml/scripts/pack.py <input_directory> <office_file>`
|
||||
|
||||
|
||||
|
||||
## Creating Thumbnail Grids
|
||||
|
||||
```bash
|
||||
python scripts/thumbnail.py template.pptx [output_prefix]
|
||||
```
|
||||
|
||||
**Features**:
|
||||
- Creates: `thumbnails.jpg` (or `thumbnails-1.jpg`, `thumbnails-2.jpg` for large decks)
|
||||
- Default: 5 columns, max 30 slides per grid (5x6)
|
||||
- Custom prefix: `python scripts/thumbnail.py template.pptx my-grid`
|
||||
- Adjust columns: `--cols 4` (range: 3-6)
|
||||
- Slides are zero-indexed (Slide 0, Slide 1, etc.)
|
||||
|
||||
## Converting Slides to Images
|
||||
|
||||
1. **Convert PPTX to PDF**:
|
||||
```bash
|
||||
soffice --headless --convert-to pdf template.pptx
|
||||
```
|
||||
|
||||
2. **Convert PDF pages to JPEG images**:
|
||||
```bash
|
||||
pdftoppm -jpeg -r 150 template.pdf slide
|
||||
```
|
||||
|
||||
## Code Style Guidelines
|
||||
**IMPORTANT**: When generating code for PPTX operations:
|
||||
- Write concise code
|
||||
- Avoid verbose variable names and redundant operations
|
||||
- Avoid unnecessary print statements
|
||||
|
||||
## Dependencies
|
||||
|
||||
Required dependencies (should already be installed):
|
||||
|
||||
- **markitdown**: `pip install "markitdown[pptx]"` (text extraction)
|
||||
- **pptxgenjs**: `npm install -g pptxgenjs` (creating presentations)
|
||||
- **playwright**: `npm install -g playwright` (HTML rendering)
|
||||
- **react-icons**: `npm install -g react-icons react react-dom` (icons)
|
||||
- **sharp**: `npm install -g sharp` (SVG rasterization and image processing)
|
||||
- **LibreOffice**: `sudo apt-get install libreoffice` (PDF conversion)
|
||||
- **Poppler**: `sudo apt-get install poppler-utils` (pdftoppm)
|
||||
- **defusedxml**: `pip install defusedxml` (secure XML parsing)
|
||||
1461
skills/ppt/beamer.md
Executable file
1461
skills/ppt/beamer.md
Executable file
File diff suppressed because it is too large
Load Diff
1671
skills/ppt/components.md
Executable file
1671
skills/ppt/components.md
Executable file
File diff suppressed because it is too large
Load Diff
529
skills/ppt/data-viz-components.md
Executable file
529
skills/ppt/data-viz-components.md
Executable file
@@ -0,0 +1,529 @@
|
||||
# Data Visualization Components — Supplement to components.md
|
||||
|
||||
These components use **pure HTML+CSS** to render charts and data visualizations without relying on PptxGenJS chart API. They convert directly through html2pptx into shapes.
|
||||
|
||||
**When to use**: Prefer data visualization components whenever the content contains numbers, comparisons, percentages, or structured data. Every PPT with 6+ slides **MUST** include at least 1-2 data visualization pages.
|
||||
|
||||
**Selection principle**: Concrete data → prioritize data viz components (bars/tables/funnels/donuts) over plain text lists. Alternate between text pages and data pages for visual rhythm.
|
||||
|
||||
For PptxGenJS native charts (BAR/LINE/PIE/DOUGHNUT), use `content-chart-focus` with placeholder + `slide.addChart()` in compile.js.
|
||||
|
||||
---
|
||||
|
||||
<a id="content-horizontal-bars"></a>
|
||||
### content-horizontal-bars — Horizontal Bar Comparison
|
||||
|
||||
`data | medium | light | none`
|
||||
|
||||
Multi-item value comparison. Best for: market share, KPI benchmarks, quarterly comparisons.
|
||||
|
||||
```html
|
||||
<body style="width:720pt; height:405pt; margin:0; padding:0; overflow:hidden;
|
||||
background-color:${background};
|
||||
font-family:'Microsoft YaHei',sans-serif;
|
||||
display:flex; flex-direction:column;">
|
||||
|
||||
<div style="width:720pt; height:56pt; background:${primary-90};
|
||||
display:flex; align-items:center; padding:0 48pt;">
|
||||
<h2 style="font-size:22pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1.25;">
|
||||
Market Share Comparison
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div style="flex:1; display:flex; flex-direction:column; justify-content:center; padding:0 48pt; gap:20pt;">
|
||||
|
||||
<!-- Bar item: repeat for each data point -->
|
||||
<div style="display:flex; align-items:center; gap:12pt;">
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:100pt; line-height:1.3; white-space:nowrap;">Product A</p>
|
||||
<div style="flex:1; height:24pt; background:${primary-10}; border-radius:4pt;">
|
||||
<div style="height:24pt; width:70%; background:${primary-80}; border-radius:4pt;"></div>
|
||||
</div>
|
||||
<p style="font-size:15pt; font-weight:bold; color:${primary-80}; margin:0; width:48pt; text-align:right; line-height:1;">70%</p>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; align-items:center; gap:12pt;">
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:100pt; line-height:1.3; white-space:nowrap;">Product B</p>
|
||||
<div style="flex:1; height:24pt; background:${primary-10}; border-radius:4pt;">
|
||||
<div style="height:24pt; width:52%; background:${primary-60}; border-radius:4pt;"></div>
|
||||
</div>
|
||||
<p style="font-size:15pt; font-weight:bold; color:${primary-60}; margin:0; width:48pt; text-align:right; line-height:1;">52%</p>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; align-items:center; gap:12pt;">
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:100pt; line-height:1.3; white-space:nowrap;">Product C</p>
|
||||
<div style="flex:1; height:24pt; background:${primary-10}; border-radius:4pt;">
|
||||
<div style="height:24pt; width:38%; background:${primary-40}; border-radius:4pt;"></div>
|
||||
</div>
|
||||
<p style="font-size:15pt; font-weight:bold; color:${primary-40}; margin:0; width:48pt; text-align:right; line-height:1;">38%</p>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; align-items:center; gap:12pt;">
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:100pt; line-height:1.3; white-space:nowrap;">Product D</p>
|
||||
<div style="flex:1; height:24pt; background:${primary-10}; border-radius:4pt;">
|
||||
<div style="height:24pt; width:22%; background:${primary-20}; border-radius:4pt;"></div>
|
||||
</div>
|
||||
<p style="font-size:15pt; font-weight:bold; color:${primary-20}; margin:0; width:48pt; text-align:right; line-height:1;">22%</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
**Variation**: Use `${accent}` for the highlighted/top bar to draw attention.
|
||||
|
||||
---
|
||||
|
||||
<a id="content-stacked-bars"></a>
|
||||
### content-stacked-bars — Stacked Progress Bars
|
||||
|
||||
`data | medium | light | shadow`
|
||||
|
||||
Multi-dimension proportional data. Best for: budget allocation, resource distribution, composition analysis.
|
||||
|
||||
```html
|
||||
<body style="width:720pt; height:405pt; margin:0; padding:0; overflow:hidden;
|
||||
background-color:${background};
|
||||
font-family:'Microsoft YaHei',sans-serif;
|
||||
display:flex; flex-direction:column;">
|
||||
|
||||
<div style="width:720pt; height:56pt; background:${primary-90};
|
||||
display:flex; align-items:center; padding:0 48pt;">
|
||||
<h2 style="font-size:22pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1.25;">
|
||||
Budget Allocation by Department
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div style="flex:1; display:flex; flex-direction:column; justify-content:center; padding:0 48pt; gap:24pt;">
|
||||
|
||||
<div>
|
||||
<div style="display:flex; justify-content:space-between; margin-bottom:8pt;">
|
||||
<p style="font-size:15pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1.3;">Q1 2024</p>
|
||||
<p style="font-size:13pt; color:${primary-40}; margin:0; line-height:1;">$2.4M Total</p>
|
||||
</div>
|
||||
<div style="display:flex; height:32pt; border-radius:6pt; overflow:hidden;">
|
||||
<div style="width:35%; background:${primary-80};"></div>
|
||||
<div style="width:25%; background:${primary-60};"></div>
|
||||
<div style="width:20%; background:${primary-40};"></div>
|
||||
<div style="width:12%; background:${accent};"></div>
|
||||
<div style="width:8%; background:${primary-20};"></div>
|
||||
</div>
|
||||
<div style="display:flex; gap:16pt; margin-top:8pt;">
|
||||
<div style="display:flex; align-items:center; gap:4pt;">
|
||||
<div style="width:8pt; height:8pt; background:${primary-80}; border-radius:2pt;"></div>
|
||||
<p style="font-size:11pt; color:${primary-60}; margin:0; line-height:1;">R&D 35%</p>
|
||||
</div>
|
||||
<div style="display:flex; align-items:center; gap:4pt;">
|
||||
<div style="width:8pt; height:8pt; background:${primary-60}; border-radius:2pt;"></div>
|
||||
<p style="font-size:11pt; color:${primary-60}; margin:0; line-height:1;">Marketing 25%</p>
|
||||
</div>
|
||||
<div style="display:flex; align-items:center; gap:4pt;">
|
||||
<div style="width:8pt; height:8pt; background:${primary-40}; border-radius:2pt;"></div>
|
||||
<p style="font-size:11pt; color:${primary-60}; margin:0; line-height:1;">Sales 20%</p>
|
||||
</div>
|
||||
<div style="display:flex; align-items:center; gap:4pt;">
|
||||
<div style="width:8pt; height:8pt; background:${accent}; border-radius:2pt;"></div>
|
||||
<p style="font-size:11pt; color:${primary-60}; margin:0; line-height:1;">Ops 12%</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div style="display:flex; justify-content:space-between; margin-bottom:8pt;">
|
||||
<p style="font-size:15pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1.3;">Q2 2024</p>
|
||||
<p style="font-size:13pt; color:${primary-40}; margin:0; line-height:1;">$2.8M Total</p>
|
||||
</div>
|
||||
<div style="display:flex; height:32pt; border-radius:6pt; overflow:hidden;">
|
||||
<div style="width:40%; background:${primary-80};"></div>
|
||||
<div style="width:22%; background:${primary-60};"></div>
|
||||
<div style="width:18%; background:${primary-40};"></div>
|
||||
<div style="width:10%; background:${accent};"></div>
|
||||
<div style="width:10%; background:${primary-20};"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<a id="content-data-table"></a>
|
||||
### content-data-table — Structured Data Table
|
||||
|
||||
`data | medium | light | none`
|
||||
|
||||
Multi-row multi-column structured data. Best for: quarterly reports, feature comparisons, competitive analysis.
|
||||
|
||||
```html
|
||||
<body style="width:720pt; height:405pt; margin:0; padding:0; overflow:hidden;
|
||||
background-color:${background};
|
||||
font-family:'Microsoft YaHei',sans-serif;
|
||||
display:flex; flex-direction:column;">
|
||||
|
||||
<div style="width:720pt; height:56pt; background:${primary-90};
|
||||
display:flex; align-items:center; padding:0 48pt;">
|
||||
<h2 style="font-size:22pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1.25;">
|
||||
Quarterly Performance Summary
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div style="flex:1; display:flex; flex-direction:column; justify-content:center; padding:0 48pt;">
|
||||
|
||||
<div style="display:flex; background:${primary-80}; border-radius:8pt 8pt 0 0; padding:12pt 16pt;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; width:120pt; line-height:1.3;">Department</p>
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; width:120pt; line-height:1.3; text-align:right;">Q1</p>
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; width:120pt; line-height:1.3; text-align:right;">Q2</p>
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; width:120pt; line-height:1.3; text-align:right;">Q3</p>
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; width:112pt; line-height:1.3; text-align:right;">Q4</p>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; background:${surface}; padding:10pt 16pt; border-left:1pt solid ${primary-10}; border-right:1pt solid ${primary-10};">
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:120pt; line-height:1.3;">Engineering</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; width:120pt; line-height:1.3; text-align:right;">$1.2M</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; width:120pt; line-height:1.3; text-align:right;">$1.5M</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; width:120pt; line-height:1.3; text-align:right;">$1.8M</p>
|
||||
<p style="font-size:13pt; color:${accent}; margin:0; width:112pt; line-height:1.3; text-align:right; font-weight:bold;">$2.1M</p>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; background:${background}; padding:10pt 16pt; border-left:1pt solid ${primary-10}; border-right:1pt solid ${primary-10};">
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:120pt; line-height:1.3;">Marketing</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; width:120pt; line-height:1.3; text-align:right;">$800K</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; width:120pt; line-height:1.3; text-align:right;">$920K</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; width:120pt; line-height:1.3; text-align:right;">$1.1M</p>
|
||||
<p style="font-size:13pt; color:${accent}; margin:0; width:112pt; line-height:1.3; text-align:right; font-weight:bold;">$1.3M</p>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; background:${surface}; padding:10pt 16pt; border-left:1pt solid ${primary-10}; border-right:1pt solid ${primary-10};">
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:120pt; line-height:1.3;">Sales</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; width:120pt; line-height:1.3; text-align:right;">$2.0M</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; width:120pt; line-height:1.3; text-align:right;">$2.3M</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; width:120pt; line-height:1.3; text-align:right;">$2.5M</p>
|
||||
<p style="font-size:13pt; color:${accent}; margin:0; width:112pt; line-height:1.3; text-align:right; font-weight:bold;">$2.8M</p>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; background:${primary-10}; padding:10pt 16pt; border-radius:0 0 8pt 8pt;">
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:120pt; line-height:1.3; font-weight:bold;">Total</p>
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:120pt; line-height:1.3; text-align:right; font-weight:bold;">$4.0M</p>
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:120pt; line-height:1.3; text-align:right; font-weight:bold;">$4.7M</p>
|
||||
<p style="font-size:13pt; color:${primary-80}; margin:0; width:120pt; line-height:1.3; text-align:right; font-weight:bold;">$5.4M</p>
|
||||
<p style="font-size:13pt; color:${accent}; margin:0; width:112pt; line-height:1.3; text-align:right; font-weight:bold;">$6.2M</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<a id="content-quadrant-matrix"></a>
|
||||
### content-quadrant-matrix — 2x2 Quadrant Matrix
|
||||
|
||||
`data | medium | light | none`
|
||||
|
||||
Two-axis classification framework. Best for: BCG matrix, priority matrix, SWOT, evaluation frameworks.
|
||||
|
||||
```html
|
||||
<body style="width:720pt; height:405pt; margin:0; padding:0; overflow:hidden;
|
||||
background-color:${background};
|
||||
font-family:'Microsoft YaHei',sans-serif;
|
||||
display:flex; flex-direction:column;">
|
||||
|
||||
<div style="width:720pt; height:56pt; background:${primary-90};
|
||||
display:flex; align-items:center; padding:0 48pt;">
|
||||
<h2 style="font-size:22pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1.25;">
|
||||
Priority Matrix
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div style="flex:1; display:flex; padding:8pt 48pt 0 48pt;">
|
||||
|
||||
<div style="width:24pt; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:9pt; color:${primary-40}; margin:0; writing-mode:vertical-rl; transform:rotate(180deg); text-align:center; line-height:1.2;">Impact</p>
|
||||
</div>
|
||||
|
||||
<div style="flex:1; display:flex; flex-direction:column;">
|
||||
|
||||
<div style="display:flex; gap:16pt; margin-bottom:16pt;">
|
||||
<div style="width:296pt; flex-shrink:0; border-radius:10pt; padding:16pt 20pt; background:${primary-80};">
|
||||
<p style="font-size:18pt; font-weight:bold; color:${on-dark}; margin:0 0 6pt 0; line-height:1.25;">Do First</p>
|
||||
<p style="font-size:12pt; color:${on-dark-secondary}; margin:0; line-height:1.5;">High Impact + High Effort. Critical items requiring attention.</p>
|
||||
</div>
|
||||
<div style="width:296pt; flex-shrink:0; border-radius:10pt; padding:16pt 20pt; background:${surface}; border:1.5pt solid ${primary-20};">
|
||||
<p style="font-size:18pt; font-weight:bold; color:${primary-80}; margin:0 0 6pt 0; line-height:1.25;">Quick Wins</p>
|
||||
<p style="font-size:12pt; color:${primary-60}; margin:0; line-height:1.5;">High Impact + Low Effort. Prioritize for maximum ROI.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; gap:16pt;">
|
||||
<div style="width:296pt; flex-shrink:0; border-radius:10pt; padding:16pt 20pt; border:1.5pt solid ${primary-20};">
|
||||
<p style="font-size:18pt; font-weight:bold; color:${primary-80}; margin:0 0 6pt 0; line-height:1.25;">Schedule</p>
|
||||
<p style="font-size:12pt; color:${primary-60}; margin:0; line-height:1.5;">Low Impact + High Effort. Plan for later.</p>
|
||||
</div>
|
||||
<div style="width:296pt; flex-shrink:0; border-radius:10pt; padding:16pt 20pt; background:${primary-90};">
|
||||
<p style="font-size:18pt; font-weight:bold; color:${on-dark}; margin:0 0 6pt 0; line-height:1.25;">Eliminate</p>
|
||||
<p style="font-size:12pt; color:${on-dark-secondary}; margin:0; line-height:1.5;">Low Impact + Low Effort. Drop these tasks.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:6pt;">
|
||||
<p style="font-size:9pt; font-weight:bold; color:${primary-40}; margin:0; text-align:center;">LOW Effort → HIGH</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<a id="content-funnel"></a>
|
||||
### content-funnel — Sales/Conversion Funnel
|
||||
|
||||
`data | medium | light | none`
|
||||
|
||||
Multi-stage progressive filtering. Best for: sales pipeline, conversion funnel, qualification process.
|
||||
|
||||
```html
|
||||
<body style="width:720pt; height:405pt; margin:0; padding:0; overflow:hidden;
|
||||
background-color:${background};
|
||||
font-family:'Microsoft YaHei',sans-serif;
|
||||
display:flex; flex-direction:column;">
|
||||
|
||||
<div style="width:720pt; height:56pt; background:${primary-90};
|
||||
display:flex; align-items:center; padding:0 48pt;">
|
||||
<h2 style="font-size:22pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1.25;">
|
||||
Sales Conversion Funnel
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div style="flex:1; display:flex; align-items:center; padding:0 48pt; gap:40pt;">
|
||||
|
||||
<div style="width:320pt; display:flex; flex-direction:column; align-items:center; gap:4pt;">
|
||||
<div style="width:280pt; height:36pt; background:${primary-80}; border-radius:6pt; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1;">Leads: 10,000</p>
|
||||
</div>
|
||||
<div style="width:230pt; height:36pt; background:${primary-60}; border-radius:6pt; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1;">Qualified: 6,500</p>
|
||||
</div>
|
||||
<div style="width:180pt; height:36pt; background:${primary-40}; border-radius:6pt; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1;">Proposals: 3,200</p>
|
||||
</div>
|
||||
<div style="width:130pt; height:36pt; background:${accent}; border-radius:6pt; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1;">Negotiation: 1,800</p>
|
||||
</div>
|
||||
<div style="width:80pt; height:36pt; background:${primary-80}; border-radius:6pt; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1;">Closed: 850</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="flex:1; display:flex; flex-direction:column; justify-content:center; gap:16pt;">
|
||||
<div style="background:${surface}; border-radius:8pt; padding:16pt; border-left:3pt solid ${accent};">
|
||||
<p style="font-size:32pt; font-weight:bold; color:${accent}; margin:0; line-height:1; white-space:nowrap;">8.5%</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:4pt 0 0 0; line-height:1.4;">Overall Conversion Rate</p>
|
||||
</div>
|
||||
<div style="background:${surface}; border-radius:8pt; padding:16pt;">
|
||||
<p style="font-size:32pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1; white-space:nowrap;">46%</p>
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:4pt 0 0 0; line-height:1.4;">Qualified to Proposal Rate</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<a id="content-before-after"></a>
|
||||
### content-before-after — Before vs After Comparison
|
||||
|
||||
`data | medium | light | none`
|
||||
|
||||
Side-by-side comparison panels. Best for: optimization results, before/after, pros/cons.
|
||||
|
||||
```html
|
||||
<body style="width:720pt; height:405pt; margin:0; padding:0; overflow:hidden;
|
||||
background-color:${background};
|
||||
font-family:'Microsoft YaHei',sans-serif;
|
||||
display:flex; flex-direction:column;">
|
||||
|
||||
<div style="width:720pt; height:56pt; background:${primary-90};
|
||||
display:flex; align-items:center; padding:0 48pt;">
|
||||
<h2 style="font-size:22pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1.25;">
|
||||
Before vs After Optimization
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div style="flex:1; display:flex; padding:16pt 48pt 0 48pt; gap:16pt;">
|
||||
|
||||
<!-- Before -->
|
||||
<div style="width:296pt; flex-shrink:0; background:${surface}; border-radius:10pt; padding:20pt 24pt;">
|
||||
<div style="display:flex; align-items:center; gap:8pt; margin-bottom:16pt;">
|
||||
<div style="width:28pt; height:28pt; border-radius:50%; background:${primary-40}; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; color:${on-dark}; margin:0; line-height:1; font-weight:bold;">B</p>
|
||||
</div>
|
||||
<p style="font-size:18pt; font-weight:bold; color:${primary-40}; margin:0; line-height:1.25;">Before</p>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; padding:8pt 0; border-bottom:1pt solid ${primary-10};">
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; line-height:1.5;">Load Time</p>
|
||||
<p style="font-size:13pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1.5;">4.2s</p>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; padding:8pt 0; border-bottom:1pt solid ${primary-10};">
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; line-height:1.5;">Bounce Rate</p>
|
||||
<p style="font-size:13pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1.5;">38%</p>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; padding:8pt 0;">
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; line-height:1.5;">Conversion</p>
|
||||
<p style="font-size:13pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1.5;">2.1%</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- After (accent border to highlight) -->
|
||||
<div style="width:296pt; flex-shrink:0; background:${surface}; border-radius:10pt; padding:20pt 24pt; border:2pt solid ${accent};">
|
||||
<div style="display:flex; align-items:center; gap:8pt; margin-bottom:16pt;">
|
||||
<div style="width:28pt; height:28pt; border-radius:50%; background:${accent}; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; color:${on-dark}; margin:0; line-height:1; font-weight:bold;">A</p>
|
||||
</div>
|
||||
<p style="font-size:18pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1.25;">After</p>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; padding:8pt 0; border-bottom:1pt solid ${primary-10};">
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; line-height:1.5;">Load Time</p>
|
||||
<p style="font-size:13pt; font-weight:bold; color:${accent}; margin:0; line-height:1.5;">1.8s</p>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; padding:8pt 0; border-bottom:1pt solid ${primary-10};">
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; line-height:1.5;">Bounce Rate</p>
|
||||
<p style="font-size:13pt; font-weight:bold; color:${accent}; margin:0; line-height:1.5;">22%</p>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; padding:8pt 0;">
|
||||
<p style="font-size:13pt; color:${primary-60}; margin:0; line-height:1.5;">Conversion</p>
|
||||
<p style="font-size:13pt; font-weight:bold; color:${accent}; margin:0; line-height:1.5;">4.7%</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<a id="content-dashboard"></a>
|
||||
### content-dashboard — Data Dashboard / KPI Grid
|
||||
|
||||
`data | medium | light | shadow`
|
||||
|
||||
Multi-metric overview. Best for: dashboards, weekly/monthly reports, KPI summaries.
|
||||
|
||||
```html
|
||||
<body style="width:720pt; height:405pt; margin:0; padding:0; overflow:hidden;
|
||||
background-color:${surface};
|
||||
font-family:'Microsoft YaHei',sans-serif;
|
||||
display:flex; flex-direction:column;">
|
||||
|
||||
<div style="width:720pt; height:56pt; background:${primary-90};
|
||||
display:flex; align-items:center; padding:0 48pt;">
|
||||
<h2 style="font-size:22pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1.25;">
|
||||
Monthly Performance Dashboard
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<!-- Row 1: 3 large stats -->
|
||||
<div style="display:flex; gap:16pt; padding:16pt 48pt 0 48pt;">
|
||||
<div style="width:192pt; flex-shrink:0; background:${surface-card}; border-radius:10pt; padding:20pt; box-shadow:0 3pt 10pt rgba(0,0,0,0.08); text-align:center;">
|
||||
<p style="font-size:40pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1; white-space:nowrap;">$4.2M</p>
|
||||
<p style="font-size:13pt; color:${primary-40}; margin:8pt 0 0 0; line-height:1.4;">Revenue</p>
|
||||
<p style="font-size:11pt; color:${accent}; margin:8pt 0 0 0; line-height:1; font-weight:bold;">+12.3% vs last month</p>
|
||||
</div>
|
||||
<div style="width:192pt; flex-shrink:0; background:${surface-card}; border-radius:10pt; padding:20pt; box-shadow:0 3pt 10pt rgba(0,0,0,0.08); text-align:center;">
|
||||
<p style="font-size:40pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1; white-space:nowrap;">2,847</p>
|
||||
<p style="font-size:13pt; color:${primary-40}; margin:8pt 0 0 0; line-height:1.4;">Active Users</p>
|
||||
<p style="font-size:11pt; color:${accent}; margin:8pt 0 0 0; line-height:1; font-weight:bold;">+8.7% vs last month</p>
|
||||
</div>
|
||||
<div style="width:192pt; flex-shrink:0; background:${surface-card}; border-radius:10pt; padding:20pt; box-shadow:0 3pt 10pt rgba(0,0,0,0.08); text-align:center;">
|
||||
<p style="font-size:40pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1; white-space:nowrap;">94.2%</p>
|
||||
<p style="font-size:13pt; color:${primary-40}; margin:8pt 0 0 0; line-height:1.4;">Uptime</p>
|
||||
<p style="font-size:11pt; color:${accent}; margin:8pt 0 0 0; line-height:1; font-weight:bold;">+0.3% vs last month</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 2: 4 smaller stats -->
|
||||
<div style="display:flex; gap:16pt; padding:16pt 48pt;">
|
||||
<div style="width:140pt; flex-shrink:0; background:${surface-card}; border-radius:8pt; padding:14pt; box-shadow:0 3pt 10pt rgba(0,0,0,0.08); text-align:center;">
|
||||
<p style="font-size:32pt; font-weight:bold; color:${primary-60}; margin:0; line-height:1; white-space:nowrap;">156</p>
|
||||
<p style="font-size:11pt; color:${primary-40}; margin:6pt 0 0 0; line-height:1.4;">New Signups</p>
|
||||
</div>
|
||||
<div style="width:140pt; flex-shrink:0; background:${surface-card}; border-radius:8pt; padding:14pt; box-shadow:0 3pt 10pt rgba(0,0,0,0.08); text-align:center;">
|
||||
<p style="font-size:32pt; font-weight:bold; color:${primary-60}; margin:0; line-height:1; white-space:nowrap;">$148</p>
|
||||
<p style="font-size:11pt; color:${primary-40}; margin:6pt 0 0 0; line-height:1.4;">Avg Revenue/User</p>
|
||||
</div>
|
||||
<div style="width:140pt; flex-shrink:0; background:${surface-card}; border-radius:8pt; padding:14pt; box-shadow:0 3pt 10pt rgba(0,0,0,0.08); text-align:center;">
|
||||
<p style="font-size:32pt; font-weight:bold; color:${primary-60}; margin:0; line-height:1; white-space:nowrap;">4.6</p>
|
||||
<p style="font-size:11pt; color:${primary-40}; margin:6pt 0 0 0; line-height:1.4;">NPS Score</p>
|
||||
</div>
|
||||
<div style="width:140pt; flex-shrink:0; background:${surface-card}; border-radius:8pt; padding:14pt; box-shadow:0 3pt 10pt rgba(0,0,0,0.08); text-align:center;">
|
||||
<p style="font-size:32pt; font-weight:bold; color:${primary-60}; margin:0; line-height:1; white-space:nowrap;">23ms</p>
|
||||
<p style="font-size:11pt; color:${primary-40}; margin:6pt 0 0 0; line-height:1.4;">Avg Response</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<a id="content-pyramid"></a>
|
||||
### content-pyramid — Pyramid / Layered Hierarchy
|
||||
|
||||
`data | medium | light | none`
|
||||
|
||||
Layered hierarchy. Best for: Maslow pyramid, org levels, tech stack layers, priority hierarchy.
|
||||
|
||||
```html
|
||||
<body style="width:720pt; height:405pt; margin:0; padding:0; overflow:hidden;
|
||||
background-color:${background};
|
||||
font-family:'Microsoft YaHei',sans-serif;
|
||||
display:flex; flex-direction:column;">
|
||||
|
||||
<div style="width:720pt; height:56pt; background:${primary-90};
|
||||
display:flex; align-items:center; padding:0 48pt;">
|
||||
<h2 style="font-size:22pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1.25;">
|
||||
Strategy Implementation Pyramid
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div style="flex:1; display:flex; align-items:center; padding:0 48pt; gap:32pt;">
|
||||
|
||||
<div style="width:360pt; display:flex; flex-direction:column; align-items:center; gap:6pt;">
|
||||
<div style="width:140pt; height:40pt; background:${primary-80}; border-radius:6pt; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1;">Vision & Mission</p>
|
||||
</div>
|
||||
<div style="width:200pt; height:40pt; background:${primary-60}; border-radius:6pt; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1;">Strategic Objectives</p>
|
||||
</div>
|
||||
<div style="width:260pt; height:40pt; background:${primary-40}; border-radius:6pt; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${on-dark}; margin:0; line-height:1;">Tactical Plans & Programs</p>
|
||||
</div>
|
||||
<div style="width:320pt; height:40pt; background:${primary-20}; border-radius:6pt; display:flex; align-items:center; justify-content:center;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${primary-80}; margin:0; line-height:1;">Operations & Daily Execution</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="flex:1; display:flex; flex-direction:column; justify-content:center; gap:20pt;">
|
||||
<div style="border-left:2pt solid ${primary-80}; padding-left:12pt;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${primary-80}; margin:0 0 4pt 0; line-height:1.3;">Top Level</p>
|
||||
<p style="font-size:12pt; color:${primary-60}; margin:0; line-height:1.4;">Long-term direction, 5-10 year horizon</p>
|
||||
</div>
|
||||
<div style="border-left:2pt solid ${primary-60}; padding[left:12pt;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${primary-80}; margin:0 0 4pt 0; line-height:1.3;">Strategy</p>
|
||||
<p style="font-size:12pt; color:${primary-60}; margin:0; line-height:1.4;">3-5 year measurable targets</p>
|
||||
</div>
|
||||
<div style="border-left:2pt solid ${primary-40}; padding-left:12pt;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${primary-80}; margin:0 0 4pt 0; line-height:1.3;">Tactics</p>
|
||||
<p style="font-size:12pt; color:${primary-60}; margin:0; line-height:1.4;">1-2 year initiatives and projects</p>
|
||||
</div>
|
||||
<div style="border-left:2pt solid ${primary-20}; padding-left:12pt;">
|
||||
<p style="font-size:13pt; font-weight:bold; color:${primary-80}; margin:0 0 4pt 0; line-height:1.3;">Operations</p>
|
||||
<p style="font-size:12pt; color:${primary-60}; margin:0; line-height:1.4;">Daily tasks and short-term goals</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
211
skills/ppt/design-system.md
Executable file
211
skills/ppt/design-system.md
Executable file
@@ -0,0 +1,211 @@
|
||||
# Design System — PPT Creative Guidelines
|
||||
|
||||
This file provides **creative principles and a color system** for PPT design. Components and layouts should be inventive and diverse — these guidelines exist to ensure visual coherence, not to constrain creativity.
|
||||
|
||||
**Philosophy: Every slide is a design opportunity.** No two slides should look the same. Vary layouts, card treatments, backgrounds, typography weight, and whitespace aggressively. The audience should feel visual momentum, not repetition.
|
||||
|
||||
---
|
||||
|
||||
## 1. Color Scale System (Mandatory)
|
||||
|
||||
The color system is the **only hard constraint**. All colors used in the deck must derive from the chosen theme.
|
||||
|
||||
### 1.1 Color Scale Generation
|
||||
|
||||
Eight levels are derived from a single Primary color:
|
||||
|
||||
| Level | Lightness | Usage Examples |
|
||||
|-------|-----------|---------------|
|
||||
| `primary-100` | Darkest (L≈8%) | Dark backgrounds, dramatic pages |
|
||||
| `primary-90` | Dark (L≈15%) | Title bars, dark blocks, overlays |
|
||||
| `primary-80` | **Main color** | Headings, primary UI elements |
|
||||
| `primary-60` | Medium dark (L≈45%) | Subheadings, icons, secondary elements |
|
||||
| `primary-40` | Medium light (L≈60%) | Muted text, dividers, subtle accents |
|
||||
| `primary-20` | Light (L≈80%) | Borders, light decorations, tints |
|
||||
| `primary-10` | Very light (L≈90%) | Card fills, surface backgrounds |
|
||||
| `primary-5` | Near white (L≈96%) | Page tints, hover states, subtle surfaces |
|
||||
|
||||
**Generation method**: From the Primary HSL (H, S, L) — keep H constant; dark levels S×1.1, light levels S×0.3; assign L per the table.
|
||||
|
||||
### 1.2 Semantic Colors
|
||||
|
||||
| Token | Value | Purpose |
|
||||
|-------|-------|---------|
|
||||
| `background` | `#FFFFFF` | Default page base |
|
||||
| `surface` | `primary-5` | Tinted content area base |
|
||||
| `surface-card` | `#FFFFFF` | Card base (floats above surface) |
|
||||
| `text-primary` | `primary-80` | Primary text |
|
||||
| `text-secondary` | `primary-60` | Secondary text |
|
||||
| `text-muted` | `primary-40` | Annotations, footnotes |
|
||||
| `on-dark` | `#FFFFFF` | Text on dark backgrounds |
|
||||
| `on-dark-secondary` | `rgba(255,255,255,0.7)` | Secondary text on dark backgrounds |
|
||||
| `border` | `primary-10` | Dividers, borders |
|
||||
| `accent` | Defined by theme | Highlight color |
|
||||
| `on-accent` | `#FFFFFF` | Text on accent color |
|
||||
|
||||
### 1.3 Color Rules
|
||||
|
||||
- **All grays must derive from the primary color scale** — no arbitrary `#666`, `#999`, `#DDD`
|
||||
- **Text on dark areas must use `on-dark`** (#FFFFFF) — never use light primary tints on dark backgrounds
|
||||
- **Accent color area**: ≤15% on standard pages; up to 40% on emphasis/transition pages
|
||||
- **Saturation limit**: Accent colors should have HSL saturation ≤ 65% for most themes. High-energy themes (Deep Mineral, Ember, Mono) may use S ≤ 75% to preserve their intended vibrancy. Colors above S=80% look garish on projected slides. The theme presets already comply; if creating custom colors, check saturation.
|
||||
- **Large color blocks** (>15% of page area): reduce saturation further (S ≤ 50%) to avoid visual fatigue. Use higher saturation only for small accents (bars, icons, small badges).
|
||||
|
||||
---
|
||||
|
||||
## 2. Creative Principles (Guidelines, Not Rules)
|
||||
|
||||
These are high-level design intentions. Interpret them freely.
|
||||
|
||||
### 2.1 Visual Diversity
|
||||
|
||||
- **No two adjacent slides should share the same layout, background treatment, or card style.** This is the single most important principle.
|
||||
- Aim for **5+ distinct layout structures** across a deck (split columns, grids, single-focus, full-bleed, asymmetric, timeline, staggered, etc.)
|
||||
- Aim for **3+ card styles** (shadow float, outline, solid fill, gradient, frosted glass, tag-style, image-backed, borderless, etc.)
|
||||
- Aim for **3+ background treatments** (pure white, tinted surface, dark full-bleed, photo + mask, gradient, diagonal split, corner decoration, color band, etc.)
|
||||
|
||||
### 2.1.1 Deck-Wide Consistency Rules
|
||||
|
||||
**What MUST stay uniform across the entire deck** (changing these = unprofessional):
|
||||
- Body text font and font size (e.g., always 15pt Microsoft YaHei)
|
||||
- Page left/right margins (e.g., always 48pt)
|
||||
- Primary color palette (same theme throughout)
|
||||
- Accent color (same accent variant throughout, or intentional A/B mixing as documented)
|
||||
|
||||
**What SHOULD vary across slides** (sameness = monotony):
|
||||
- Layout structure (grid, split, list, focus, timeline, etc.)
|
||||
- Background treatment (white, surface, dark, photo, gradient)
|
||||
- Card style (shadow, outline, solid, accent-bar, dark card)
|
||||
- Title bar style (dark bar, accent bar, underline, inline title, vertical band)
|
||||
- Decorative elements (accent bars, shapes, circles, dot patterns)
|
||||
|
||||
**The boundary is clear: base typography and spacing = consistent; visual composition = diverse.**
|
||||
|
||||
### 2.2 Intentional vs Accidental Whitespace
|
||||
|
||||
Not all whitespace is bad. The key is **intent**.
|
||||
|
||||
**Intentional whitespace (good — preserve it):**
|
||||
- KPI / big-number pages: Large number centered with breathing room → dramatic focus
|
||||
- Quote / pullout pages: Single sentence with generous margins → elegant emphasis
|
||||
- Photo + caption pages: Image dominates, text is minimal → visual storytelling
|
||||
- Title / divider pages: Bold text with open space → transition signal
|
||||
|
||||
**Accidental whitespace (bad — fix it):**
|
||||
- Bullet list with 3 items occupying only 1/3 of the slide → expand or add visuals
|
||||
- Card grid with small cards clustered at the top, bottom 60% empty → enlarge cards, increase padding
|
||||
- Text block in the upper-left corner with nothing else on the page → redistribute content
|
||||
|
||||
**Rule of thumb**: If the whitespace makes the slide feel "unfinished" or "forgot to add content," it's accidental. If it makes the slide feel "clean" or "focused," it's intentional.
|
||||
|
||||
### 2.3 Visual Rhythm
|
||||
|
||||
- Alternate between high-density and low-density pages
|
||||
- Insert a "rhythm breaker" every 3-4 slides — a page that looks dramatically different (full-bleed dark, photo overlay, large single quote, bold color block)
|
||||
- Cover and closing page should echo each other in color or mood
|
||||
- **Vary the page header treatment** — don't use the same dark title bar on every slide. Alternatives:
|
||||
- Accent-colored bar (e.g., `background:${accent}`)
|
||||
- Transparent header with large colored text and a bottom divider line
|
||||
- No header bar at all — use oversized inline heading text
|
||||
- Left-side vertical color band instead of top horizontal bar
|
||||
- Gradient header (dark-to-transparent from top)
|
||||
|
||||
### 2.4 Typography
|
||||
|
||||
- **Hierarchy is king**: Headings should be visually distinct from body text through size, weight, and/or color
|
||||
- Body text should be readable at projection distance — don't go below ~13pt
|
||||
- Let type breathe — generous line-height makes everything feel more designed
|
||||
- KPI / hero numbers should be oversized and bold to create a focal point
|
||||
- Prefer cutting content over shrinking fonts — only when a slide is already well-filled and overflow is imminent; never cut content preemptively
|
||||
|
||||
### 2.5 Spacing & Layout
|
||||
|
||||
- Use consistent margins across the deck (recommended: 48pt left/right, 40pt top, ≥36pt bottom safe zone)
|
||||
- Content should be **vertically balanced** — not crammed at the top with empty space below
|
||||
- Give elements room — tight packing reads as "cheap"
|
||||
- Fixed widths for multi-column cards prevent uneven stretching
|
||||
|
||||
### 2.6 Decoration & Visual Interest
|
||||
|
||||
- Every content slide should have **at least one non-text visual element** — accent bar, color block, photo, shape, large number, chart
|
||||
- Decorative elements (circles, bars, geometric shapes, dot patterns) add polish and visual rhythm
|
||||
- Decoration should support the content, never compete with it
|
||||
|
||||
### 2.7 Imagery
|
||||
|
||||
- Real photographs dramatically elevate quality — use them on covers, dividers, and visual pages
|
||||
- Background images need a semi-transparent mask overlay for text readability
|
||||
- Image tone (warm/cool) should match the theme atmosphere
|
||||
|
||||
---
|
||||
|
||||
## 3. Technical Constraints (html2pptx Engine)
|
||||
|
||||
These are **rendering engine limitations**, not design choices. Violating them causes broken output.
|
||||
|
||||
| Constraint | Reason |
|
||||
|-----------|--------|
|
||||
| Slide canvas: 720×405pt (16:9) | Fixed PPTX dimensions |
|
||||
| `background-image` only works on `<body>`, not on `<div>` | html2pptx engine limitation |
|
||||
| Don't use `flex-wrap` for multi-row grids — use separate flex containers per row | html2pptx drops wrapped rows |
|
||||
| Don't use negative margins | Causes text stacking in PPT (elements become independent text boxes) |
|
||||
| `font-family` must include a CJK font name | Required for correct font mapping |
|
||||
| Images must be local file paths, not URLs | html2pptx reads from filesystem |
|
||||
| Content that exceeds 405pt height will overflow — split into multiple slides instead | No scroll in PPT |
|
||||
| Multi-column equal-width cards: use explicit `width` + `flex-shrink:0`, not `flex:1` | Prevents uneven stretching |
|
||||
| Titles and short labels: use `white-space:nowrap` | Prevents unexpected line breaks in conversion |
|
||||
|
||||
---
|
||||
|
||||
## 4. Quick Reference
|
||||
|
||||
### Recommended Font Size Range
|
||||
|
||||
| Role | Suggested Size | Weight |
|
||||
|------|---------------|--------|
|
||||
| Display / decorative number (ghost) | 80–100pt | Bold |
|
||||
| Hero focal metric (single-stat page) | 56–88pt | Bold |
|
||||
| Hero / cover title | 40–48pt | Bold |
|
||||
| KPI dashboard numbers | 36–48pt | Bold |
|
||||
| Section title | 28–34pt | Bold |
|
||||
| Page title (in title bar) | 26–30pt | Bold |
|
||||
| Card / sub heading | 20–24pt | Bold |
|
||||
| Body text | 14–16pt | Normal |
|
||||
| Annotations / footnotes | 12–13pt | Normal |
|
||||
| Captions / tiny labels | 10–12pt | Normal |
|
||||
| Tag / chip label | 10–11pt | Normal |
|
||||
|
||||
**Ghost number technique**: Large decorative numbers (80–100pt) at very low opacity (`color:rgba(255,255,255,0.05)` on dark backgrounds, or `color:rgba(0,0,0,0.04)` on light) add visual depth without competing with readable content. Use as background layer behind chapter numbers, inside TOC cards, or behind section titles.
|
||||
|
||||
### Common Spacing Values
|
||||
|
||||
| Usage | Suggested |
|
||||
|-------|-----------|
|
||||
| Page left/right margins | 48pt |
|
||||
| Page top margin | 40pt |
|
||||
| Bottom safe zone | ≥36pt |
|
||||
| Between heading and body | 8-16pt |
|
||||
| Between cards | 12-20pt |
|
||||
| Card internal padding | 16-24pt |
|
||||
|
||||
### Width Reference (720pt total)
|
||||
|
||||
| Layout | Approximate Column Widths |
|
||||
|--------|--------------------------|
|
||||
| Full width (with margins) | ~624pt |
|
||||
| Two columns | ~296pt each (16pt gap) |
|
||||
| Three columns | ~192pt each (16pt×2 gaps) |
|
||||
| Four columns | ~140pt each (16pt×3 gaps) |
|
||||
|
||||
### Height Reference (405pt total)
|
||||
|
||||
| Component | Approximate Height |
|
||||
|-----------|--------------------|
|
||||
| Title bar | ~56pt |
|
||||
| Single text line (15pt body) | ~23pt |
|
||||
| KPI number line (40pt) | ~40pt |
|
||||
| Card padding (top+bottom) | ~32-48pt |
|
||||
|
||||
---
|
||||
|
||||
**Remember: This system gives you a coherent color palette and a few engine-level constraints. Everything else — layout invention, typography expression, decorative flair, card styling, background artistry — is yours to create freely. Make every slide count.**
|
||||
394
skills/ppt/html2pptx.md
Executable file
394
skills/ppt/html2pptx.md
Executable file
@@ -0,0 +1,394 @@
|
||||
# HTML to PowerPoint Guide
|
||||
|
||||
Convert HTML slides into PowerPoint presentations using the `html2pptx.js` library with accurate positioning.
|
||||
|
||||
---
|
||||
|
||||
## Creating HTML Slides
|
||||
|
||||
Each HTML slide must include the correct body dimensions:
|
||||
|
||||
### Layout Dimensions
|
||||
|
||||
- **16:9** (default): `width: 720pt; height: 405pt`
|
||||
- **4:3**: `width: 720pt; height: 540pt`
|
||||
- **16:10**: `width: 720pt; height: 450pt`
|
||||
|
||||
**CRITICAL — Prevent Overflow**:
|
||||
- `<body>` must set exact dimensions via inline style: `width: 720pt; height: 405pt; margin: 0; padding: 0; overflow: hidden;`
|
||||
- All content must fit within these boundaries. If content overflows, split into multiple slides
|
||||
- Maintain at least **36pt bottom margin** inside the body for safe spacing
|
||||
|
||||
**Fill the slide**: Content should occupy the available space well. Avoid designs where text clusters in the top third with the bottom two-thirds empty. Use generous font sizes, spacing, and visual elements to fill the canvas.
|
||||
|
||||
### Supported Elements
|
||||
|
||||
- `<p>`, `<h1>`-`<h6>` — Styled text
|
||||
- `<ul>`, `<ol>` — Lists (never use manual bullet symbols like bullet, -, *)
|
||||
- `<b>`, `<strong>`, `<i>`, `<em>`, `<u>` — Inline formatting
|
||||
- `<span>` — Inline formatting with CSS styles
|
||||
- `<br>` — Line breaks
|
||||
- `<div>` with bg/border — Becomes shapes
|
||||
- `<img>` — Images
|
||||
- `class="placeholder"` — Reserves space for charts (returns `{ id, x, y, w, h }`)
|
||||
|
||||
### Key Text Rules
|
||||
|
||||
**All text must be inside `<p>`, `<h1>`-`<h6>`, `<ul>`, or `<ol>` tags:**
|
||||
- ✅ `<div><p>Text here</p></div>`
|
||||
- ❌ `<div>Text here</div>` — **Silently ignored in PowerPoint**
|
||||
- ❌ `<span>Text here</span>` — **Silently ignored in PowerPoint**
|
||||
|
||||
**Never use manual bullet symbols (bullet, -, *, etc.)** — use `<ul>` or `<ol>` instead.
|
||||
|
||||
**v3 Smart Font Mapping (pass-through + safe fallback):**
|
||||
|
||||
html2pptx.js v3 no longer maps all fonts to the same one. Strategy:
|
||||
1. **PPT-safe fonts** (Corbel, Arial, SimHei, Palatino Linotype, etc. 40+) → **Pass through directly**
|
||||
2. **macOS-exclusive fonts** (PingFang SC, Hiragino Sans) → Mapped to cross-platform equivalents
|
||||
3. **Web fonts** (Roboto, Montserrat, Inter, etc. 40+) → Mapped to visually closest PPT-safe font
|
||||
4. **CSS generic names** (sans-serif/serif) → Corbel / Times New Roman
|
||||
5. **Unknown fonts** → CJK falls back to fontConfig.cjk; Latin passes through directly
|
||||
|
||||
**Write PPT font names directly in HTML**:
|
||||
```css
|
||||
font-family: "SimHei", "Microsoft YaHei", sans-serif; /* CJK heading */
|
||||
font-family: "Microsoft YaHei", sans-serif; /* CJK body */
|
||||
font-family: "Gill Sans MT", "Century Gothic", sans-serif; /* English heading */
|
||||
```
|
||||
|
||||
**fontConfig is still available** (as CJK/Latin ultimate fallback, optional):
|
||||
```javascript
|
||||
const fontConfig = { cjk: 'SimHei', latin: 'Gill Sans MT' };
|
||||
const result = await html2pptx('slide.html', pptx, { fontConfig });
|
||||
```
|
||||
|
||||
### Styles
|
||||
|
||||
- Body must use `display: flex; flex-direction: column;` — without it, multiple direct children stack horizontally
|
||||
- **Do not use `flex-wrap`** — multi-row layouts must use separate flex containers (html2pptx renderer may lose wrapped content)
|
||||
- `<span>` supports: `font-weight`, `font-style`, `text-decoration`, `color`, `font-size`, `letter-spacing`; color accepts `rgba()` for transparency
|
||||
- `<span>` does NOT support: `margin`, `padding`
|
||||
- `text-transform: uppercase / lowercase / capitalize` works on all text elements and `<span>`
|
||||
- **Rotated text**: `transform: rotate(-30deg)` or `writing-mode: vertical-rl / vertical-lr`
|
||||
- Use hex colors with `#` prefix in CSS; use `text-align` for alignment hints
|
||||
|
||||
### Shape Styles (DIV elements only)
|
||||
|
||||
Backgrounds, borders, and shadows **only work on `<div>`**, not on text elements.
|
||||
|
||||
- **Background**: `background-color` on `<div>` only
|
||||
- **Border**: uniform (`border: 2px solid #333`) or partial (`border-left`, `border-right`, etc.)
|
||||
- **Border radius**: `border-radius: 8pt` for rounded corners; `50%` for circle; percentages relative to smaller dimension
|
||||
- **Box shadow**: outer shadows only — `box-shadow: 2px 2px 8px rgba(0,0,0,0.3)`; inset shadows ignored
|
||||
|
||||
### Typography Guidelines
|
||||
|
||||
Choose font sizes that create clear visual hierarchy. Refer to `design-system.md` for suggested ranges.
|
||||
|
||||
**Minimum font size**: Don't go below ~11pt for any text. Prefer ≥13pt for body text.
|
||||
**Hierarchy principle**: Headings should be noticeably larger and bolder than body text.
|
||||
|
||||
### Spacing Guidelines
|
||||
|
||||
Use consistent spacing throughout the deck. Refer to `design-system.md` for suggested values. Key principles:
|
||||
- Page margins: ~48pt left/right, ~40pt top, ≥36pt bottom safe zone
|
||||
- Be generous with whitespace — but fill the slide; avoid large empty areas
|
||||
|
||||
### Color Rules
|
||||
|
||||
**All colors must come from the current theme's color scale.** Arbitrary grays unrelated to the primary color are forbidden.
|
||||
|
||||
After selecting a theme from `themes.md`, use that theme's complete color scale.
|
||||
|
||||
### Image Rules (MANDATORY for decks with 6+ slides)
|
||||
|
||||
Every deck with 6+ slides must include real photographs. Images create visual richness and professional quality.
|
||||
|
||||
**Image sourcing priority**:
|
||||
1. **Unsplash** (free, high quality) — use theme's **Image Keywords** from `themes.md`:
|
||||
```bash
|
||||
curl -L "https://source.unsplash.com/1920x1080/?keyword1,keyword2" -o cover-bg.jpg
|
||||
```
|
||||
2. **User-provided images** — local files
|
||||
3. **Gradient fallback** — if Unsplash fails, generate gradient PNG via Sharp
|
||||
|
||||
**Image usage in HTML**:
|
||||
- **Page background**: `<body style="background-image:url('bg.jpg'); background-size:cover;">`
|
||||
- **Inline image**: `<img src="photo.jpg" style="width:296pt; height:220pt; object-fit:cover;">`
|
||||
- **DIV background-image is NOT supported** — only body background-image works
|
||||
|
||||
**Mask overlay for photo backgrounds**:
|
||||
```html
|
||||
<!-- Background photo on body -->
|
||||
<body style="width:720pt; height:405pt; margin:0; padding:0; overflow:hidden;
|
||||
background-image:url('cover-bg.jpg'); background-size:cover;
|
||||
font-family:'PingFang SC','Microsoft YaHei',sans-serif;
|
||||
display:flex; flex-direction:column;">
|
||||
<!-- Semi-transparent mask layer (use theme's Mask Color from themes.md) -->
|
||||
<div style="position:absolute; top:0; left:0; width:720pt; height:405pt;
|
||||
background-color:rgba(18,32,64,0.75);"></div>
|
||||
<!-- Content layer above mask -->
|
||||
<div style="position:relative; z-index:1; flex:1; display:flex; flex-direction:column;
|
||||
justify-content:center; align-items:center;">
|
||||
<h1 style="font-size:34pt; font-weight:bold; color:#FFFFFF;">Title Here</h1>
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
**Mask opacity guide**:
|
||||
- Dark mask (cover/divider): opacity 0.70–0.85 — text clearly readable
|
||||
- Light mask (content): opacity 0.60–0.80 — retains image visibility
|
||||
|
||||
### Icons & Gradients
|
||||
|
||||
- **CRITICAL: Never use CSS gradients** — pre-rasterize as PNG with Sharp
|
||||
- **Icons**: rasterize react-icons SVG to PNG; **Gradients**: rasterize SVG to PNG background
|
||||
|
||||
```javascript
|
||||
// Icon to PNG
|
||||
const { FaHome } = require('react-icons/fa');
|
||||
const svgString = ReactDOMServer.renderToStaticMarkup(
|
||||
React.createElement(FaHome, { color: '#4472C4', size: '256' })
|
||||
);
|
||||
await sharp(Buffer.from(svgString)).png().toFile('home-icon.png');
|
||||
// In HTML: <img src="home-icon.png" style="width:40pt;height:40pt;">
|
||||
|
||||
// Gradient to PNG
|
||||
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="562.5">
|
||||
<defs><linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#COLOR1"/>
|
||||
<stop offset="100%" style="stop-color:#COLOR2"/>
|
||||
</linearGradient></defs>
|
||||
<rect width="100%" height="100%" fill="url(#g)"/>
|
||||
</svg>`;
|
||||
await sharp(Buffer.from(svg)).png().toFile('gradient-bg.png');
|
||||
// In HTML: <body style="background-image: url('gradient-bg.png');">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Using the html2pptx Library
|
||||
|
||||
### Dependencies
|
||||
|
||||
Globally installed: `pptxgenjs`, `playwright`, `sharp`
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```javascript
|
||||
const pptxgen = require('pptxgenjs');
|
||||
const html2pptx = require('./html2pptx');
|
||||
|
||||
const pptx = new pptxgen();
|
||||
pptx.layout = 'LAYOUT_16x9'; // Must match HTML body dimensions
|
||||
|
||||
// Optional: custom font configuration (from themes.md)
|
||||
const fontConfig = { cjk: 'Microsoft YaHei', latin: 'Gill Sans MT' };
|
||||
|
||||
const { slide, placeholders, warnings } = await html2pptx('slide1.html', pptx, { fontConfig });
|
||||
|
||||
// If warnings is non-empty, fix the HTML and re-run
|
||||
if (warnings.length > 0) {
|
||||
console.error('Fix overflow issues before saving:', warnings);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (placeholders.length > 0) {
|
||||
slide.addChart(pptx.charts.LINE, chartData, placeholders[0]);
|
||||
}
|
||||
|
||||
await pptx.writeFile('output.pptx');
|
||||
```
|
||||
|
||||
### API Reference
|
||||
|
||||
```javascript
|
||||
await html2pptx(htmlFile, pres, options)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `htmlFile` (string): Path to HTML file
|
||||
- `pres` (pptxgen): PptxGenJS instance with layout set
|
||||
- `options.tmpDir` (string): Temp dir (default: `process.env.TMPDIR || '/tmp'`)
|
||||
- `options.slide` (object): Existing slide to reuse
|
||||
- `options.fontConfig` (object): Font mapping config `{ cjk: 'Microsoft YaHei', latin: 'Corbel' }`
|
||||
|
||||
**Returns:**
|
||||
```javascript
|
||||
{
|
||||
slide: pptxgenSlide,
|
||||
placeholders: [{ id, x, y, w, h }, ...],
|
||||
warnings: string[] // Overflow and layout suggestions; empty if none
|
||||
}
|
||||
```
|
||||
|
||||
### Validation
|
||||
|
||||
**Blocking errors** (conversion aborted):
|
||||
1. CSS gradients — must be pre-rasterized as PNG
|
||||
2. Backgrounds/borders/shadows on text elements (`<p>`, `<h1>`-`<h6>`, etc.)
|
||||
3. Unwrapped text directly in `<div>`
|
||||
4. Manual bullet symbols in text elements
|
||||
5. Font size below 11pt
|
||||
|
||||
**Non-blocking warnings** (conversion succeeds, returned in `warnings`):
|
||||
1. Element out of bounds — extends beyond slide edges
|
||||
2. Vertical imbalance — content clusters in top 55%
|
||||
3. Text overlap — text elements overlap each other
|
||||
4. Character density — exceeds 350 CJK / 550 Latin chars
|
||||
5. Body-level overflow
|
||||
|
||||
**Blocking issues** (overflow, font < 11pt) must be fixed. **Non-blocking warnings** are suggestions — use your judgment.
|
||||
|
||||
### Visual Quality Check
|
||||
|
||||
After generating all slides, do a quick quality scan:
|
||||
- Is there visual variety across the deck? (different layouts, backgrounds, card styles)
|
||||
- Do real photographs appear? (at least on cover + 1 other slide for 6+ slide decks)
|
||||
- Is there at least one dramatic "rhythm breaker" page?
|
||||
- Does every slide have a clear visual focal point?
|
||||
|
||||
### Working with Placeholders
|
||||
|
||||
```javascript
|
||||
const { slide, placeholders } = await html2pptx('slide.html', pptx);
|
||||
slide.addChart(pptx.charts.BAR, data, placeholders[0]);
|
||||
|
||||
// By ID:
|
||||
const chartArea = placeholders.find(p => p.id === 'chart-area');
|
||||
slide.addChart(pptx.charts.LINE, data, chartArea);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Using PptxGenJS
|
||||
|
||||
### Critical Rules
|
||||
|
||||
**NEVER use `#` prefix** with hex colors in PptxGenJS — causes file corruption.
|
||||
- ✅ `color: "FF0000"`, `fill: { color: "0066CC" }`
|
||||
- ❌ `color: "#FF0000"`
|
||||
|
||||
### Adding Images
|
||||
|
||||
```javascript
|
||||
const imgWidth = 1860, imgHeight = 1519;
|
||||
const h = 3, w = h * (imgWidth / imgHeight);
|
||||
slide.addImage({ path: "chart.png", x: (10 - w) / 2, y: 1.5, w, h });
|
||||
```
|
||||
|
||||
### Adding Shapes
|
||||
|
||||
```javascript
|
||||
slide.addShape(pptx.shapes.RECTANGLE, {
|
||||
x: 1, y: 1, w: 3, h: 2,
|
||||
fill: { color: "4472C4" },
|
||||
line: { color: "2E5DA8", width: 2 },
|
||||
rectRadius: 0.1 // rounded corners (ROUNDED_RECTANGLE only)
|
||||
});
|
||||
```
|
||||
|
||||
### Adding Charts
|
||||
|
||||
**Time Series Granularity:** `< 30 days` daily | `30-365 days` monthly | `> 365 days` yearly.
|
||||
|
||||
#### Bar Chart
|
||||
|
||||
```javascript
|
||||
slide.addChart(pptx.charts.BAR, [{
|
||||
name: "Sales 2024",
|
||||
labels: ["Q1", "Q2", "Q3", "Q4"],
|
||||
values: [4500, 5500, 6200, 7100]
|
||||
}], {
|
||||
...placeholders[0],
|
||||
barDir: 'col',
|
||||
showTitle: true, title: 'Quarterly Sales',
|
||||
showLegend: false,
|
||||
showCatAxisTitle: true, catAxisTitle: 'Quarter',
|
||||
showValAxisTitle: true, valAxisTitle: 'Sales ($000s)',
|
||||
valAxisMinVal: 0, valAxisMaxVal: 8000, valAxisMajorUnit: 2000,
|
||||
chartColors: ["4472C4"]
|
||||
});
|
||||
```
|
||||
|
||||
#### Line Chart
|
||||
|
||||
```javascript
|
||||
slide.addChart(pptx.charts.LINE, [{
|
||||
name: "Temperature",
|
||||
labels: ["Jan", "Feb", "Mar", "Apr"],
|
||||
values: [32, 35, 42, 55]
|
||||
}], {
|
||||
x: 1, y: 1, w: 8, h: 4,
|
||||
lineSize: 4, lineSmooth: true,
|
||||
showCatAxisTitle: true, catAxisTitle: 'Month',
|
||||
showValAxisTitle: true, valAxisTitle: 'Temp (F)',
|
||||
valAxisMinVal: 0, valAxisMaxVal: 60, valAxisMajorUnit: 20,
|
||||
chartColors: ["4472C4"]
|
||||
});
|
||||
```
|
||||
|
||||
#### Pie Chart
|
||||
|
||||
```javascript
|
||||
slide.addChart(pptx.charts.PIE, [{
|
||||
name: "Market Share",
|
||||
labels: ["Product A", "Product B", "Other"],
|
||||
values: [35, 45, 20]
|
||||
}], {
|
||||
x: 2, y: 1, w: 6, h: 4,
|
||||
showPercent: true, showLegend: true, legendPos: 'r',
|
||||
chartColors: ["4472C4", "ED7D31", "A5A5A5"]
|
||||
});
|
||||
```
|
||||
|
||||
#### Scatter Chart
|
||||
|
||||
```javascript
|
||||
slide.addChart(pptx.charts.SCATTER, [
|
||||
{ name: 'X-Axis', values: [10, 15, 20, 12, 18] },
|
||||
{ name: 'Series 1', values: [20, 25, 30] },
|
||||
{ name: 'Series 2', values: [18, 22] }
|
||||
], {
|
||||
x: 1, y: 1, w: 8, h: 4,
|
||||
lineSize: 0, lineDataSymbol: 'circle', lineDataSymbolSize: 6,
|
||||
showCatAxisTitle: true, catAxisTitle: 'X',
|
||||
showValAxisTitle: true, valAxisTitle: 'Y',
|
||||
chartColors: ["4472C4", "ED7D31"]
|
||||
});
|
||||
```
|
||||
|
||||
#### Multiple Series
|
||||
|
||||
```javascript
|
||||
slide.addChart(pptx.charts.LINE, [
|
||||
{ name: "Product A", labels: ["Q1","Q2","Q3","Q4"], values: [10,20,30,40] },
|
||||
{ name: "Product B", labels: ["Q1","Q2","Q3","Q4"], values: [15,25,20,35] }
|
||||
], { x: 1, y: 1, w: 8, h: 4, showCatAxisTitle: true, catAxisTitle: 'Quarter',
|
||||
showValAxisTitle: true, valAxisTitle: 'Revenue ($M)' });
|
||||
```
|
||||
|
||||
**Chart colors:** no `#` prefix; align with slide palette; strong contrast between adjacent series.
|
||||
|
||||
### Adding Tables
|
||||
|
||||
```javascript
|
||||
const tableData = [
|
||||
[
|
||||
{ text: "Product", options: { fill: { color: "4472C4" }, color: "FFFFFF", bold: true } },
|
||||
{ text: "Revenue", options: { fill: { color: "4472C4" }, color: "FFFFFF", bold: true } },
|
||||
{ text: "Growth", options: { fill: { color: "4472C4" }, color: "FFFFFF", bold: true } }
|
||||
],
|
||||
["Product A", "$50M", "+15%"],
|
||||
["Product B", "$35M", "+22%"]
|
||||
];
|
||||
slide.addTable(tableData, {
|
||||
x: 1, y: 1.5, w: 8, h: 2.5,
|
||||
colW: [3, 2.5, 2.5], rowH: [0.5, 0.6, 0.6],
|
||||
border: { pt: 1, color: "CCCCCC" },
|
||||
align: "center", valign: "middle", fontSize: 14
|
||||
});
|
||||
```
|
||||
|
||||
**Table options:** `x, y, w, h` | `colW` | `rowH` | `border: { pt, color }` | `fill` | `align` | `valign` | `fontSize` | `autoPage`
|
||||
427
skills/ppt/ooxml.md
Executable file
427
skills/ppt/ooxml.md
Executable file
@@ -0,0 +1,427 @@
|
||||
# Office Open XML Technical Reference for PowerPoint
|
||||
|
||||
**Important: Read this entire document before starting.** Critical XML schema rules and formatting requirements are covered throughout. Incorrect implementation can create invalid PPTX files that PowerPoint cannot open.
|
||||
|
||||
## Technical Guidelines
|
||||
|
||||
### Schema Compliance
|
||||
- **Element ordering in `<p:txBody>`**: `<a:bodyPr>`, `<a:lstStyle>`, `<a:p>`
|
||||
- **Whitespace**: Add `xml:space='preserve'` to `<a:t>` elements with leading/trailing spaces
|
||||
- **Unicode**: Escape characters in ASCII content: `"` becomes `“`
|
||||
- **Images**: Add to `ppt/media/`, reference in slide XML, set dimensions to fit slide bounds
|
||||
- **Relationships**: Update `ppt/slides/_rels/slideN.xml.rels` for each slide's resources
|
||||
- **Dirty attribute**: Add `dirty="0"` to `<a:rPr>` and `<a:endParaRPr>` elements to indicate clean state
|
||||
|
||||
## Presentation Structure
|
||||
|
||||
### Basic Slide Structure
|
||||
```xml
|
||||
<!-- ppt/slides/slide1.xml -->
|
||||
<p:sld>
|
||||
<p:cSld>
|
||||
<p:spTree>
|
||||
<p:nvGrpSpPr>...</p:nvGrpSpPr>
|
||||
<p:grpSpPr>...</p:grpSpPr>
|
||||
<!-- Shapes go here -->
|
||||
</p:spTree>
|
||||
</p:cSld>
|
||||
</p:sld>
|
||||
```
|
||||
|
||||
### Text Box / Shape with Text
|
||||
```xml
|
||||
<p:sp>
|
||||
<p:nvSpPr>
|
||||
<p:cNvPr id="2" name="Title"/>
|
||||
<p:cNvSpPr>
|
||||
<a:spLocks noGrp="1"/>
|
||||
</p:cNvSpPr>
|
||||
<p:nvPr>
|
||||
<p:ph type="ctrTitle"/>
|
||||
</p:nvPr>
|
||||
</p:nvSpPr>
|
||||
<p:spPr>
|
||||
<a:xfrm>
|
||||
<a:off x="838200" y="365125"/>
|
||||
<a:ext cx="7772400" cy="1470025"/>
|
||||
</a:xfrm>
|
||||
</p:spPr>
|
||||
<p:txBody>
|
||||
<a:bodyPr/>
|
||||
<a:lstStyle/>
|
||||
<a:p>
|
||||
<a:r>
|
||||
<a:t>Slide Title</a:t>
|
||||
</a:r>
|
||||
</a:p>
|
||||
</p:txBody>
|
||||
</p:sp>
|
||||
```
|
||||
|
||||
### Text Formatting
|
||||
```xml
|
||||
<!-- Bold -->
|
||||
<a:r>
|
||||
<a:rPr b="1"/>
|
||||
<a:t>Bold Text</a:t>
|
||||
</a:r>
|
||||
|
||||
<!-- Italic -->
|
||||
<a:r>
|
||||
<a:rPr i="1"/>
|
||||
<a:t>Italic Text</a:t>
|
||||
</a:r>
|
||||
|
||||
<!-- Underline -->
|
||||
<a:r>
|
||||
<a:rPr u="sng"/>
|
||||
<a:t>Underlined</a:t>
|
||||
</a:r>
|
||||
|
||||
<!-- Highlight -->
|
||||
<a:r>
|
||||
<a:rPr>
|
||||
<a:highlight>
|
||||
<a:srgbClr val="FFFF00"/>
|
||||
</a:highlight>
|
||||
</a:rPr>
|
||||
<a:t>Highlighted Text</a:t>
|
||||
</a:r>
|
||||
|
||||
<!-- Font and Size -->
|
||||
<a:r>
|
||||
<a:rPr sz="2400" typeface="Arial">
|
||||
<a:solidFill>
|
||||
<a:srgbClr val="FF0000"/>
|
||||
</a:solidFill>
|
||||
</a:rPr>
|
||||
<a:t>Colored Arial 24pt</a:t>
|
||||
</a:r>
|
||||
|
||||
<!-- Complete formatting example -->
|
||||
<a:r>
|
||||
<a:rPr lang="en-US" sz="1400" b="1" dirty="0">
|
||||
<a:solidFill>
|
||||
<a:srgbClr val="FAFAFA"/>
|
||||
</a:solidFill>
|
||||
</a:rPr>
|
||||
<a:t>Formatted text</a:t>
|
||||
</a:r>
|
||||
```
|
||||
|
||||
### Lists
|
||||
```xml
|
||||
<!-- Bullet list -->
|
||||
<a:p>
|
||||
<a:pPr lvl="0">
|
||||
<a:buChar char="•"/>
|
||||
</a:pPr>
|
||||
<a:r>
|
||||
<a:t>First bullet point</a:t>
|
||||
</a:r>
|
||||
</a:p>
|
||||
|
||||
<!-- Numbered list -->
|
||||
<a:p>
|
||||
<a:pPr lvl="0">
|
||||
<a:buAutoNum type="arabicPeriod"/>
|
||||
</a:pPr>
|
||||
<a:r>
|
||||
<a:t>First numbered item</a:t>
|
||||
</a:r>
|
||||
</a:p>
|
||||
|
||||
<!-- Second level indent -->
|
||||
<a:p>
|
||||
<a:pPr lvl="1">
|
||||
<a:buChar char="•"/>
|
||||
</a:pPr>
|
||||
<a:r>
|
||||
<a:t>Indented bullet</a:t>
|
||||
</a:r>
|
||||
</a:p>
|
||||
```
|
||||
|
||||
### Shapes
|
||||
```xml
|
||||
<!-- Rectangle -->
|
||||
<p:sp>
|
||||
<p:nvSpPr>
|
||||
<p:cNvPr id="3" name="Rectangle"/>
|
||||
<p:cNvSpPr/>
|
||||
<p:nvPr/>
|
||||
</p:nvSpPr>
|
||||
<p:spPr>
|
||||
<a:xfrm>
|
||||
<a:off x="1000000" y="1000000"/>
|
||||
<a:ext cx="3000000" cy="2000000"/>
|
||||
</a:xfrm>
|
||||
<a:prstGeom prst="rect">
|
||||
<a:avLst/>
|
||||
</a:prstGeom>
|
||||
<a:solidFill>
|
||||
<a:srgbClr val="FF0000"/>
|
||||
</a:solidFill>
|
||||
<a:ln w="25400">
|
||||
<a:solidFill>
|
||||
<a:srgbClr val="000000"/>
|
||||
</a:solidFill>
|
||||
</a:ln>
|
||||
</p:spPr>
|
||||
</p:sp>
|
||||
|
||||
<!-- Rounded Rectangle -->
|
||||
<p:sp>
|
||||
<p:spPr>
|
||||
<a:prstGeom prst="roundRect">
|
||||
<a:avLst/>
|
||||
</a:prstGeom>
|
||||
</p:spPr>
|
||||
</p:sp>
|
||||
|
||||
<!-- Circle/Ellipse -->
|
||||
<p:sp>
|
||||
<p:spPr>
|
||||
<a:prstGeom prst="ellipse">
|
||||
<a:avLst/>
|
||||
</a:prstGeom>
|
||||
</p:spPr>
|
||||
</p:sp>
|
||||
```
|
||||
|
||||
### Images
|
||||
```xml
|
||||
<p:pic>
|
||||
<p:nvPicPr>
|
||||
<p:cNvPr id="4" name="Picture">
|
||||
<a:hlinkClick r:id="" action="ppaction://media"/>
|
||||
</p:cNvPr>
|
||||
<p:cNvPicPr>
|
||||
<a:picLocks noChangeAspect="1"/>
|
||||
</p:cNvPicPr>
|
||||
<p:nvPr/>
|
||||
</p:nvPicPr>
|
||||
<p:blipFill>
|
||||
<a:blip r:embed="rId2"/>
|
||||
<a:stretch>
|
||||
<a:fillRect/>
|
||||
</a:stretch>
|
||||
</p:blipFill>
|
||||
<p:spPr>
|
||||
<a:xfrm>
|
||||
<a:off x="1000000" y="1000000"/>
|
||||
<a:ext cx="3000000" cy="2000000"/>
|
||||
</a:xfrm>
|
||||
<a:prstGeom prst="rect">
|
||||
<a:avLst/>
|
||||
</a:prstGeom>
|
||||
</p:spPr>
|
||||
</p:pic>
|
||||
```
|
||||
|
||||
### Tables
|
||||
```xml
|
||||
<p:graphicFrame>
|
||||
<p:nvGraphicFramePr>
|
||||
<p:cNvPr id="5" name="Table"/>
|
||||
<p:cNvGraphicFramePr>
|
||||
<a:graphicFrameLocks noGrp="1"/>
|
||||
</p:cNvGraphicFramePr>
|
||||
<p:nvPr/>
|
||||
</p:nvGraphicFramePr>
|
||||
<p:xfrm>
|
||||
<a:off x="1000000" y="1000000"/>
|
||||
<a:ext cx="6000000" cy="2000000"/>
|
||||
</p:xfrm>
|
||||
<a:graphic>
|
||||
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/table">
|
||||
<a:tbl>
|
||||
<a:tblGrid>
|
||||
<a:gridCol w="3000000"/>
|
||||
<a:gridCol w="3000000"/>
|
||||
</a:tblGrid>
|
||||
<a:tr h="500000">
|
||||
<a:tc>
|
||||
<a:txBody>
|
||||
<a:bodyPr/>
|
||||
<a:lstStyle/>
|
||||
<a:p>
|
||||
<a:r>
|
||||
<a:t>Cell 1</a:t>
|
||||
</a:r>
|
||||
</a:p>
|
||||
</a:txBody>
|
||||
</a:tc>
|
||||
<a:tc>
|
||||
<a:txBody>
|
||||
<a:bodyPr/>
|
||||
<a:lstStyle/>
|
||||
<a:p>
|
||||
<a:r>
|
||||
<a:t>Cell 2</a:t>
|
||||
</a:r>
|
||||
</a:p>
|
||||
</a:txBody>
|
||||
</a:tc>
|
||||
</a:tr>
|
||||
</a:tbl>
|
||||
</a:graphicData>
|
||||
</a:graphic>
|
||||
</p:graphicFrame>
|
||||
```
|
||||
|
||||
### Slide Layouts
|
||||
|
||||
```xml
|
||||
<!-- Title Slide Layout -->
|
||||
<p:sp>
|
||||
<p:nvSpPr>
|
||||
<p:nvPr>
|
||||
<p:ph type="ctrTitle"/>
|
||||
</p:nvPr>
|
||||
</p:nvSpPr>
|
||||
<!-- Title content -->
|
||||
</p:sp>
|
||||
|
||||
<p:sp>
|
||||
<p:nvSpPr>
|
||||
<p:nvPr>
|
||||
<p:ph type="subTitle" idx="1"/>
|
||||
</p:nvPr>
|
||||
</p:nvSpPr>
|
||||
<!-- Subtitle content -->
|
||||
</p:sp>
|
||||
|
||||
<!-- Content Slide Layout -->
|
||||
<p:sp>
|
||||
<p:nvSpPr>
|
||||
<p:nvPr>
|
||||
<p:ph type="title"/>
|
||||
</p:nvPr>
|
||||
</p:nvSpPr>
|
||||
<!-- Slide title -->
|
||||
</p:sp>
|
||||
|
||||
<p:sp>
|
||||
<p:nvSpPr>
|
||||
<p:nvPr>
|
||||
<p:ph type="body" idx="1"/>
|
||||
</p:nvPr>
|
||||
</p:nvSpPr>
|
||||
<!-- Content body -->
|
||||
</p:sp>
|
||||
```
|
||||
|
||||
## File Updates
|
||||
|
||||
When adding content, update these files:
|
||||
|
||||
**`ppt/_rels/presentation.xml.rels`:**
|
||||
```xml
|
||||
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" Target="slides/slide1.xml"/>
|
||||
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="slideMasters/slideMaster1.xml"/>
|
||||
```
|
||||
|
||||
**`ppt/slides/_rels/slide1.xml.rels`:**
|
||||
```xml
|
||||
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/>
|
||||
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/image1.png"/>
|
||||
```
|
||||
|
||||
**`[Content_Types].xml`:**
|
||||
```xml
|
||||
<Default Extension="png" ContentType="image/png"/>
|
||||
<Default Extension="jpg" ContentType="image/jpeg"/>
|
||||
<Override PartName="/ppt/slides/slide1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slide+xml"/>
|
||||
```
|
||||
|
||||
**`ppt/presentation.xml`:**
|
||||
```xml
|
||||
<p:sldIdLst>
|
||||
<p:sldId id="256" r:id="rId1"/>
|
||||
<p:sldId id="257" r:id="rId2"/>
|
||||
</p:sldIdLst>
|
||||
```
|
||||
|
||||
**`docProps/app.xml`:** Update slide count and statistics
|
||||
```xml
|
||||
<Slides>2</Slides>
|
||||
<Paragraphs>10</Paragraphs>
|
||||
<Words>50</Words>
|
||||
```
|
||||
|
||||
## Slide Operations
|
||||
|
||||
### Adding a New Slide
|
||||
When adding a slide to the end of the presentation:
|
||||
|
||||
1. **Create the slide file** (`ppt/slides/slideN.xml`)
|
||||
2. **Update `[Content_Types].xml`**: Add Override for the new slide
|
||||
3. **Update `ppt/_rels/presentation.xml.rels`**: Add relationship for the new slide
|
||||
4. **Update `ppt/presentation.xml`**: Add slide ID to `<p:sldIdLst>`
|
||||
5. **Create slide relationships** (`ppt/slides/_rels/slideN.xml.rels`) if needed
|
||||
6. **Update `docProps/app.xml`**: Increment slide count and update statistics (if present)
|
||||
|
||||
### Duplicating a Slide
|
||||
1. Copy the source slide XML file with a new name
|
||||
2. Update all IDs in the new slide to be unique
|
||||
3. Follow the "Adding a New Slide" steps above
|
||||
4. **CRITICAL**: Remove or update any notes slide references in `_rels` files
|
||||
5. Remove references to unused media files
|
||||
|
||||
### Reordering Slides
|
||||
1. **Update `ppt/presentation.xml`**: Reorder `<p:sldId>` elements in `<p:sldIdLst>`
|
||||
2. The order of `<p:sldId>` elements determines slide order
|
||||
3. Keep slide IDs and relationship IDs unchanged
|
||||
|
||||
Example:
|
||||
```xml
|
||||
<!-- Original order -->
|
||||
<p:sldIdLst>
|
||||
<p:sldId id="256" r:id="rId2"/>
|
||||
<p:sldId id="257" r:id="rId3"/>
|
||||
<p:sldId id="258" r:id="rId4"/>
|
||||
</p:sldIdLst>
|
||||
|
||||
<!-- After moving slide 3 to position 2 -->
|
||||
<p:sldIdLst>
|
||||
<p:sldId id="256" r:id="rId2"/>
|
||||
<p:sldId id="258" r:id="rId4"/>
|
||||
<p:sldId id="257" r:id="rId3"/>
|
||||
</p:sldIdLst>
|
||||
```
|
||||
|
||||
### Deleting a Slide
|
||||
1. **Remove from `ppt/presentation.xml`**: Delete the `<p:sldId>` entry
|
||||
2. **Remove from `ppt/_rels/presentation.xml.rels`**: Delete the relationship
|
||||
3. **Remove from `[Content_Types].xml`**: Delete the Override entry
|
||||
4. **Delete files**: Remove `ppt/slides/slideN.xml` and `ppt/slides/_rels/slideN.xml.rels`
|
||||
5. **Update `docProps/app.xml`**: Decrement slide count and update statistics
|
||||
6. **Clean up unused media**: Remove orphaned images from `ppt/media/`
|
||||
|
||||
Note: Don't renumber remaining slides - keep their original IDs and filenames.
|
||||
|
||||
|
||||
## Common Errors to Avoid
|
||||
|
||||
- **Encodings**: Escape unicode characters in ASCII content: `"` becomes `“`
|
||||
- **Images**: Add to `ppt/media/` and update relationship files
|
||||
- **Lists**: Omit bullets from list headers
|
||||
- **IDs**: Use valid hexadecimal values for UUIDs
|
||||
- **Themes**: Check all themes in `theme` directory for colors
|
||||
|
||||
## Validation Checklist for Template-Based Presentations
|
||||
|
||||
### Before Packing, Always:
|
||||
- **Clean unused resources**: Remove unreferenced media, fonts, and notes directories
|
||||
- **Fix Content_Types.xml**: Declare ALL slides, layouts, and themes present in the package
|
||||
- **Fix relationship IDs**:
|
||||
- Remove font embed references if not using embedded fonts
|
||||
- **Remove broken references**: Check all `_rels` files for references to deleted resources
|
||||
|
||||
### Common Template Duplication Pitfalls:
|
||||
- Multiple slides referencing the same notes slide after duplication
|
||||
- Image/media references from template slides that no longer exist
|
||||
- Font embedding references when fonts aren't included
|
||||
- Missing slideLayout declarations for layouts 12-25
|
||||
- docProps directory may not unpack - this is optional
|
||||
1499
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd
Executable file
1499
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd
Executable file
File diff suppressed because it is too large
Load Diff
146
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd
Executable file
146
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd
Executable file
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
xmlns="http://schemas.openxmlformats.org/drawingml/2006/chartDrawing"
|
||||
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/chartDrawing"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
schemaLocation="dml-main.xsd"/>
|
||||
<xsd:complexType name="CT_ShapeNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvSpPr" type="a:CT_NonVisualDrawingShapeProps" minOccurs="1" maxOccurs="1"
|
||||
/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Shape">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvSpPr" type="CT_ShapeNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="txBody" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="textlink" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fLocksText" type="xsd:boolean" use="optional" default="true"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ConnectorNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvCxnSpPr" type="a:CT_NonVisualConnectorProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Connector">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvCxnSpPr" type="CT_ConnectorNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PictureNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvPicPr" type="a:CT_NonVisualPictureProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Picture">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvPicPr" type="CT_PictureNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="blipFill" type="a:CT_BlipFillProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional" default=""/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GraphicFrameNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
|
||||
minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GraphicFrame">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvGraphicFramePr" type="CT_GraphicFrameNonVisual" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupShapeNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGrpSpPr" type="a:CT_NonVisualGroupDrawingShapeProps" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupShape">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvGrpSpPr" type="CT_GroupShapeNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="grpSpPr" type="a:CT_GroupShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="sp" type="CT_Shape"/>
|
||||
<xsd:element name="grpSp" type="CT_GroupShape"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
|
||||
<xsd:element name="cxnSp" type="CT_Connector"/>
|
||||
<xsd:element name="pic" type="CT_Picture"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ObjectChoices">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="sp" type="CT_Shape"/>
|
||||
<xsd:element name="grpSp" type="CT_GroupShape"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
|
||||
<xsd:element name="cxnSp" type="CT_Connector"/>
|
||||
<xsd:element name="pic" type="CT_Picture"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:simpleType name="ST_MarkerCoordinate">
|
||||
<xsd:restriction base="xsd:double">
|
||||
<xsd:minInclusive value="0.0"/>
|
||||
<xsd:maxInclusive value="1.0"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Marker">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="x" type="ST_MarkerCoordinate" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="y" type="ST_MarkerCoordinate" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_RelSizeAnchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="from" type="CT_Marker"/>
|
||||
<xsd:element name="to" type="CT_Marker"/>
|
||||
<xsd:group ref="EG_ObjectChoices"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_AbsSizeAnchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="from" type="CT_Marker"/>
|
||||
<xsd:element name="ext" type="a:CT_PositiveSize2D"/>
|
||||
<xsd:group ref="EG_ObjectChoices"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_Anchor">
|
||||
<xsd:choice>
|
||||
<xsd:element name="relSizeAnchor" type="CT_RelSizeAnchor"/>
|
||||
<xsd:element name="absSizeAnchor" type="CT_AbsSizeAnchor"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_Drawing">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_Anchor" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
1085
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd
Executable file
1085
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd
Executable file
File diff suppressed because it is too large
Load Diff
11
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd
Executable file
11
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd
Executable file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas"
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
elementFormDefault="qualified"
|
||||
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
schemaLocation="dml-main.xsd"/>
|
||||
<xsd:element name="lockedCanvas" type="a:CT_GvmlGroupShape"/>
|
||||
</xsd:schema>
|
||||
3081
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd
Executable file
3081
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd
Executable file
File diff suppressed because it is too large
Load Diff
23
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd
Executable file
23
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd
Executable file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/drawingml/2006/picture"
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" elementFormDefault="qualified"
|
||||
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/picture">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
schemaLocation="dml-main.xsd"/>
|
||||
<xsd:complexType name="CT_PictureNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvPicPr" type="a:CT_NonVisualPictureProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Picture">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="nvPicPr" type="CT_PictureNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="blipFill" type="a:CT_BlipFillProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="pic" type="CT_Picture"/>
|
||||
</xsd:schema>
|
||||
185
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd
Executable file
185
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd
Executable file
@@ -0,0 +1,185 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
xmlns="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
schemaLocation="dml-main.xsd"/>
|
||||
<xsd:import schemaLocation="shared-relationshipReference.xsd"
|
||||
namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"/>
|
||||
<xsd:element name="from" type="CT_Marker"/>
|
||||
<xsd:element name="to" type="CT_Marker"/>
|
||||
<xsd:complexType name="CT_AnchorClientData">
|
||||
<xsd:attribute name="fLocksWithSheet" type="xsd:boolean" use="optional" default="true"/>
|
||||
<xsd:attribute name="fPrintsWithSheet" type="xsd:boolean" use="optional" default="true"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ShapeNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvSpPr" type="a:CT_NonVisualDrawingShapeProps" minOccurs="1" maxOccurs="1"
|
||||
/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Shape">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvSpPr" type="CT_ShapeNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="txBody" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="textlink" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fLocksText" type="xsd:boolean" use="optional" default="true"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ConnectorNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvCxnSpPr" type="a:CT_NonVisualConnectorProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Connector">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvCxnSpPr" type="CT_ConnectorNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PictureNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvPicPr" type="a:CT_NonVisualPictureProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Picture">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvPicPr" type="CT_PictureNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="blipFill" type="a:CT_BlipFillProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional" default=""/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GraphicalObjectFrameNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
|
||||
minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GraphicalObjectFrame">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvGraphicFramePr" type="CT_GraphicalObjectFrameNonVisual" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="macro" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupShapeNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGrpSpPr" type="a:CT_NonVisualGroupDrawingShapeProps" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupShape">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvGrpSpPr" type="CT_GroupShapeNonVisual" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="grpSpPr" type="a:CT_GroupShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="sp" type="CT_Shape"/>
|
||||
<xsd:element name="grpSp" type="CT_GroupShape"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicalObjectFrame"/>
|
||||
<xsd:element name="cxnSp" type="CT_Connector"/>
|
||||
<xsd:element name="pic" type="CT_Picture"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ObjectChoices">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="sp" type="CT_Shape"/>
|
||||
<xsd:element name="grpSp" type="CT_GroupShape"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicalObjectFrame"/>
|
||||
<xsd:element name="cxnSp" type="CT_Connector"/>
|
||||
<xsd:element name="pic" type="CT_Picture"/>
|
||||
<xsd:element name="contentPart" type="CT_Rel"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_Rel">
|
||||
<xsd:attribute ref="r:id" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_ColID">
|
||||
<xsd:restriction base="xsd:int">
|
||||
<xsd:minInclusive value="0"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_RowID">
|
||||
<xsd:restriction base="xsd:int">
|
||||
<xsd:minInclusive value="0"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Marker">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="col" type="ST_ColID"/>
|
||||
<xsd:element name="colOff" type="a:ST_Coordinate"/>
|
||||
<xsd:element name="row" type="ST_RowID"/>
|
||||
<xsd:element name="rowOff" type="a:ST_Coordinate"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_EditAs">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="twoCell"/>
|
||||
<xsd:enumeration value="oneCell"/>
|
||||
<xsd:enumeration value="absolute"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_TwoCellAnchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="from" type="CT_Marker"/>
|
||||
<xsd:element name="to" type="CT_Marker"/>
|
||||
<xsd:group ref="EG_ObjectChoices"/>
|
||||
<xsd:element name="clientData" type="CT_AnchorClientData" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="editAs" type="ST_EditAs" use="optional" default="twoCell"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OneCellAnchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="from" type="CT_Marker"/>
|
||||
<xsd:element name="ext" type="a:CT_PositiveSize2D"/>
|
||||
<xsd:group ref="EG_ObjectChoices"/>
|
||||
<xsd:element name="clientData" type="CT_AnchorClientData" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_AbsoluteAnchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="pos" type="a:CT_Point2D"/>
|
||||
<xsd:element name="ext" type="a:CT_PositiveSize2D"/>
|
||||
<xsd:group ref="EG_ObjectChoices"/>
|
||||
<xsd:element name="clientData" type="CT_AnchorClientData" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_Anchor">
|
||||
<xsd:choice>
|
||||
<xsd:element name="twoCellAnchor" type="CT_TwoCellAnchor"/>
|
||||
<xsd:element name="oneCellAnchor" type="CT_OneCellAnchor"/>
|
||||
<xsd:element name="absoluteAnchor" type="CT_AbsoluteAnchor"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_Drawing">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_Anchor" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="wsDr" type="CT_Drawing"/>
|
||||
</xsd:schema>
|
||||
287
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd
Executable file
287
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd
Executable file
@@ -0,0 +1,287 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
xmlns:dpct="http://schemas.openxmlformats.org/drawingml/2006/picture"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
xmlns="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
|
||||
targetNamespace="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
schemaLocation="dml-main.xsd"/>
|
||||
<xsd:import schemaLocation="wml.xsd"
|
||||
namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/picture"
|
||||
schemaLocation="dml-picture.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
schemaLocation="shared-relationshipReference.xsd"/>
|
||||
<xsd:complexType name="CT_EffectExtent">
|
||||
<xsd:attribute name="l" type="a:ST_Coordinate" use="required"/>
|
||||
<xsd:attribute name="t" type="a:ST_Coordinate" use="required"/>
|
||||
<xsd:attribute name="r" type="a:ST_Coordinate" use="required"/>
|
||||
<xsd:attribute name="b" type="a:ST_Coordinate" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_WrapDistance">
|
||||
<xsd:restriction base="xsd:unsignedInt"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Inline">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="extent" type="a:CT_PositiveSize2D"/>
|
||||
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
|
||||
<xsd:element name="docPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
|
||||
minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_WrapText">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="bothSides"/>
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="largest"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_WrapPath">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="start" type="a:CT_Point2D" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="lineTo" type="a:CT_Point2D" minOccurs="2" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="edited" type="xsd:boolean" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WrapNone"/>
|
||||
<xsd:complexType name="CT_WrapSquare">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="wrapText" type="ST_WrapText" use="required"/>
|
||||
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WrapTight">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="wrapPolygon" type="CT_WrapPath" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="wrapText" type="ST_WrapText" use="required"/>
|
||||
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WrapThrough">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="wrapPolygon" type="CT_WrapPath" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="wrapText" type="ST_WrapText" use="required"/>
|
||||
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WrapTopBottom">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_WrapType">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="wrapNone" type="CT_WrapNone" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="wrapSquare" type="CT_WrapSquare" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="wrapTight" type="CT_WrapTight" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="wrapThrough" type="CT_WrapThrough" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="wrapTopAndBottom" type="CT_WrapTopBottom" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:simpleType name="ST_PositionOffset">
|
||||
<xsd:restriction base="xsd:int"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_AlignH">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="inside"/>
|
||||
<xsd:enumeration value="outside"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_RelFromH">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="margin"/>
|
||||
<xsd:enumeration value="page"/>
|
||||
<xsd:enumeration value="column"/>
|
||||
<xsd:enumeration value="character"/>
|
||||
<xsd:enumeration value="leftMargin"/>
|
||||
<xsd:enumeration value="rightMargin"/>
|
||||
<xsd:enumeration value="insideMargin"/>
|
||||
<xsd:enumeration value="outsideMargin"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_PosH">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="align" type="ST_AlignH" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="posOffset" type="ST_PositionOffset" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="relativeFrom" type="ST_RelFromH" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_AlignV">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="top"/>
|
||||
<xsd:enumeration value="bottom"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="inside"/>
|
||||
<xsd:enumeration value="outside"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_RelFromV">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="margin"/>
|
||||
<xsd:enumeration value="page"/>
|
||||
<xsd:enumeration value="paragraph"/>
|
||||
<xsd:enumeration value="line"/>
|
||||
<xsd:enumeration value="topMargin"/>
|
||||
<xsd:enumeration value="bottomMargin"/>
|
||||
<xsd:enumeration value="insideMargin"/>
|
||||
<xsd:enumeration value="outsideMargin"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_PosV">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="align" type="ST_AlignV" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="posOffset" type="ST_PositionOffset" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="relativeFrom" type="ST_RelFromV" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Anchor">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="simplePos" type="a:CT_Point2D"/>
|
||||
<xsd:element name="positionH" type="CT_PosH"/>
|
||||
<xsd:element name="positionV" type="CT_PosV"/>
|
||||
<xsd:element name="extent" type="a:CT_PositiveSize2D"/>
|
||||
<xsd:element name="effectExtent" type="CT_EffectExtent" minOccurs="0"/>
|
||||
<xsd:group ref="EG_WrapType"/>
|
||||
<xsd:element name="docPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGraphicFramePr" type="a:CT_NonVisualGraphicFrameProperties"
|
||||
minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="distT" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distB" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distL" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="distR" type="ST_WrapDistance" use="optional"/>
|
||||
<xsd:attribute name="simplePos" type="xsd:boolean"/>
|
||||
<xsd:attribute name="relativeHeight" type="xsd:unsignedInt" use="required"/>
|
||||
<xsd:attribute name="behindDoc" type="xsd:boolean" use="required"/>
|
||||
<xsd:attribute name="locked" type="xsd:boolean" use="required"/>
|
||||
<xsd:attribute name="layoutInCell" type="xsd:boolean" use="required"/>
|
||||
<xsd:attribute name="hidden" type="xsd:boolean" use="optional"/>
|
||||
<xsd:attribute name="allowOverlap" type="xsd:boolean" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_TxbxContent">
|
||||
<xsd:group ref="w:EG_BlockLevelElts" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_TextboxInfo">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="txbxContent" type="CT_TxbxContent" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:unsignedShort" use="optional" default="0"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LinkedTextboxInformation">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:unsignedShort" use="required"/>
|
||||
<xsd:attribute name="seq" type="xsd:unsignedShort" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WordprocessingShape">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="cNvSpPr" type="a:CT_NonVisualDrawingShapeProps" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="cNvCnPr" type="a:CT_NonVisualConnectorProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="1">
|
||||
<xsd:element name="txbx" type="CT_TextboxInfo" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="linkedTxbx" type="CT_LinkedTextboxInformation" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="bodyPr" type="a:CT_TextBodyProperties" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="normalEastAsianFlow" type="xsd:boolean" use="optional" default="false"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GraphicFrame">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="cNvFrPr" type="a:CT_NonVisualGraphicFrameProperties" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element ref="a:graphic" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WordprocessingContentPartNonVisual">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="cNvContentPartPr" type="a:CT_NonVisualContentPartProperties" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WordprocessingContentPart">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="nvContentPartPr" type="CT_WordprocessingContentPartNonVisual" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="xfrm" type="a:CT_Transform2D" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="bwMode" type="a:ST_BlackWhiteMode" use="optional"/>
|
||||
<xsd:attribute ref="r:id" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WordprocessingGroup">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="cNvGrpSpPr" type="a:CT_NonVisualGroupDrawingShapeProps" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="grpSpPr" type="a:CT_GroupShapeProperties" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element ref="wsp"/>
|
||||
<xsd:element name="grpSp" type="CT_WordprocessingGroup"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
|
||||
<xsd:element ref="dpct:pic"/>
|
||||
<xsd:element name="contentPart" type="CT_WordprocessingContentPart"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_WordprocessingCanvas">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="bg" type="a:CT_BackgroundFormatting" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="whole" type="a:CT_WholeE2oFormatting" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element ref="wsp"/>
|
||||
<xsd:element ref="dpct:pic"/>
|
||||
<xsd:element name="contentPart" type="CT_WordprocessingContentPart"/>
|
||||
<xsd:element ref="wgp"/>
|
||||
<xsd:element name="graphicFrame" type="CT_GraphicFrame"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="extLst" type="a:CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="wpc" type="CT_WordprocessingCanvas"/>
|
||||
<xsd:element name="wgp" type="CT_WordprocessingGroup"/>
|
||||
<xsd:element name="wsp" type="CT_WordprocessingShape"/>
|
||||
<xsd:element name="inline" type="CT_Inline"/>
|
||||
<xsd:element name="anchor" type="CT_Anchor"/>
|
||||
</xsd:schema>
|
||||
1676
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd
Executable file
1676
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd
Executable file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/characteristics"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/characteristics"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:complexType name="CT_AdditionalCharacteristics">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="characteristic" type="CT_Characteristic" minOccurs="0"
|
||||
maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Characteristic">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="relation" type="ST_Relation" use="required"/>
|
||||
<xsd:attribute name="val" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="vocabulary" type="xsd:anyURI" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Relation">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="ge"/>
|
||||
<xsd:enumeration value="le"/>
|
||||
<xsd:enumeration value="gt"/>
|
||||
<xsd:enumeration value="lt"/>
|
||||
<xsd:enumeration value="eq"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:element name="additionalCharacteristics" type="CT_AdditionalCharacteristics"/>
|
||||
</xsd:schema>
|
||||
144
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd
Executable file
144
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd
Executable file
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/bibliography"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/bibliography"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:simpleType name="ST_SourceType">
|
||||
<xsd:restriction base="s:ST_String">
|
||||
<xsd:enumeration value="ArticleInAPeriodical"/>
|
||||
<xsd:enumeration value="Book"/>
|
||||
<xsd:enumeration value="BookSection"/>
|
||||
<xsd:enumeration value="JournalArticle"/>
|
||||
<xsd:enumeration value="ConferenceProceedings"/>
|
||||
<xsd:enumeration value="Report"/>
|
||||
<xsd:enumeration value="SoundRecording"/>
|
||||
<xsd:enumeration value="Performance"/>
|
||||
<xsd:enumeration value="Art"/>
|
||||
<xsd:enumeration value="DocumentFromInternetSite"/>
|
||||
<xsd:enumeration value="InternetSite"/>
|
||||
<xsd:enumeration value="Film"/>
|
||||
<xsd:enumeration value="Interview"/>
|
||||
<xsd:enumeration value="Patent"/>
|
||||
<xsd:enumeration value="ElectronicSource"/>
|
||||
<xsd:enumeration value="Case"/>
|
||||
<xsd:enumeration value="Misc"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_NameListType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Person" type="CT_PersonType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PersonType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Last" type="s:ST_String" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="First" type="s:ST_String" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="Middle" type="s:ST_String" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_NameType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="NameList" type="CT_NameListType" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_NameOrCorporateType">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="0" maxOccurs="1">
|
||||
<xsd:element name="NameList" type="CT_NameListType" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:element name="Corporate" minOccurs="1" maxOccurs="1" type="s:ST_String"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_AuthorType">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="Artist" type="CT_NameType"/>
|
||||
<xsd:element name="Author" type="CT_NameOrCorporateType"/>
|
||||
<xsd:element name="BookAuthor" type="CT_NameType"/>
|
||||
<xsd:element name="Compiler" type="CT_NameType"/>
|
||||
<xsd:element name="Composer" type="CT_NameType"/>
|
||||
<xsd:element name="Conductor" type="CT_NameType"/>
|
||||
<xsd:element name="Counsel" type="CT_NameType"/>
|
||||
<xsd:element name="Director" type="CT_NameType"/>
|
||||
<xsd:element name="Editor" type="CT_NameType"/>
|
||||
<xsd:element name="Interviewee" type="CT_NameType"/>
|
||||
<xsd:element name="Interviewer" type="CT_NameType"/>
|
||||
<xsd:element name="Inventor" type="CT_NameType"/>
|
||||
<xsd:element name="Performer" type="CT_NameOrCorporateType"/>
|
||||
<xsd:element name="ProducerName" type="CT_NameType"/>
|
||||
<xsd:element name="Translator" type="CT_NameType"/>
|
||||
<xsd:element name="Writer" type="CT_NameType"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SourceType">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="AbbreviatedCaseNumber" type="s:ST_String"/>
|
||||
<xsd:element name="AlbumTitle" type="s:ST_String"/>
|
||||
<xsd:element name="Author" type="CT_AuthorType"/>
|
||||
<xsd:element name="BookTitle" type="s:ST_String"/>
|
||||
<xsd:element name="Broadcaster" type="s:ST_String"/>
|
||||
<xsd:element name="BroadcastTitle" type="s:ST_String"/>
|
||||
<xsd:element name="CaseNumber" type="s:ST_String"/>
|
||||
<xsd:element name="ChapterNumber" type="s:ST_String"/>
|
||||
<xsd:element name="City" type="s:ST_String"/>
|
||||
<xsd:element name="Comments" type="s:ST_String"/>
|
||||
<xsd:element name="ConferenceName" type="s:ST_String"/>
|
||||
<xsd:element name="CountryRegion" type="s:ST_String"/>
|
||||
<xsd:element name="Court" type="s:ST_String"/>
|
||||
<xsd:element name="Day" type="s:ST_String"/>
|
||||
<xsd:element name="DayAccessed" type="s:ST_String"/>
|
||||
<xsd:element name="Department" type="s:ST_String"/>
|
||||
<xsd:element name="Distributor" type="s:ST_String"/>
|
||||
<xsd:element name="Edition" type="s:ST_String"/>
|
||||
<xsd:element name="Guid" type="s:ST_String"/>
|
||||
<xsd:element name="Institution" type="s:ST_String"/>
|
||||
<xsd:element name="InternetSiteTitle" type="s:ST_String"/>
|
||||
<xsd:element name="Issue" type="s:ST_String"/>
|
||||
<xsd:element name="JournalName" type="s:ST_String"/>
|
||||
<xsd:element name="LCID" type="s:ST_Lang"/>
|
||||
<xsd:element name="Medium" type="s:ST_String"/>
|
||||
<xsd:element name="Month" type="s:ST_String"/>
|
||||
<xsd:element name="MonthAccessed" type="s:ST_String"/>
|
||||
<xsd:element name="NumberVolumes" type="s:ST_String"/>
|
||||
<xsd:element name="Pages" type="s:ST_String"/>
|
||||
<xsd:element name="PatentNumber" type="s:ST_String"/>
|
||||
<xsd:element name="PeriodicalTitle" type="s:ST_String"/>
|
||||
<xsd:element name="ProductionCompany" type="s:ST_String"/>
|
||||
<xsd:element name="PublicationTitle" type="s:ST_String"/>
|
||||
<xsd:element name="Publisher" type="s:ST_String"/>
|
||||
<xsd:element name="RecordingNumber" type="s:ST_String"/>
|
||||
<xsd:element name="RefOrder" type="s:ST_String"/>
|
||||
<xsd:element name="Reporter" type="s:ST_String"/>
|
||||
<xsd:element name="SourceType" type="ST_SourceType"/>
|
||||
<xsd:element name="ShortTitle" type="s:ST_String"/>
|
||||
<xsd:element name="StandardNumber" type="s:ST_String"/>
|
||||
<xsd:element name="StateProvince" type="s:ST_String"/>
|
||||
<xsd:element name="Station" type="s:ST_String"/>
|
||||
<xsd:element name="Tag" type="s:ST_String"/>
|
||||
<xsd:element name="Theater" type="s:ST_String"/>
|
||||
<xsd:element name="ThesisType" type="s:ST_String"/>
|
||||
<xsd:element name="Title" type="s:ST_String"/>
|
||||
<xsd:element name="Type" type="s:ST_String"/>
|
||||
<xsd:element name="URL" type="s:ST_String"/>
|
||||
<xsd:element name="Version" type="s:ST_String"/>
|
||||
<xsd:element name="Volume" type="s:ST_String"/>
|
||||
<xsd:element name="Year" type="s:ST_String"/>
|
||||
<xsd:element name="YearAccessed" type="s:ST_String"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="Sources" type="CT_Sources"/>
|
||||
<xsd:complexType name="CT_Sources">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Source" type="CT_SourceType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="SelectedStyle" type="s:ST_String"/>
|
||||
<xsd:attribute name="StyleName" type="s:ST_String"/>
|
||||
<xsd:attribute name="URI" type="s:ST_String"/>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
174
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd
Executable file
174
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd
Executable file
@@ -0,0 +1,174 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
elementFormDefault="qualified">
|
||||
<xsd:simpleType name="ST_Lang">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_HexColorRGB">
|
||||
<xsd:restriction base="xsd:hexBinary">
|
||||
<xsd:length value="3" fixed="true"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Panose">
|
||||
<xsd:restriction base="xsd:hexBinary">
|
||||
<xsd:length value="10"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_CalendarType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="gregorian"/>
|
||||
<xsd:enumeration value="gregorianUs"/>
|
||||
<xsd:enumeration value="gregorianMeFrench"/>
|
||||
<xsd:enumeration value="gregorianArabic"/>
|
||||
<xsd:enumeration value="hijri"/>
|
||||
<xsd:enumeration value="hebrew"/>
|
||||
<xsd:enumeration value="taiwan"/>
|
||||
<xsd:enumeration value="japan"/>
|
||||
<xsd:enumeration value="thai"/>
|
||||
<xsd:enumeration value="korea"/>
|
||||
<xsd:enumeration value="saka"/>
|
||||
<xsd:enumeration value="gregorianXlitEnglish"/>
|
||||
<xsd:enumeration value="gregorianXlitFrench"/>
|
||||
<xsd:enumeration value="none"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_AlgClass">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="hash"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_CryptProv">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="rsaAES"/>
|
||||
<xsd:enumeration value="rsaFull"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_AlgType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="typeAny"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ColorType">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Guid">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:pattern value="\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OnOff">
|
||||
<xsd:union memberTypes="xsd:boolean ST_OnOff1"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OnOff1">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="on"/>
|
||||
<xsd:enumeration value="off"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_String">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_XmlName">
|
||||
<xsd:restriction base="xsd:NCName">
|
||||
<xsd:minLength value="1"/>
|
||||
<xsd:maxLength value="255"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_TrueFalse">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="t"/>
|
||||
<xsd:enumeration value="f"/>
|
||||
<xsd:enumeration value="true"/>
|
||||
<xsd:enumeration value="false"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_TrueFalseBlank">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="t"/>
|
||||
<xsd:enumeration value="f"/>
|
||||
<xsd:enumeration value="true"/>
|
||||
<xsd:enumeration value="false"/>
|
||||
<xsd:enumeration value=""/>
|
||||
<xsd:enumeration value="True"/>
|
||||
<xsd:enumeration value="False"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_UnsignedDecimalNumber">
|
||||
<xsd:restriction base="xsd:decimal">
|
||||
<xsd:minInclusive value="0"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_TwipsMeasure">
|
||||
<xsd:union memberTypes="ST_UnsignedDecimalNumber ST_PositiveUniversalMeasure"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_VerticalAlignRun">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="baseline"/>
|
||||
<xsd:enumeration value="superscript"/>
|
||||
<xsd:enumeration value="subscript"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Xstring">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_XAlign">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="inside"/>
|
||||
<xsd:enumeration value="outside"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_YAlign">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="inline"/>
|
||||
<xsd:enumeration value="top"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="bottom"/>
|
||||
<xsd:enumeration value="inside"/>
|
||||
<xsd:enumeration value="outside"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ConformanceClass">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="strict"/>
|
||||
<xsd:enumeration value="transitional"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_UniversalMeasure">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="-?[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PositiveUniversalMeasure">
|
||||
<xsd:restriction base="ST_UniversalMeasure">
|
||||
<xsd:pattern value="[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Percentage">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="-?[0-9]+(\.[0-9]+)?%"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_FixedPercentage">
|
||||
<xsd:restriction base="ST_Percentage">
|
||||
<xsd:pattern value="-?((100)|([0-9][0-9]?))(\.[0-9][0-9]?)?%"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PositivePercentage">
|
||||
<xsd:restriction base="ST_Percentage">
|
||||
<xsd:pattern value="[0-9]+(\.[0-9]+)?%"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PositiveFixedPercentage">
|
||||
<xsd:restriction base="ST_Percentage">
|
||||
<xsd:pattern value="((100)|([0-9][0-9]?))(\.[0-9][0-9]?)?%"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/customXml"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/customXml"
|
||||
elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:complexType name="CT_DatastoreSchemaRef">
|
||||
<xsd:attribute name="uri" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_DatastoreSchemaRefs">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="schemaRef" type="CT_DatastoreSchemaRef" minOccurs="0" maxOccurs="unbounded"
|
||||
/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_DatastoreItem">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="schemaRefs" type="CT_DatastoreSchemaRefs" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="itemID" type="s:ST_Guid" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="datastoreItem" type="CT_DatastoreItem"/>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/schemaLibrary/2006/main"
|
||||
targetNamespace="http://schemas.openxmlformats.org/schemaLibrary/2006/main"
|
||||
attributeFormDefault="qualified" elementFormDefault="qualified">
|
||||
<xsd:complexType name="CT_Schema">
|
||||
<xsd:attribute name="uri" type="xsd:string" default=""/>
|
||||
<xsd:attribute name="manifestLocation" type="xsd:string"/>
|
||||
<xsd:attribute name="schemaLocation" type="xsd:string"/>
|
||||
<xsd:attribute name="schemaLanguage" type="xsd:token"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SchemaLibrary">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="schema" type="CT_Schema" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="schemaLibrary" type="CT_SchemaLibrary"/>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"
|
||||
xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"
|
||||
blockDefault="#all" elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
schemaLocation="shared-documentPropertiesVariantTypes.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:element name="Properties" type="CT_Properties"/>
|
||||
<xsd:complexType name="CT_Properties">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="property" minOccurs="0" maxOccurs="unbounded" type="CT_Property"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Property">
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element ref="vt:vector"/>
|
||||
<xsd:element ref="vt:array"/>
|
||||
<xsd:element ref="vt:blob"/>
|
||||
<xsd:element ref="vt:oblob"/>
|
||||
<xsd:element ref="vt:empty"/>
|
||||
<xsd:element ref="vt:null"/>
|
||||
<xsd:element ref="vt:i1"/>
|
||||
<xsd:element ref="vt:i2"/>
|
||||
<xsd:element ref="vt:i4"/>
|
||||
<xsd:element ref="vt:i8"/>
|
||||
<xsd:element ref="vt:int"/>
|
||||
<xsd:element ref="vt:ui1"/>
|
||||
<xsd:element ref="vt:ui2"/>
|
||||
<xsd:element ref="vt:ui4"/>
|
||||
<xsd:element ref="vt:ui8"/>
|
||||
<xsd:element ref="vt:uint"/>
|
||||
<xsd:element ref="vt:r4"/>
|
||||
<xsd:element ref="vt:r8"/>
|
||||
<xsd:element ref="vt:decimal"/>
|
||||
<xsd:element ref="vt:lpstr"/>
|
||||
<xsd:element ref="vt:lpwstr"/>
|
||||
<xsd:element ref="vt:bstr"/>
|
||||
<xsd:element ref="vt:date"/>
|
||||
<xsd:element ref="vt:filetime"/>
|
||||
<xsd:element ref="vt:bool"/>
|
||||
<xsd:element ref="vt:cy"/>
|
||||
<xsd:element ref="vt:error"/>
|
||||
<xsd:element ref="vt:stream"/>
|
||||
<xsd:element ref="vt:ostream"/>
|
||||
<xsd:element ref="vt:storage"/>
|
||||
<xsd:element ref="vt:ostorage"/>
|
||||
<xsd:element ref="vt:vstream"/>
|
||||
<xsd:element ref="vt:clsid"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="fmtid" use="required" type="s:ST_Guid"/>
|
||||
<xsd:attribute name="pid" use="required" type="xsd:int"/>
|
||||
<xsd:attribute name="name" use="optional" type="xsd:string"/>
|
||||
<xsd:attribute name="linkTarget" use="optional" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
|
||||
xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
|
||||
elementFormDefault="qualified" blockDefault="#all">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
schemaLocation="shared-documentPropertiesVariantTypes.xsd"/>
|
||||
<xsd:element name="Properties" type="CT_Properties"/>
|
||||
<xsd:complexType name="CT_Properties">
|
||||
<xsd:all>
|
||||
<xsd:element name="Template" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="Manager" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="Company" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="Pages" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="Words" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="Characters" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="PresentationFormat" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="Lines" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="Paragraphs" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="Slides" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="Notes" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="TotalTime" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="HiddenSlides" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="MMClips" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="ScaleCrop" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
|
||||
<xsd:element name="HeadingPairs" minOccurs="0" maxOccurs="1" type="CT_VectorVariant"/>
|
||||
<xsd:element name="TitlesOfParts" minOccurs="0" maxOccurs="1" type="CT_VectorLpstr"/>
|
||||
<xsd:element name="LinksUpToDate" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
|
||||
<xsd:element name="CharactersWithSpaces" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
<xsd:element name="SharedDoc" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
|
||||
<xsd:element name="HyperlinkBase" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="HLinks" minOccurs="0" maxOccurs="1" type="CT_VectorVariant"/>
|
||||
<xsd:element name="HyperlinksChanged" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
|
||||
<xsd:element name="DigSig" minOccurs="0" maxOccurs="1" type="CT_DigSigBlob"/>
|
||||
<xsd:element name="Application" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="AppVersion" minOccurs="0" maxOccurs="1" type="xsd:string"/>
|
||||
<xsd:element name="DocSecurity" minOccurs="0" maxOccurs="1" type="xsd:int"/>
|
||||
</xsd:all>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_VectorVariant">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element ref="vt:vector"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_VectorLpstr">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element ref="vt:vector"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_DigSigBlob">
|
||||
<xsd:sequence minOccurs="1" maxOccurs="1">
|
||||
<xsd:element ref="vt:blob"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,195 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
||||
blockDefault="#all" elementFormDefault="qualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:simpleType name="ST_VectorBaseType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="variant"/>
|
||||
<xsd:enumeration value="i1"/>
|
||||
<xsd:enumeration value="i2"/>
|
||||
<xsd:enumeration value="i4"/>
|
||||
<xsd:enumeration value="i8"/>
|
||||
<xsd:enumeration value="ui1"/>
|
||||
<xsd:enumeration value="ui2"/>
|
||||
<xsd:enumeration value="ui4"/>
|
||||
<xsd:enumeration value="ui8"/>
|
||||
<xsd:enumeration value="r4"/>
|
||||
<xsd:enumeration value="r8"/>
|
||||
<xsd:enumeration value="lpstr"/>
|
||||
<xsd:enumeration value="lpwstr"/>
|
||||
<xsd:enumeration value="bstr"/>
|
||||
<xsd:enumeration value="date"/>
|
||||
<xsd:enumeration value="filetime"/>
|
||||
<xsd:enumeration value="bool"/>
|
||||
<xsd:enumeration value="cy"/>
|
||||
<xsd:enumeration value="error"/>
|
||||
<xsd:enumeration value="clsid"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ArrayBaseType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="variant"/>
|
||||
<xsd:enumeration value="i1"/>
|
||||
<xsd:enumeration value="i2"/>
|
||||
<xsd:enumeration value="i4"/>
|
||||
<xsd:enumeration value="int"/>
|
||||
<xsd:enumeration value="ui1"/>
|
||||
<xsd:enumeration value="ui2"/>
|
||||
<xsd:enumeration value="ui4"/>
|
||||
<xsd:enumeration value="uint"/>
|
||||
<xsd:enumeration value="r4"/>
|
||||
<xsd:enumeration value="r8"/>
|
||||
<xsd:enumeration value="decimal"/>
|
||||
<xsd:enumeration value="bstr"/>
|
||||
<xsd:enumeration value="date"/>
|
||||
<xsd:enumeration value="bool"/>
|
||||
<xsd:enumeration value="cy"/>
|
||||
<xsd:enumeration value="error"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Cy">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="\s*[0-9]*\.[0-9]{4}\s*"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Error">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="\s*0x[0-9A-Za-z]{8}\s*"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Empty"/>
|
||||
<xsd:complexType name="CT_Null"/>
|
||||
<xsd:complexType name="CT_Vector">
|
||||
<xsd:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:element ref="variant"/>
|
||||
<xsd:element ref="i1"/>
|
||||
<xsd:element ref="i2"/>
|
||||
<xsd:element ref="i4"/>
|
||||
<xsd:element ref="i8"/>
|
||||
<xsd:element ref="ui1"/>
|
||||
<xsd:element ref="ui2"/>
|
||||
<xsd:element ref="ui4"/>
|
||||
<xsd:element ref="ui8"/>
|
||||
<xsd:element ref="r4"/>
|
||||
<xsd:element ref="r8"/>
|
||||
<xsd:element ref="lpstr"/>
|
||||
<xsd:element ref="lpwstr"/>
|
||||
<xsd:element ref="bstr"/>
|
||||
<xsd:element ref="date"/>
|
||||
<xsd:element ref="filetime"/>
|
||||
<xsd:element ref="bool"/>
|
||||
<xsd:element ref="cy"/>
|
||||
<xsd:element ref="error"/>
|
||||
<xsd:element ref="clsid"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="baseType" type="ST_VectorBaseType" use="required"/>
|
||||
<xsd:attribute name="size" type="xsd:unsignedInt" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Array">
|
||||
<xsd:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:element ref="variant"/>
|
||||
<xsd:element ref="i1"/>
|
||||
<xsd:element ref="i2"/>
|
||||
<xsd:element ref="i4"/>
|
||||
<xsd:element ref="int"/>
|
||||
<xsd:element ref="ui1"/>
|
||||
<xsd:element ref="ui2"/>
|
||||
<xsd:element ref="ui4"/>
|
||||
<xsd:element ref="uint"/>
|
||||
<xsd:element ref="r4"/>
|
||||
<xsd:element ref="r8"/>
|
||||
<xsd:element ref="decimal"/>
|
||||
<xsd:element ref="bstr"/>
|
||||
<xsd:element ref="date"/>
|
||||
<xsd:element ref="bool"/>
|
||||
<xsd:element ref="error"/>
|
||||
<xsd:element ref="cy"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="lBounds" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="uBounds" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="baseType" type="ST_ArrayBaseType" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Variant">
|
||||
<xsd:choice minOccurs="1" maxOccurs="1">
|
||||
<xsd:element ref="variant"/>
|
||||
<xsd:element ref="vector"/>
|
||||
<xsd:element ref="array"/>
|
||||
<xsd:element ref="blob"/>
|
||||
<xsd:element ref="oblob"/>
|
||||
<xsd:element ref="empty"/>
|
||||
<xsd:element ref="null"/>
|
||||
<xsd:element ref="i1"/>
|
||||
<xsd:element ref="i2"/>
|
||||
<xsd:element ref="i4"/>
|
||||
<xsd:element ref="i8"/>
|
||||
<xsd:element ref="int"/>
|
||||
<xsd:element ref="ui1"/>
|
||||
<xsd:element ref="ui2"/>
|
||||
<xsd:element ref="ui4"/>
|
||||
<xsd:element ref="ui8"/>
|
||||
<xsd:element ref="uint"/>
|
||||
<xsd:element ref="r4"/>
|
||||
<xsd:element ref="r8"/>
|
||||
<xsd:element ref="decimal"/>
|
||||
<xsd:element ref="lpstr"/>
|
||||
<xsd:element ref="lpwstr"/>
|
||||
<xsd:element ref="bstr"/>
|
||||
<xsd:element ref="date"/>
|
||||
<xsd:element ref="filetime"/>
|
||||
<xsd:element ref="bool"/>
|
||||
<xsd:element ref="cy"/>
|
||||
<xsd:element ref="error"/>
|
||||
<xsd:element ref="stream"/>
|
||||
<xsd:element ref="ostream"/>
|
||||
<xsd:element ref="storage"/>
|
||||
<xsd:element ref="ostorage"/>
|
||||
<xsd:element ref="vstream"/>
|
||||
<xsd:element ref="clsid"/>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Vstream">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:base64Binary">
|
||||
<xsd:attribute name="version" type="s:ST_Guid"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="variant" type="CT_Variant"/>
|
||||
<xsd:element name="vector" type="CT_Vector"/>
|
||||
<xsd:element name="array" type="CT_Array"/>
|
||||
<xsd:element name="blob" type="xsd:base64Binary"/>
|
||||
<xsd:element name="oblob" type="xsd:base64Binary"/>
|
||||
<xsd:element name="empty" type="CT_Empty"/>
|
||||
<xsd:element name="null" type="CT_Null"/>
|
||||
<xsd:element name="i1" type="xsd:byte"/>
|
||||
<xsd:element name="i2" type="xsd:short"/>
|
||||
<xsd:element name="i4" type="xsd:int"/>
|
||||
<xsd:element name="i8" type="xsd:long"/>
|
||||
<xsd:element name="int" type="xsd:int"/>
|
||||
<xsd:element name="ui1" type="xsd:unsignedByte"/>
|
||||
<xsd:element name="ui2" type="xsd:unsignedShort"/>
|
||||
<xsd:element name="ui4" type="xsd:unsignedInt"/>
|
||||
<xsd:element name="ui8" type="xsd:unsignedLong"/>
|
||||
<xsd:element name="uint" type="xsd:unsignedInt"/>
|
||||
<xsd:element name="r4" type="xsd:float"/>
|
||||
<xsd:element name="r8" type="xsd:double"/>
|
||||
<xsd:element name="decimal" type="xsd:decimal"/>
|
||||
<xsd:element name="lpstr" type="xsd:string"/>
|
||||
<xsd:element name="lpwstr" type="xsd:string"/>
|
||||
<xsd:element name="bstr" type="xsd:string"/>
|
||||
<xsd:element name="date" type="xsd:dateTime"/>
|
||||
<xsd:element name="filetime" type="xsd:dateTime"/>
|
||||
<xsd:element name="bool" type="xsd:boolean"/>
|
||||
<xsd:element name="cy" type="ST_Cy"/>
|
||||
<xsd:element name="error" type="ST_Error"/>
|
||||
<xsd:element name="stream" type="xsd:base64Binary"/>
|
||||
<xsd:element name="ostream" type="xsd:base64Binary"/>
|
||||
<xsd:element name="storage" type="xsd:base64Binary"/>
|
||||
<xsd:element name="ostorage" type="xsd:base64Binary"/>
|
||||
<xsd:element name="vstream" type="CT_Vstream"/>
|
||||
<xsd:element name="clsid" type="s:ST_Guid"/>
|
||||
</xsd:schema>
|
||||
582
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd
Executable file
582
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd
Executable file
@@ -0,0 +1,582 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/math"
|
||||
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
|
||||
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/math">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
schemaLocation="wml.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
|
||||
<xsd:simpleType name="ST_Integer255">
|
||||
<xsd:restriction base="xsd:integer">
|
||||
<xsd:minInclusive value="1"/>
|
||||
<xsd:maxInclusive value="255"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Integer255">
|
||||
<xsd:attribute name="val" type="ST_Integer255" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Integer2">
|
||||
<xsd:restriction base="xsd:integer">
|
||||
<xsd:minInclusive value="-2"/>
|
||||
<xsd:maxInclusive value="2"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Integer2">
|
||||
<xsd:attribute name="val" type="ST_Integer2" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_SpacingRule">
|
||||
<xsd:restriction base="xsd:integer">
|
||||
<xsd:minInclusive value="0"/>
|
||||
<xsd:maxInclusive value="4"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_SpacingRule">
|
||||
<xsd:attribute name="val" type="ST_SpacingRule" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_UnSignedInteger">
|
||||
<xsd:restriction base="xsd:unsignedInt"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_UnSignedInteger">
|
||||
<xsd:attribute name="val" type="ST_UnSignedInteger" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Char">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="1"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Char">
|
||||
<xsd:attribute name="val" type="ST_Char" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OnOff">
|
||||
<xsd:attribute name="val" type="s:ST_OnOff"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_String">
|
||||
<xsd:attribute name="val" type="s:ST_String"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_XAlign">
|
||||
<xsd:attribute name="val" type="s:ST_XAlign" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_YAlign">
|
||||
<xsd:attribute name="val" type="s:ST_YAlign" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Shp">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="centered"/>
|
||||
<xsd:enumeration value="match"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Shp">
|
||||
<xsd:attribute name="val" type="ST_Shp" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_FType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="bar"/>
|
||||
<xsd:enumeration value="skw"/>
|
||||
<xsd:enumeration value="lin"/>
|
||||
<xsd:enumeration value="noBar"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_FType">
|
||||
<xsd:attribute name="val" type="ST_FType" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_LimLoc">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="undOvr"/>
|
||||
<xsd:enumeration value="subSup"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_LimLoc">
|
||||
<xsd:attribute name="val" type="ST_LimLoc" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_TopBot">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="top"/>
|
||||
<xsd:enumeration value="bot"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_TopBot">
|
||||
<xsd:attribute name="val" type="ST_TopBot" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Script">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="roman"/>
|
||||
<xsd:enumeration value="script"/>
|
||||
<xsd:enumeration value="fraktur"/>
|
||||
<xsd:enumeration value="double-struck"/>
|
||||
<xsd:enumeration value="sans-serif"/>
|
||||
<xsd:enumeration value="monospace"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Script">
|
||||
<xsd:attribute name="val" type="ST_Script"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Style">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="p"/>
|
||||
<xsd:enumeration value="b"/>
|
||||
<xsd:enumeration value="i"/>
|
||||
<xsd:enumeration value="bi"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Style">
|
||||
<xsd:attribute name="val" type="ST_Style"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ManualBreak">
|
||||
<xsd:attribute name="alnAt" type="ST_Integer255"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ScriptStyle">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="scr" minOccurs="0" type="CT_Script"/>
|
||||
<xsd:element name="sty" minOccurs="0" type="CT_Style"/>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_RPR">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="lit" minOccurs="0" type="CT_OnOff"/>
|
||||
<xsd:choice>
|
||||
<xsd:element name="nor" minOccurs="0" type="CT_OnOff"/>
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ScriptStyle"/>
|
||||
</xsd:sequence>
|
||||
</xsd:choice>
|
||||
<xsd:element name="brk" minOccurs="0" type="CT_ManualBreak"/>
|
||||
<xsd:element name="aln" minOccurs="0" type="CT_OnOff"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Text">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="s:ST_String">
|
||||
<xsd:attribute ref="xml:space" use="optional"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_R">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="rPr" type="CT_RPR" minOccurs="0"/>
|
||||
<xsd:group ref="w:EG_RPr" minOccurs="0"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:group ref="w:EG_RunInnerContent"/>
|
||||
<xsd:element name="t" type="CT_Text" minOccurs="0"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_CtrlPr">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="w:EG_RPrMath" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_AccPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="chr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Acc">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="accPr" type="CT_AccPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_BarPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="pos" type="CT_TopBot" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Bar">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="barPr" type="CT_BarPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_BoxPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="opEmu" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="noBreak" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="diff" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="brk" type="CT_ManualBreak" minOccurs="0"/>
|
||||
<xsd:element name="aln" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Box">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="boxPr" type="CT_BoxPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_BorderBoxPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="hideTop" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="hideBot" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="hideLeft" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="hideRight" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="strikeH" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="strikeV" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="strikeBLTR" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="strikeTLBR" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_BorderBox">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="borderBoxPr" type="CT_BorderBoxPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_DPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="begChr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="sepChr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="endChr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="grow" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="shp" type="CT_Shp" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_D">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="dPr" type="CT_DPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_EqArrPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="baseJc" type="CT_YAlign" minOccurs="0"/>
|
||||
<xsd:element name="maxDist" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="objDist" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="rSpRule" type="CT_SpacingRule" minOccurs="0"/>
|
||||
<xsd:element name="rSp" type="CT_UnSignedInteger" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_EqArr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="eqArrPr" type="CT_EqArrPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_FPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="type" type="CT_FType" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_F">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="fPr" type="CT_FPr" minOccurs="0"/>
|
||||
<xsd:element name="num" type="CT_OMathArg"/>
|
||||
<xsd:element name="den" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_FuncPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Func">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="funcPr" type="CT_FuncPr" minOccurs="0"/>
|
||||
<xsd:element name="fName" type="CT_OMathArg"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupChrPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="chr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="pos" type="CT_TopBot" minOccurs="0"/>
|
||||
<xsd:element name="vertJc" type="CT_TopBot" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GroupChr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="groupChrPr" type="CT_GroupChrPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LimLowPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LimLow">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="limLowPr" type="CT_LimLowPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
<xsd:element name="lim" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LimUppPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LimUpp">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="limUppPr" type="CT_LimUppPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
<xsd:element name="lim" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MCPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="count" type="CT_Integer255" minOccurs="0"/>
|
||||
<xsd:element name="mcJc" type="CT_XAlign" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MC">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="mcPr" type="CT_MCPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MCS">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="mc" type="CT_MC" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="baseJc" type="CT_YAlign" minOccurs="0"/>
|
||||
<xsd:element name="plcHide" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="rSpRule" type="CT_SpacingRule" minOccurs="0"/>
|
||||
<xsd:element name="cGpRule" type="CT_SpacingRule" minOccurs="0"/>
|
||||
<xsd:element name="rSp" type="CT_UnSignedInteger" minOccurs="0"/>
|
||||
<xsd:element name="cSp" type="CT_UnSignedInteger" minOccurs="0"/>
|
||||
<xsd:element name="cGp" type="CT_UnSignedInteger" minOccurs="0"/>
|
||||
<xsd:element name="mcs" type="CT_MCS" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MR">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="e" type="CT_OMathArg" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_M">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="mPr" type="CT_MPr" minOccurs="0"/>
|
||||
<xsd:element name="mr" type="CT_MR" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_NaryPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="chr" type="CT_Char" minOccurs="0"/>
|
||||
<xsd:element name="limLoc" type="CT_LimLoc" minOccurs="0"/>
|
||||
<xsd:element name="grow" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="subHide" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="supHide" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Nary">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="naryPr" type="CT_NaryPr" minOccurs="0"/>
|
||||
<xsd:element name="sub" type="CT_OMathArg"/>
|
||||
<xsd:element name="sup" type="CT_OMathArg"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PhantPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="show" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="zeroWid" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="zeroAsc" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="zeroDesc" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="transp" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Phant">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="phantPr" type="CT_PhantPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_RadPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="degHide" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Rad">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="radPr" type="CT_RadPr" minOccurs="0"/>
|
||||
<xsd:element name="deg" type="CT_OMathArg"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SPrePr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SPre">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sPrePr" type="CT_SPrePr" minOccurs="0"/>
|
||||
<xsd:element name="sub" type="CT_OMathArg"/>
|
||||
<xsd:element name="sup" type="CT_OMathArg"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSubPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSub">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sSubPr" type="CT_SSubPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
<xsd:element name="sub" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSubSupPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="alnScr" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSubSup">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sSubSupPr" type="CT_SSubSupPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
<xsd:element name="sub" type="CT_OMathArg"/>
|
||||
<xsd:element name="sup" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSupPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SSup">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sSupPr" type="CT_SSupPr" minOccurs="0"/>
|
||||
<xsd:element name="e" type="CT_OMathArg"/>
|
||||
<xsd:element name="sup" type="CT_OMathArg"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_OMathMathElements">
|
||||
<xsd:choice>
|
||||
<xsd:element name="acc" type="CT_Acc"/>
|
||||
<xsd:element name="bar" type="CT_Bar"/>
|
||||
<xsd:element name="box" type="CT_Box"/>
|
||||
<xsd:element name="borderBox" type="CT_BorderBox"/>
|
||||
<xsd:element name="d" type="CT_D"/>
|
||||
<xsd:element name="eqArr" type="CT_EqArr"/>
|
||||
<xsd:element name="f" type="CT_F"/>
|
||||
<xsd:element name="func" type="CT_Func"/>
|
||||
<xsd:element name="groupChr" type="CT_GroupChr"/>
|
||||
<xsd:element name="limLow" type="CT_LimLow"/>
|
||||
<xsd:element name="limUpp" type="CT_LimUpp"/>
|
||||
<xsd:element name="m" type="CT_M"/>
|
||||
<xsd:element name="nary" type="CT_Nary"/>
|
||||
<xsd:element name="phant" type="CT_Phant"/>
|
||||
<xsd:element name="rad" type="CT_Rad"/>
|
||||
<xsd:element name="sPre" type="CT_SPre"/>
|
||||
<xsd:element name="sSub" type="CT_SSub"/>
|
||||
<xsd:element name="sSubSup" type="CT_SSubSup"/>
|
||||
<xsd:element name="sSup" type="CT_SSup"/>
|
||||
<xsd:element name="r" type="CT_R"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:group name="EG_OMathElements">
|
||||
<xsd:choice>
|
||||
<xsd:group ref="EG_OMathMathElements"/>
|
||||
<xsd:group ref="w:EG_PContentMath"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_OMathArgPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="argSz" type="CT_Integer2" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OMathArg">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="argPr" type="CT_OMathArgPr" minOccurs="0"/>
|
||||
<xsd:group ref="EG_OMathElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="ctrlPr" type="CT_CtrlPr" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Jc">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="centerGroup"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_OMathJc">
|
||||
<xsd:attribute name="val" type="ST_Jc"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OMathParaPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="jc" type="CT_OMathJc" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_TwipsMeasure">
|
||||
<xsd:attribute name="val" type="s:ST_TwipsMeasure" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_BreakBin">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="before"/>
|
||||
<xsd:enumeration value="after"/>
|
||||
<xsd:enumeration value="repeat"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_BreakBin">
|
||||
<xsd:attribute name="val" type="ST_BreakBin"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_BreakBinSub">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="--"/>
|
||||
<xsd:enumeration value="-+"/>
|
||||
<xsd:enumeration value="+-"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_BreakBinSub">
|
||||
<xsd:attribute name="val" type="ST_BreakBinSub"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_MathPr">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="mathFont" type="CT_String" minOccurs="0"/>
|
||||
<xsd:element name="brkBin" type="CT_BreakBin" minOccurs="0"/>
|
||||
<xsd:element name="brkBinSub" type="CT_BreakBinSub" minOccurs="0"/>
|
||||
<xsd:element name="smallFrac" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="dispDef" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="lMargin" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:element name="rMargin" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:element name="defJc" type="CT_OMathJc" minOccurs="0"/>
|
||||
<xsd:element name="preSp" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:element name="postSp" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:element name="interSp" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:element name="intraSp" type="CT_TwipsMeasure" minOccurs="0"/>
|
||||
<xsd:choice minOccurs="0">
|
||||
<xsd:element name="wrapIndent" type="CT_TwipsMeasure"/>
|
||||
<xsd:element name="wrapRight" type="CT_OnOff"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="intLim" type="CT_LimLoc" minOccurs="0"/>
|
||||
<xsd:element name="naryLim" type="CT_LimLoc" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="mathPr" type="CT_MathPr"/>
|
||||
<xsd:complexType name="CT_OMathPara">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="oMathParaPr" type="CT_OMathParaPr" minOccurs="0"/>
|
||||
<xsd:element name="oMath" type="CT_OMath" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OMath">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_OMathElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="oMathPara" type="CT_OMathPara"/>
|
||||
<xsd:element name="oMath" type="CT_OMath"/>
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
elementFormDefault="qualified"
|
||||
targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
blockDefault="#all">
|
||||
<xsd:simpleType name="ST_RelationshipId">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:attribute name="id" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="embed" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="link" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="dm" type="ST_RelationshipId" default=""/>
|
||||
<xsd:attribute name="lo" type="ST_RelationshipId" default=""/>
|
||||
<xsd:attribute name="qs" type="ST_RelationshipId" default=""/>
|
||||
<xsd:attribute name="cs" type="ST_RelationshipId" default=""/>
|
||||
<xsd:attribute name="blip" type="ST_RelationshipId" default=""/>
|
||||
<xsd:attribute name="pict" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="href" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="topLeft" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="topRight" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="bottomLeft" type="ST_RelationshipId"/>
|
||||
<xsd:attribute name="bottomRight" type="ST_RelationshipId"/>
|
||||
</xsd:schema>
|
||||
4439
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd
Executable file
4439
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd
Executable file
File diff suppressed because it is too large
Load Diff
570
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd
Executable file
570
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd
Executable file
@@ -0,0 +1,570 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:schemas-microsoft-com:vml"
|
||||
xmlns:pvml="urn:schemas-microsoft-com:office:powerpoint"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
xmlns:w10="urn:schemas-microsoft-com:office:word"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="urn:schemas-microsoft-com:vml" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
<xsd:import namespace="urn:schemas-microsoft-com:office:office"
|
||||
schemaLocation="vml-officeDrawing.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
schemaLocation="wml.xsd"/>
|
||||
<xsd:import namespace="urn:schemas-microsoft-com:office:word"
|
||||
schemaLocation="vml-wordprocessingDrawing.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
schemaLocation="shared-relationshipReference.xsd"/>
|
||||
<xsd:import namespace="urn:schemas-microsoft-com:office:excel"
|
||||
schemaLocation="vml-spreadsheetDrawing.xsd"/>
|
||||
<xsd:import namespace="urn:schemas-microsoft-com:office:powerpoint"
|
||||
schemaLocation="vml-presentationDrawing.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:attributeGroup name="AG_Id">
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Style">
|
||||
<xsd:attribute name="style" type="xsd:string" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Type">
|
||||
<xsd:attribute name="type" type="xsd:string" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Adj">
|
||||
<xsd:attribute name="adj" type="xsd:string" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Path">
|
||||
<xsd:attribute name="path" type="xsd:string" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Fill">
|
||||
<xsd:attribute name="filled" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="fillcolor" type="s:ST_ColorType" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Chromakey">
|
||||
<xsd:attribute name="chromakey" type="s:ST_ColorType" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_Ext">
|
||||
<xsd:attribute name="ext" form="qualified" type="ST_Ext"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_CoreAttributes">
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_Style"/>
|
||||
<xsd:attribute name="href" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="target" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="class" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="title" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="alt" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="coordsize" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="coordorigin" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="wrapcoords" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="print" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_ShapeAttributes">
|
||||
<xsd:attributeGroup ref="AG_Chromakey"/>
|
||||
<xsd:attributeGroup ref="AG_Fill"/>
|
||||
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="stroked" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="strokecolor" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="strokeweight" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="insetpen" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_OfficeCoreAttributes">
|
||||
<xsd:attribute ref="o:spid"/>
|
||||
<xsd:attribute ref="o:oned"/>
|
||||
<xsd:attribute ref="o:regroupid"/>
|
||||
<xsd:attribute ref="o:doubleclicknotify"/>
|
||||
<xsd:attribute ref="o:button"/>
|
||||
<xsd:attribute ref="o:userhidden"/>
|
||||
<xsd:attribute ref="o:bullet"/>
|
||||
<xsd:attribute ref="o:hr"/>
|
||||
<xsd:attribute ref="o:hrstd"/>
|
||||
<xsd:attribute ref="o:hrnoshade"/>
|
||||
<xsd:attribute ref="o:hrpct"/>
|
||||
<xsd:attribute ref="o:hralign"/>
|
||||
<xsd:attribute ref="o:allowincell"/>
|
||||
<xsd:attribute ref="o:allowoverlap"/>
|
||||
<xsd:attribute ref="o:userdrawn"/>
|
||||
<xsd:attribute ref="o:bordertopcolor"/>
|
||||
<xsd:attribute ref="o:borderleftcolor"/>
|
||||
<xsd:attribute ref="o:borderbottomcolor"/>
|
||||
<xsd:attribute ref="o:borderrightcolor"/>
|
||||
<xsd:attribute ref="o:dgmlayout"/>
|
||||
<xsd:attribute ref="o:dgmnodekind"/>
|
||||
<xsd:attribute ref="o:dgmlayoutmru"/>
|
||||
<xsd:attribute ref="o:insetmode"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_OfficeShapeAttributes">
|
||||
<xsd:attribute ref="o:spt"/>
|
||||
<xsd:attribute ref="o:connectortype"/>
|
||||
<xsd:attribute ref="o:bwmode"/>
|
||||
<xsd:attribute ref="o:bwpure"/>
|
||||
<xsd:attribute ref="o:bwnormal"/>
|
||||
<xsd:attribute ref="o:forcedash"/>
|
||||
<xsd:attribute ref="o:oleicon"/>
|
||||
<xsd:attribute ref="o:ole"/>
|
||||
<xsd:attribute ref="o:preferrelative"/>
|
||||
<xsd:attribute ref="o:cliptowrap"/>
|
||||
<xsd:attribute ref="o:clip"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_AllCoreAttributes">
|
||||
<xsd:attributeGroup ref="AG_CoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_OfficeCoreAttributes"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_AllShapeAttributes">
|
||||
<xsd:attributeGroup ref="AG_ShapeAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_OfficeShapeAttributes"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_ImageAttributes">
|
||||
<xsd:attribute name="src" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="cropleft" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="croptop" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="cropright" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="cropbottom" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="gain" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="blacklevel" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="gamma" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="grayscale" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="bilevel" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attributeGroup name="AG_StrokeAttributes">
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="weight" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="linestyle" type="ST_StrokeLineStyle" use="optional"/>
|
||||
<xsd:attribute name="miterlimit" type="xsd:decimal" use="optional"/>
|
||||
<xsd:attribute name="joinstyle" type="ST_StrokeJoinStyle" use="optional"/>
|
||||
<xsd:attribute name="endcap" type="ST_StrokeEndCap" use="optional"/>
|
||||
<xsd:attribute name="dashstyle" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="filltype" type="ST_FillType" use="optional"/>
|
||||
<xsd:attribute name="src" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="imageaspect" type="ST_ImageAspect" use="optional"/>
|
||||
<xsd:attribute name="imagesize" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="imagealignshape" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="startarrow" type="ST_StrokeArrowType" use="optional"/>
|
||||
<xsd:attribute name="startarrowwidth" type="ST_StrokeArrowWidth" use="optional"/>
|
||||
<xsd:attribute name="startarrowlength" type="ST_StrokeArrowLength" use="optional"/>
|
||||
<xsd:attribute name="endarrow" type="ST_StrokeArrowType" use="optional"/>
|
||||
<xsd:attribute name="endarrowwidth" type="ST_StrokeArrowWidth" use="optional"/>
|
||||
<xsd:attribute name="endarrowlength" type="ST_StrokeArrowLength" use="optional"/>
|
||||
<xsd:attribute ref="o:href"/>
|
||||
<xsd:attribute ref="o:althref"/>
|
||||
<xsd:attribute ref="o:title"/>
|
||||
<xsd:attribute ref="o:forcedash"/>
|
||||
<xsd:attribute ref="r:id" use="optional"/>
|
||||
<xsd:attribute name="insetpen" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute ref="o:relid"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:group name="EG_ShapeElements">
|
||||
<xsd:choice>
|
||||
<xsd:element ref="path"/>
|
||||
<xsd:element ref="formulas"/>
|
||||
<xsd:element ref="handles"/>
|
||||
<xsd:element ref="fill"/>
|
||||
<xsd:element ref="stroke"/>
|
||||
<xsd:element ref="shadow"/>
|
||||
<xsd:element ref="textbox"/>
|
||||
<xsd:element ref="textpath"/>
|
||||
<xsd:element ref="imagedata"/>
|
||||
<xsd:element ref="o:skew"/>
|
||||
<xsd:element ref="o:extrusion"/>
|
||||
<xsd:element ref="o:callout"/>
|
||||
<xsd:element ref="o:lock"/>
|
||||
<xsd:element ref="o:clippath"/>
|
||||
<xsd:element ref="o:signatureline"/>
|
||||
<xsd:element ref="w10:wrap"/>
|
||||
<xsd:element ref="w10:anchorlock"/>
|
||||
<xsd:element ref="w10:bordertop"/>
|
||||
<xsd:element ref="w10:borderbottom"/>
|
||||
<xsd:element ref="w10:borderleft"/>
|
||||
<xsd:element ref="w10:borderright"/>
|
||||
<xsd:element ref="x:ClientData" minOccurs="0"/>
|
||||
<xsd:element ref="pvml:textdata" minOccurs="0"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:element name="shape" type="CT_Shape"/>
|
||||
<xsd:element name="shapetype" type="CT_Shapetype"/>
|
||||
<xsd:element name="group" type="CT_Group"/>
|
||||
<xsd:element name="background" type="CT_Background"/>
|
||||
<xsd:complexType name="CT_Shape">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements"/>
|
||||
<xsd:element ref="o:ink"/>
|
||||
<xsd:element ref="pvml:iscomment"/>
|
||||
<xsd:element ref="o:equationxml"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_Type"/>
|
||||
<xsd:attributeGroup ref="AG_Adj"/>
|
||||
<xsd:attributeGroup ref="AG_Path"/>
|
||||
<xsd:attribute ref="o:gfxdata"/>
|
||||
<xsd:attribute name="equationxml" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Shapetype">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element ref="o:complex" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_Adj"/>
|
||||
<xsd:attributeGroup ref="AG_Path"/>
|
||||
<xsd:attribute ref="o:master"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Group">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements"/>
|
||||
<xsd:element ref="group"/>
|
||||
<xsd:element ref="shape"/>
|
||||
<xsd:element ref="shapetype"/>
|
||||
<xsd:element ref="arc"/>
|
||||
<xsd:element ref="curve"/>
|
||||
<xsd:element ref="image"/>
|
||||
<xsd:element ref="line"/>
|
||||
<xsd:element ref="oval"/>
|
||||
<xsd:element ref="polyline"/>
|
||||
<xsd:element ref="rect"/>
|
||||
<xsd:element ref="roundrect"/>
|
||||
<xsd:element ref="o:diagram"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_Fill"/>
|
||||
<xsd:attribute name="editas" type="ST_EditAs" use="optional"/>
|
||||
<xsd:attribute ref="o:tableproperties"/>
|
||||
<xsd:attribute ref="o:tablelimits"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Background">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="fill" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_Fill"/>
|
||||
<xsd:attribute ref="o:bwmode"/>
|
||||
<xsd:attribute ref="o:bwpure"/>
|
||||
<xsd:attribute ref="o:bwnormal"/>
|
||||
<xsd:attribute ref="o:targetscreensize"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="fill" type="CT_Fill"/>
|
||||
<xsd:element name="formulas" type="CT_Formulas"/>
|
||||
<xsd:element name="handles" type="CT_Handles"/>
|
||||
<xsd:element name="imagedata" type="CT_ImageData"/>
|
||||
<xsd:element name="path" type="CT_Path"/>
|
||||
<xsd:element name="textbox" type="CT_Textbox"/>
|
||||
<xsd:element name="shadow" type="CT_Shadow"/>
|
||||
<xsd:element name="stroke" type="CT_Stroke"/>
|
||||
<xsd:element name="textpath" type="CT_TextPath"/>
|
||||
<xsd:complexType name="CT_Fill">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="o:fill" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attribute name="type" type="ST_FillType" use="optional"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="src" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute ref="o:href"/>
|
||||
<xsd:attribute ref="o:althref"/>
|
||||
<xsd:attribute name="size" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="origin" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="position" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="aspect" type="ST_ImageAspect" use="optional"/>
|
||||
<xsd:attribute name="colors" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="angle" type="xsd:decimal" use="optional"/>
|
||||
<xsd:attribute name="alignshape" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="focus" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="focussize" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="focusposition" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="method" type="ST_FillMethod" use="optional"/>
|
||||
<xsd:attribute ref="o:detectmouseclick"/>
|
||||
<xsd:attribute ref="o:title"/>
|
||||
<xsd:attribute ref="o:opacity2"/>
|
||||
<xsd:attribute name="recolor" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="rotate" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute ref="r:id" use="optional"/>
|
||||
<xsd:attribute ref="o:relid" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Formulas">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="f" type="CT_F" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_F">
|
||||
<xsd:attribute name="eqn" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Handles">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="h" type="CT_H" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_H">
|
||||
<xsd:attribute name="position" type="xsd:string"/>
|
||||
<xsd:attribute name="polar" type="xsd:string"/>
|
||||
<xsd:attribute name="map" type="xsd:string"/>
|
||||
<xsd:attribute name="invx" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="invy" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="switch" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:attribute name="xrange" type="xsd:string"/>
|
||||
<xsd:attribute name="yrange" type="xsd:string"/>
|
||||
<xsd:attribute name="radiusrange" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ImageData">
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_ImageAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_Chromakey"/>
|
||||
<xsd:attribute name="embosscolor" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="recolortarget" type="s:ST_ColorType"/>
|
||||
<xsd:attribute ref="o:href"/>
|
||||
<xsd:attribute ref="o:althref"/>
|
||||
<xsd:attribute ref="o:title"/>
|
||||
<xsd:attribute ref="o:oleid"/>
|
||||
<xsd:attribute ref="o:detectmouseclick"/>
|
||||
<xsd:attribute ref="o:movie"/>
|
||||
<xsd:attribute ref="o:relid"/>
|
||||
<xsd:attribute ref="r:id"/>
|
||||
<xsd:attribute ref="r:pict"/>
|
||||
<xsd:attribute ref="r:href"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Path">
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attribute name="v" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="limo" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="textboxrect" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fillok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="strokeok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="shadowok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="arrowok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="gradientshapeok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="textpathok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="insetpenok" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute ref="o:connecttype"/>
|
||||
<xsd:attribute ref="o:connectlocs"/>
|
||||
<xsd:attribute ref="o:connectangles"/>
|
||||
<xsd:attribute ref="o:extrusionok"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Shadow">
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="type" type="ST_ShadowType" use="optional"/>
|
||||
<xsd:attribute name="obscured" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="offset" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="offset2" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="origin" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="matrix" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Stroke">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="o:left" minOccurs="0"/>
|
||||
<xsd:element ref="o:top" minOccurs="0"/>
|
||||
<xsd:element ref="o:right" minOccurs="0"/>
|
||||
<xsd:element ref="o:bottom" minOccurs="0"/>
|
||||
<xsd:element ref="o:column" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_StrokeAttributes"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Textbox">
|
||||
<xsd:choice>
|
||||
<xsd:element ref="w:txbxContent" minOccurs="0"/>
|
||||
<xsd:any namespace="##local" processContents="skip"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_Style"/>
|
||||
<xsd:attribute name="inset" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute ref="o:singleclick"/>
|
||||
<xsd:attribute ref="o:insetmode"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_TextPath">
|
||||
<xsd:attributeGroup ref="AG_Id"/>
|
||||
<xsd:attributeGroup ref="AG_Style"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="fitshape" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="fitpath" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="trim" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="xscale" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="string" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="arc" type="CT_Arc"/>
|
||||
<xsd:element name="curve" type="CT_Curve"/>
|
||||
<xsd:element name="image" type="CT_Image"/>
|
||||
<xsd:element name="line" type="CT_Line"/>
|
||||
<xsd:element name="oval" type="CT_Oval"/>
|
||||
<xsd:element name="polyline" type="CT_PolyLine"/>
|
||||
<xsd:element name="rect" type="CT_Rect"/>
|
||||
<xsd:element name="roundrect" type="CT_RoundRect"/>
|
||||
<xsd:complexType name="CT_Arc">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attribute name="startAngle" type="xsd:decimal" use="optional"/>
|
||||
<xsd:attribute name="endAngle" type="xsd:decimal" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Curve">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attribute name="from" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="control1" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="control2" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="to" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Image">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_ImageAttributes"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Line">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attribute name="from" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="to" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Oval">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PolyLine">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements"/>
|
||||
<xsd:element ref="o:ink"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attribute name="points" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Rect">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_RoundRect">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:group ref="EG_ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="AG_AllCoreAttributes"/>
|
||||
<xsd:attributeGroup ref="AG_AllShapeAttributes"/>
|
||||
<xsd:attribute name="arcsize" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Ext">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="view"/>
|
||||
<xsd:enumeration value="edit"/>
|
||||
<xsd:enumeration value="backwardCompatible"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_FillType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="solid"/>
|
||||
<xsd:enumeration value="gradient"/>
|
||||
<xsd:enumeration value="gradientRadial"/>
|
||||
<xsd:enumeration value="tile"/>
|
||||
<xsd:enumeration value="pattern"/>
|
||||
<xsd:enumeration value="frame"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_FillMethod">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="linear"/>
|
||||
<xsd:enumeration value="sigma"/>
|
||||
<xsd:enumeration value="any"/>
|
||||
<xsd:enumeration value="linear sigma"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ShadowType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="single"/>
|
||||
<xsd:enumeration value="double"/>
|
||||
<xsd:enumeration value="emboss"/>
|
||||
<xsd:enumeration value="perspective"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeLineStyle">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="single"/>
|
||||
<xsd:enumeration value="thinThin"/>
|
||||
<xsd:enumeration value="thinThick"/>
|
||||
<xsd:enumeration value="thickThin"/>
|
||||
<xsd:enumeration value="thickBetweenThin"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeJoinStyle">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="round"/>
|
||||
<xsd:enumeration value="bevel"/>
|
||||
<xsd:enumeration value="miter"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeEndCap">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="flat"/>
|
||||
<xsd:enumeration value="square"/>
|
||||
<xsd:enumeration value="round"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeArrowLength">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="short"/>
|
||||
<xsd:enumeration value="medium"/>
|
||||
<xsd:enumeration value="long"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeArrowWidth">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="narrow"/>
|
||||
<xsd:enumeration value="medium"/>
|
||||
<xsd:enumeration value="wide"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_StrokeArrowType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="block"/>
|
||||
<xsd:enumeration value="classic"/>
|
||||
<xsd:enumeration value="oval"/>
|
||||
<xsd:enumeration value="diamond"/>
|
||||
<xsd:enumeration value="open"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ImageAspect">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="ignore"/>
|
||||
<xsd:enumeration value="atMost"/>
|
||||
<xsd:enumeration value="atLeast"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_EditAs">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="canvas"/>
|
||||
<xsd:enumeration value="orgchart"/>
|
||||
<xsd:enumeration value="radial"/>
|
||||
<xsd:enumeration value="cycle"/>
|
||||
<xsd:enumeration value="stacked"/>
|
||||
<xsd:enumeration value="venn"/>
|
||||
<xsd:enumeration value="bullseye"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
509
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd
Executable file
509
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd
Executable file
@@ -0,0 +1,509 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="urn:schemas-microsoft-com:office:office" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
<xsd:import namespace="urn:schemas-microsoft-com:vml" schemaLocation="vml-main.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
schemaLocation="shared-relationshipReference.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:attribute name="bwmode" type="ST_BWMode"/>
|
||||
<xsd:attribute name="bwpure" type="ST_BWMode"/>
|
||||
<xsd:attribute name="bwnormal" type="ST_BWMode"/>
|
||||
<xsd:attribute name="targetscreensize" type="ST_ScreenSize"/>
|
||||
<xsd:attribute name="insetmode" type="ST_InsetMode" default="custom"/>
|
||||
<xsd:attribute name="spt" type="xsd:float"/>
|
||||
<xsd:attribute name="wrapcoords" type="xsd:string"/>
|
||||
<xsd:attribute name="oned" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="regroupid" type="xsd:integer"/>
|
||||
<xsd:attribute name="doubleclicknotify" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="connectortype" type="ST_ConnectorType" default="straight"/>
|
||||
<xsd:attribute name="button" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="userhidden" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="forcedash" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="oleicon" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="ole" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:attribute name="preferrelative" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="cliptowrap" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="clip" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="bullet" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="hr" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="hrstd" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="hrnoshade" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="hrpct" type="xsd:float"/>
|
||||
<xsd:attribute name="hralign" type="ST_HrAlign" default="left"/>
|
||||
<xsd:attribute name="allowincell" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="allowoverlap" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="userdrawn" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="bordertopcolor" type="xsd:string"/>
|
||||
<xsd:attribute name="borderleftcolor" type="xsd:string"/>
|
||||
<xsd:attribute name="borderbottomcolor" type="xsd:string"/>
|
||||
<xsd:attribute name="borderrightcolor" type="xsd:string"/>
|
||||
<xsd:attribute name="connecttype" type="ST_ConnectType"/>
|
||||
<xsd:attribute name="connectlocs" type="xsd:string"/>
|
||||
<xsd:attribute name="connectangles" type="xsd:string"/>
|
||||
<xsd:attribute name="master" type="xsd:string"/>
|
||||
<xsd:attribute name="extrusionok" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="href" type="xsd:string"/>
|
||||
<xsd:attribute name="althref" type="xsd:string"/>
|
||||
<xsd:attribute name="title" type="xsd:string"/>
|
||||
<xsd:attribute name="singleclick" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="oleid" type="xsd:float"/>
|
||||
<xsd:attribute name="detectmouseclick" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="movie" type="xsd:float"/>
|
||||
<xsd:attribute name="spid" type="xsd:string"/>
|
||||
<xsd:attribute name="opacity2" type="xsd:string"/>
|
||||
<xsd:attribute name="relid" type="r:ST_RelationshipId"/>
|
||||
<xsd:attribute name="dgmlayout" type="ST_DiagramLayout"/>
|
||||
<xsd:attribute name="dgmnodekind" type="xsd:integer"/>
|
||||
<xsd:attribute name="dgmlayoutmru" type="ST_DiagramLayout"/>
|
||||
<xsd:attribute name="gfxdata" type="xsd:base64Binary"/>
|
||||
<xsd:attribute name="tableproperties" type="xsd:string"/>
|
||||
<xsd:attribute name="tablelimits" type="xsd:string"/>
|
||||
<xsd:element name="shapedefaults" type="CT_ShapeDefaults"/>
|
||||
<xsd:element name="shapelayout" type="CT_ShapeLayout"/>
|
||||
<xsd:element name="signatureline" type="CT_SignatureLine"/>
|
||||
<xsd:element name="ink" type="CT_Ink"/>
|
||||
<xsd:element name="diagram" type="CT_Diagram"/>
|
||||
<xsd:element name="equationxml" type="CT_EquationXml"/>
|
||||
<xsd:complexType name="CT_ShapeDefaults">
|
||||
<xsd:all minOccurs="0">
|
||||
<xsd:element ref="v:fill" minOccurs="0"/>
|
||||
<xsd:element ref="v:stroke" minOccurs="0"/>
|
||||
<xsd:element ref="v:textbox" minOccurs="0"/>
|
||||
<xsd:element ref="v:shadow" minOccurs="0"/>
|
||||
<xsd:element ref="skew" minOccurs="0"/>
|
||||
<xsd:element ref="extrusion" minOccurs="0"/>
|
||||
<xsd:element ref="callout" minOccurs="0"/>
|
||||
<xsd:element ref="lock" minOccurs="0"/>
|
||||
<xsd:element name="colormru" minOccurs="0" type="CT_ColorMru"/>
|
||||
<xsd:element name="colormenu" minOccurs="0" type="CT_ColorMenu"/>
|
||||
</xsd:all>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="spidmax" type="xsd:integer" use="optional"/>
|
||||
<xsd:attribute name="style" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="fill" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="fillcolor" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="stroke" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="strokecolor" type="s:ST_ColorType"/>
|
||||
<xsd:attribute name="allowincell" form="qualified" type="s:ST_TrueFalse"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Ink">
|
||||
<xsd:sequence/>
|
||||
<xsd:attribute name="i" type="xsd:string"/>
|
||||
<xsd:attribute name="annotation" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="contentType" type="ST_ContentType" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SignatureLine">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="issignatureline" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="id" type="s:ST_Guid"/>
|
||||
<xsd:attribute name="provid" type="s:ST_Guid"/>
|
||||
<xsd:attribute name="signinginstructionsset" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="allowcomments" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="showsigndate" type="s:ST_TrueFalse"/>
|
||||
<xsd:attribute name="suggestedsigner" type="xsd:string" form="qualified"/>
|
||||
<xsd:attribute name="suggestedsigner2" type="xsd:string" form="qualified"/>
|
||||
<xsd:attribute name="suggestedsigneremail" type="xsd:string" form="qualified"/>
|
||||
<xsd:attribute name="signinginstructions" type="xsd:string"/>
|
||||
<xsd:attribute name="addlxml" type="xsd:string"/>
|
||||
<xsd:attribute name="sigprovurl" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ShapeLayout">
|
||||
<xsd:all>
|
||||
<xsd:element name="idmap" type="CT_IdMap" minOccurs="0"/>
|
||||
<xsd:element name="regrouptable" type="CT_RegroupTable" minOccurs="0"/>
|
||||
<xsd:element name="rules" type="CT_Rules" minOccurs="0"/>
|
||||
</xsd:all>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_IdMap">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="data" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_RegroupTable">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="entry" type="CT_Entry" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Entry">
|
||||
<xsd:attribute name="new" type="xsd:int" use="optional"/>
|
||||
<xsd:attribute name="old" type="xsd:int" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Rules">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="r" type="CT_R" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_R">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="proxy" type="CT_Proxy" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="type" type="ST_RType" use="optional"/>
|
||||
<xsd:attribute name="how" type="ST_How" use="optional"/>
|
||||
<xsd:attribute name="idref" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Proxy">
|
||||
<xsd:attribute name="start" type="s:ST_TrueFalseBlank" use="optional" default="false"/>
|
||||
<xsd:attribute name="end" type="s:ST_TrueFalseBlank" use="optional" default="false"/>
|
||||
<xsd:attribute name="idref" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="connectloc" type="xsd:int" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Diagram">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="relationtable" type="CT_RelationTable" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="dgmstyle" type="xsd:integer" use="optional"/>
|
||||
<xsd:attribute name="autoformat" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="reverse" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="autolayout" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="dgmscalex" type="xsd:integer" use="optional"/>
|
||||
<xsd:attribute name="dgmscaley" type="xsd:integer" use="optional"/>
|
||||
<xsd:attribute name="dgmfontsize" type="xsd:integer" use="optional"/>
|
||||
<xsd:attribute name="constrainbounds" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="dgmbasetextscale" type="xsd:integer" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_EquationXml">
|
||||
<xsd:sequence>
|
||||
<xsd:any namespace="##any"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="contentType" type="ST_AlternateMathContentType" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_AlternateMathContentType">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_RelationTable">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="rel" type="CT_Relation" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Relation">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="idsrc" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="iddest" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="idcntr" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ColorMru">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="colors" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ColorMenu">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="strokecolor" type="s:ST_ColorType"/>
|
||||
<xsd:attribute name="fillcolor" type="s:ST_ColorType"/>
|
||||
<xsd:attribute name="shadowcolor" type="s:ST_ColorType"/>
|
||||
<xsd:attribute name="extrusioncolor" type="s:ST_ColorType"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="skew" type="CT_Skew"/>
|
||||
<xsd:element name="extrusion" type="CT_Extrusion"/>
|
||||
<xsd:element name="callout" type="CT_Callout"/>
|
||||
<xsd:element name="lock" type="CT_Lock"/>
|
||||
<xsd:element name="OLEObject" type="CT_OLEObject"/>
|
||||
<xsd:element name="complex" type="CT_Complex"/>
|
||||
<xsd:element name="left" type="CT_StrokeChild"/>
|
||||
<xsd:element name="top" type="CT_StrokeChild"/>
|
||||
<xsd:element name="right" type="CT_StrokeChild"/>
|
||||
<xsd:element name="bottom" type="CT_StrokeChild"/>
|
||||
<xsd:element name="column" type="CT_StrokeChild"/>
|
||||
<xsd:element name="clippath" type="CT_ClipPath"/>
|
||||
<xsd:element name="fill" type="CT_Fill"/>
|
||||
<xsd:complexType name="CT_Skew">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="offset" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="origin" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="matrix" type="xsd:string" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Extrusion">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="type" type="ST_ExtrusionType" default="parallel" use="optional"/>
|
||||
<xsd:attribute name="render" type="ST_ExtrusionRender" default="solid" use="optional"/>
|
||||
<xsd:attribute name="viewpointorigin" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="viewpoint" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="plane" type="ST_ExtrusionPlane" default="XY" use="optional"/>
|
||||
<xsd:attribute name="skewangle" type="xsd:float" use="optional"/>
|
||||
<xsd:attribute name="skewamt" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="foredepth" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="backdepth" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="orientation" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="orientationangle" type="xsd:float" use="optional"/>
|
||||
<xsd:attribute name="lockrotationcenter" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="autorotationcenter" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="rotationcenter" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="rotationangle" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="colormode" type="ST_ColorMode" use="optional"/>
|
||||
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="shininess" type="xsd:float" use="optional"/>
|
||||
<xsd:attribute name="specularity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="diffusity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="metal" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="edge" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="facet" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightface" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="brightness" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightposition" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightlevel" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightharsh" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="lightposition2" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightlevel2" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lightharsh2" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Callout">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="type" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="gap" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="angle" type="ST_Angle" use="optional"/>
|
||||
<xsd:attribute name="dropauto" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="drop" type="ST_CalloutDrop" use="optional"/>
|
||||
<xsd:attribute name="distance" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="lengthspecified" type="s:ST_TrueFalse" default="f" use="optional"/>
|
||||
<xsd:attribute name="length" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="accentbar" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="textborder" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="minusx" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="minusy" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Lock">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="position" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="selection" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="grouping" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="ungrouping" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="rotation" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="cropping" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="verticies" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="adjusthandles" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="text" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="aspectratio" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="shapetype" type="s:ST_TrueFalse" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_OLEObject">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="LinkType" type="ST_OLELinkType" minOccurs="0"/>
|
||||
<xsd:element name="LockedField" type="s:ST_TrueFalseBlank" minOccurs="0"/>
|
||||
<xsd:element name="FieldCodes" type="xsd:string" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="Type" type="ST_OLEType" use="optional"/>
|
||||
<xsd:attribute name="ProgID" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="ShapeID" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="DrawAspect" type="ST_OLEDrawAspect" use="optional"/>
|
||||
<xsd:attribute name="ObjectID" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute ref="r:id" use="optional"/>
|
||||
<xsd:attribute name="UpdateMode" type="ST_OLEUpdateMode" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Complex">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_StrokeChild">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="on" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="weight" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="color" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="color2" type="s:ST_ColorType" use="optional"/>
|
||||
<xsd:attribute name="opacity" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="linestyle" type="v:ST_StrokeLineStyle" use="optional"/>
|
||||
<xsd:attribute name="miterlimit" type="xsd:decimal" use="optional"/>
|
||||
<xsd:attribute name="joinstyle" type="v:ST_StrokeJoinStyle" use="optional"/>
|
||||
<xsd:attribute name="endcap" type="v:ST_StrokeEndCap" use="optional"/>
|
||||
<xsd:attribute name="dashstyle" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="insetpen" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="filltype" type="v:ST_FillType" use="optional"/>
|
||||
<xsd:attribute name="src" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="imageaspect" type="v:ST_ImageAspect" use="optional"/>
|
||||
<xsd:attribute name="imagesize" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="imagealignshape" type="s:ST_TrueFalse" use="optional"/>
|
||||
<xsd:attribute name="startarrow" type="v:ST_StrokeArrowType" use="optional"/>
|
||||
<xsd:attribute name="startarrowwidth" type="v:ST_StrokeArrowWidth" use="optional"/>
|
||||
<xsd:attribute name="startarrowlength" type="v:ST_StrokeArrowLength" use="optional"/>
|
||||
<xsd:attribute name="endarrow" type="v:ST_StrokeArrowType" use="optional"/>
|
||||
<xsd:attribute name="endarrowwidth" type="v:ST_StrokeArrowWidth" use="optional"/>
|
||||
<xsd:attribute name="endarrowlength" type="v:ST_StrokeArrowLength" use="optional"/>
|
||||
<xsd:attribute ref="href"/>
|
||||
<xsd:attribute ref="althref"/>
|
||||
<xsd:attribute ref="title"/>
|
||||
<xsd:attribute ref="forcedash"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ClipPath">
|
||||
<xsd:attribute name="v" type="xsd:string" use="required" form="qualified"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Fill">
|
||||
<xsd:attributeGroup ref="v:AG_Ext"/>
|
||||
<xsd:attribute name="type" type="ST_FillType"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_RType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="arc"/>
|
||||
<xsd:enumeration value="callout"/>
|
||||
<xsd:enumeration value="connector"/>
|
||||
<xsd:enumeration value="align"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_How">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="top"/>
|
||||
<xsd:enumeration value="middle"/>
|
||||
<xsd:enumeration value="bottom"/>
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_BWMode">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="color"/>
|
||||
<xsd:enumeration value="auto"/>
|
||||
<xsd:enumeration value="grayScale"/>
|
||||
<xsd:enumeration value="lightGrayscale"/>
|
||||
<xsd:enumeration value="inverseGray"/>
|
||||
<xsd:enumeration value="grayOutline"/>
|
||||
<xsd:enumeration value="highContrast"/>
|
||||
<xsd:enumeration value="black"/>
|
||||
<xsd:enumeration value="white"/>
|
||||
<xsd:enumeration value="hide"/>
|
||||
<xsd:enumeration value="undrawn"/>
|
||||
<xsd:enumeration value="blackTextAndLines"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ScreenSize">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="544,376"/>
|
||||
<xsd:enumeration value="640,480"/>
|
||||
<xsd:enumeration value="720,512"/>
|
||||
<xsd:enumeration value="800,600"/>
|
||||
<xsd:enumeration value="1024,768"/>
|
||||
<xsd:enumeration value="1152,862"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_InsetMode">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="auto"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ColorMode">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="auto"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ContentType">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_DiagramLayout">
|
||||
<xsd:restriction base="xsd:integer">
|
||||
<xsd:enumeration value="0"/>
|
||||
<xsd:enumeration value="1"/>
|
||||
<xsd:enumeration value="2"/>
|
||||
<xsd:enumeration value="3"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ExtrusionType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="perspective"/>
|
||||
<xsd:enumeration value="parallel"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ExtrusionRender">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="solid"/>
|
||||
<xsd:enumeration value="wireFrame"/>
|
||||
<xsd:enumeration value="boundingCube"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ExtrusionPlane">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="XY"/>
|
||||
<xsd:enumeration value="ZX"/>
|
||||
<xsd:enumeration value="YZ"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_Angle">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="any"/>
|
||||
<xsd:enumeration value="30"/>
|
||||
<xsd:enumeration value="45"/>
|
||||
<xsd:enumeration value="60"/>
|
||||
<xsd:enumeration value="90"/>
|
||||
<xsd:enumeration value="auto"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_CalloutDrop">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_CalloutPlacement">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="top"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
<xsd:enumeration value="bottom"/>
|
||||
<xsd:enumeration value="user"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ConnectorType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="straight"/>
|
||||
<xsd:enumeration value="elbow"/>
|
||||
<xsd:enumeration value="curved"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_HrAlign">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="center"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ConnectType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="rect"/>
|
||||
<xsd:enumeration value="segments"/>
|
||||
<xsd:enumeration value="custom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OLELinkType">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OLEType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Embed"/>
|
||||
<xsd:enumeration value="Link"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OLEDrawAspect">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Content"/>
|
||||
<xsd:enumeration value="Icon"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_OLEUpdateMode">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Always"/>
|
||||
<xsd:enumeration value="OnCall"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_FillType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="gradientCenter"/>
|
||||
<xsd:enumeration value="solid"/>
|
||||
<xsd:enumeration value="pattern"/>
|
||||
<xsd:enumeration value="tile"/>
|
||||
<xsd:enumeration value="frame"/>
|
||||
<xsd:enumeration value="gradientUnscaled"/>
|
||||
<xsd:enumeration value="gradientRadial"/>
|
||||
<xsd:enumeration value="gradient"/>
|
||||
<xsd:enumeration value="background"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
12
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd
Executable file
12
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd
Executable file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="urn:schemas-microsoft-com:office:powerpoint"
|
||||
targetNamespace="urn:schemas-microsoft-com:office:powerpoint" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
<xsd:element name="iscomment" type="CT_Empty"/>
|
||||
<xsd:element name="textdata" type="CT_Rel"/>
|
||||
<xsd:complexType name="CT_Empty"/>
|
||||
<xsd:complexType name="CT_Rel">
|
||||
<xsd:attribute name="id" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
108
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd
Executable file
108
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd
Executable file
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="urn:schemas-microsoft-com:office:excel"
|
||||
xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
targetNamespace="urn:schemas-microsoft-com:office:excel" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes"
|
||||
schemaLocation="shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:element name="ClientData" type="CT_ClientData"/>
|
||||
<xsd:complexType name="CT_ClientData">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="MoveWithCells" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="SizeWithCells" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Anchor" type="xsd:string"/>
|
||||
<xsd:element name="Locked" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="DefaultSize" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="PrintObject" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Disabled" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="AutoFill" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="AutoLine" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="AutoPict" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="FmlaMacro" type="xsd:string"/>
|
||||
<xsd:element name="TextHAlign" type="xsd:string"/>
|
||||
<xsd:element name="TextVAlign" type="xsd:string"/>
|
||||
<xsd:element name="LockText" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="JustLastX" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="SecretEdit" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Default" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Help" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Cancel" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Dismiss" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Accel" type="xsd:integer"/>
|
||||
<xsd:element name="Accel2" type="xsd:integer"/>
|
||||
<xsd:element name="Row" type="xsd:integer"/>
|
||||
<xsd:element name="Column" type="xsd:integer"/>
|
||||
<xsd:element name="Visible" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="RowHidden" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="ColHidden" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="VTEdit" type="xsd:integer"/>
|
||||
<xsd:element name="MultiLine" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="VScroll" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="ValidIds" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="FmlaRange" type="xsd:string"/>
|
||||
<xsd:element name="WidthMin" type="xsd:integer"/>
|
||||
<xsd:element name="Sel" type="xsd:integer"/>
|
||||
<xsd:element name="NoThreeD2" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="SelType" type="xsd:string"/>
|
||||
<xsd:element name="MultiSel" type="xsd:string"/>
|
||||
<xsd:element name="LCT" type="xsd:string"/>
|
||||
<xsd:element name="ListItem" type="xsd:string"/>
|
||||
<xsd:element name="DropStyle" type="xsd:string"/>
|
||||
<xsd:element name="Colored" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="DropLines" type="xsd:integer"/>
|
||||
<xsd:element name="Checked" type="xsd:integer"/>
|
||||
<xsd:element name="FmlaLink" type="xsd:string"/>
|
||||
<xsd:element name="FmlaPict" type="xsd:string"/>
|
||||
<xsd:element name="NoThreeD" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="FirstButton" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="FmlaGroup" type="xsd:string"/>
|
||||
<xsd:element name="Val" type="xsd:integer"/>
|
||||
<xsd:element name="Min" type="xsd:integer"/>
|
||||
<xsd:element name="Max" type="xsd:integer"/>
|
||||
<xsd:element name="Inc" type="xsd:integer"/>
|
||||
<xsd:element name="Page" type="xsd:integer"/>
|
||||
<xsd:element name="Horiz" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="Dx" type="xsd:integer"/>
|
||||
<xsd:element name="MapOCX" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="CF" type="ST_CF"/>
|
||||
<xsd:element name="Camera" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="RecalcAlways" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="AutoScale" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="DDE" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="UIObj" type="s:ST_TrueFalseBlank"/>
|
||||
<xsd:element name="ScriptText" type="xsd:string"/>
|
||||
<xsd:element name="ScriptExtended" type="xsd:string"/>
|
||||
<xsd:element name="ScriptLanguage" type="xsd:nonNegativeInteger"/>
|
||||
<xsd:element name="ScriptLocation" type="xsd:nonNegativeInteger"/>
|
||||
<xsd:element name="FmlaTxbx" type="xsd:string"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="ObjectType" type="ST_ObjectType" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_CF">
|
||||
<xsd:restriction base="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_ObjectType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Button"/>
|
||||
<xsd:enumeration value="Checkbox"/>
|
||||
<xsd:enumeration value="Dialog"/>
|
||||
<xsd:enumeration value="Drop"/>
|
||||
<xsd:enumeration value="Edit"/>
|
||||
<xsd:enumeration value="GBox"/>
|
||||
<xsd:enumeration value="Label"/>
|
||||
<xsd:enumeration value="LineA"/>
|
||||
<xsd:enumeration value="List"/>
|
||||
<xsd:enumeration value="Movie"/>
|
||||
<xsd:enumeration value="Note"/>
|
||||
<xsd:enumeration value="Pict"/>
|
||||
<xsd:enumeration value="Radio"/>
|
||||
<xsd:enumeration value="RectA"/>
|
||||
<xsd:enumeration value="Scroll"/>
|
||||
<xsd:enumeration value="Spin"/>
|
||||
<xsd:enumeration value="Shape"/>
|
||||
<xsd:enumeration value="Group"/>
|
||||
<xsd:enumeration value="Rect"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
96
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd
Executable file
96
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd
Executable file
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="urn:schemas-microsoft-com:office:word"
|
||||
targetNamespace="urn:schemas-microsoft-com:office:word" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
<xsd:element name="bordertop" type="CT_Border"/>
|
||||
<xsd:element name="borderleft" type="CT_Border"/>
|
||||
<xsd:element name="borderright" type="CT_Border"/>
|
||||
<xsd:element name="borderbottom" type="CT_Border"/>
|
||||
<xsd:complexType name="CT_Border">
|
||||
<xsd:attribute name="type" type="ST_BorderType" use="optional"/>
|
||||
<xsd:attribute name="width" type="xsd:positiveInteger" use="optional"/>
|
||||
<xsd:attribute name="shadow" type="ST_BorderShadow" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="wrap" type="CT_Wrap"/>
|
||||
<xsd:complexType name="CT_Wrap">
|
||||
<xsd:attribute name="type" type="ST_WrapType" use="optional"/>
|
||||
<xsd:attribute name="side" type="ST_WrapSide" use="optional"/>
|
||||
<xsd:attribute name="anchorx" type="ST_HorizontalAnchor" use="optional"/>
|
||||
<xsd:attribute name="anchory" type="ST_VerticalAnchor" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="anchorlock" type="CT_AnchorLock"/>
|
||||
<xsd:complexType name="CT_AnchorLock"/>
|
||||
<xsd:simpleType name="ST_BorderType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="single"/>
|
||||
<xsd:enumeration value="thick"/>
|
||||
<xsd:enumeration value="double"/>
|
||||
<xsd:enumeration value="hairline"/>
|
||||
<xsd:enumeration value="dot"/>
|
||||
<xsd:enumeration value="dash"/>
|
||||
<xsd:enumeration value="dotDash"/>
|
||||
<xsd:enumeration value="dashDotDot"/>
|
||||
<xsd:enumeration value="triple"/>
|
||||
<xsd:enumeration value="thinThickSmall"/>
|
||||
<xsd:enumeration value="thickThinSmall"/>
|
||||
<xsd:enumeration value="thickBetweenThinSmall"/>
|
||||
<xsd:enumeration value="thinThick"/>
|
||||
<xsd:enumeration value="thickThin"/>
|
||||
<xsd:enumeration value="thickBetweenThin"/>
|
||||
<xsd:enumeration value="thinThickLarge"/>
|
||||
<xsd:enumeration value="thickThinLarge"/>
|
||||
<xsd:enumeration value="thickBetweenThinLarge"/>
|
||||
<xsd:enumeration value="wave"/>
|
||||
<xsd:enumeration value="doubleWave"/>
|
||||
<xsd:enumeration value="dashedSmall"/>
|
||||
<xsd:enumeration value="dashDotStroked"/>
|
||||
<xsd:enumeration value="threeDEmboss"/>
|
||||
<xsd:enumeration value="threeDEngrave"/>
|
||||
<xsd:enumeration value="HTMLOutset"/>
|
||||
<xsd:enumeration value="HTMLInset"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_BorderShadow">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="t"/>
|
||||
<xsd:enumeration value="true"/>
|
||||
<xsd:enumeration value="f"/>
|
||||
<xsd:enumeration value="false"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_WrapType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="topAndBottom"/>
|
||||
<xsd:enumeration value="square"/>
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="tight"/>
|
||||
<xsd:enumeration value="through"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_WrapSide">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="both"/>
|
||||
<xsd:enumeration value="left"/>
|
||||
<xsd:enumeration value="right"/>
|
||||
<xsd:enumeration value="largest"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_HorizontalAnchor">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="margin"/>
|
||||
<xsd:enumeration value="page"/>
|
||||
<xsd:enumeration value="text"/>
|
||||
<xsd:enumeration value="char"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_VerticalAnchor">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="margin"/>
|
||||
<xsd:enumeration value="page"/>
|
||||
<xsd:enumeration value="text"/>
|
||||
<xsd:enumeration value="line"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
3646
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd
Executable file
3646
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd
Executable file
File diff suppressed because it is too large
Load Diff
116
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd
Executable file
116
skills/ppt/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd
Executable file
@@ -0,0 +1,116 @@
|
||||
<?xml version='1.0'?>
|
||||
<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
|
||||
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
See http://www.w3.org/XML/1998/namespace.html and
|
||||
http://www.w3.org/TR/REC-xml for information about this namespace.
|
||||
|
||||
This schema document describes the XML namespace, in a form
|
||||
suitable for import by other schema documents.
|
||||
|
||||
Note that local names in this namespace are intended to be defined
|
||||
only by the World Wide Web Consortium or its subgroups. The
|
||||
following names are currently defined in this namespace and should
|
||||
not be used with conflicting semantics by any Working Group,
|
||||
specification, or document instance:
|
||||
|
||||
base (as an attribute name): denotes an attribute whose value
|
||||
provides a URI to be used as the base for interpreting any
|
||||
relative URIs in the scope of the element on which it
|
||||
appears; its value is inherited. This name is reserved
|
||||
by virtue of its definition in the XML Base specification.
|
||||
|
||||
lang (as an attribute name): denotes an attribute whose value
|
||||
is a language code for the natural language of the content of
|
||||
any element; its value is inherited. This name is reserved
|
||||
by virtue of its definition in the XML specification.
|
||||
|
||||
space (as an attribute name): denotes an attribute whose
|
||||
value is a keyword indicating what whitespace processing
|
||||
discipline is intended for the content of the element; its
|
||||
value is inherited. This name is reserved by virtue of its
|
||||
definition in the XML specification.
|
||||
|
||||
Father (in any context at all): denotes Jon Bosak, the chair of
|
||||
the original XML Working Group. This name is reserved by
|
||||
the following decision of the W3C XML Plenary and
|
||||
XML Coordination groups:
|
||||
|
||||
In appreciation for his vision, leadership and dedication
|
||||
the W3C XML Plenary on this 10th day of February, 2000
|
||||
reserves for Jon Bosak in perpetuity the XML name
|
||||
xml:Father
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
|
||||
<xs:annotation>
|
||||
<xs:documentation>This schema defines attributes and an attribute group
|
||||
suitable for use by
|
||||
schemas wishing to allow xml:base, xml:lang or xml:space attributes
|
||||
on elements they define.
|
||||
|
||||
To enable this, such a schema must import this schema
|
||||
for the XML namespace, e.g. as follows:
|
||||
<schema . . .>
|
||||
. . .
|
||||
<import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/03/xml.xsd"/>
|
||||
|
||||
Subsequently, qualified reference to any of the attributes
|
||||
or the group defined below will have the desired effect, e.g.
|
||||
|
||||
<type . . .>
|
||||
. . .
|
||||
<attributeGroup ref="xml:specialAttrs"/>
|
||||
|
||||
will define a type which will schema-validate an instance
|
||||
element with any of those attributes</xs:documentation>
|
||||
</xs:annotation>
|
||||
|
||||
<xs:annotation>
|
||||
<xs:documentation>In keeping with the XML Schema WG's standard versioning
|
||||
policy, this schema document will persist at
|
||||
http://www.w3.org/2001/03/xml.xsd.
|
||||
At the date of issue it can also be found at
|
||||
http://www.w3.org/2001/xml.xsd.
|
||||
The schema document at that URI may however change in the future,
|
||||
in order to remain compatible with the latest version of XML Schema
|
||||
itself. In other words, if the XML Schema namespace changes, the version
|
||||
of this document at
|
||||
http://www.w3.org/2001/xml.xsd will change
|
||||
accordingly; the version at
|
||||
http://www.w3.org/2001/03/xml.xsd will not change.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
|
||||
<xs:attribute name="lang" type="xs:language">
|
||||
<xs:annotation>
|
||||
<xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter
|
||||
codes as the enumerated possible values . . .</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
|
||||
<xs:attribute name="space" default="preserve">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:NCName">
|
||||
<xs:enumeration value="default"/>
|
||||
<xs:enumeration value="preserve"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
|
||||
<xs:attribute name="base" type="xs:anyURI">
|
||||
<xs:annotation>
|
||||
<xs:documentation>See http://www.w3.org/TR/xmlbase/ for
|
||||
information about this attribute.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
|
||||
<xs:attributeGroup name="specialAttrs">
|
||||
<xs:attribute ref="xml:base"/>
|
||||
<xs:attribute ref="xml:lang"/>
|
||||
<xs:attribute ref="xml:space"/>
|
||||
</xs:attributeGroup>
|
||||
|
||||
</xs:schema>
|
||||
42
skills/ppt/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd
Executable file
42
skills/ppt/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd
Executable file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<xs:schema xmlns="http://schemas.openxmlformats.org/package/2006/content-types"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://schemas.openxmlformats.org/package/2006/content-types"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all">
|
||||
|
||||
<xs:element name="Types" type="CT_Types"/>
|
||||
<xs:element name="Default" type="CT_Default"/>
|
||||
<xs:element name="Override" type="CT_Override"/>
|
||||
|
||||
<xs:complexType name="CT_Types">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element ref="Default"/>
|
||||
<xs:element ref="Override"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="CT_Default">
|
||||
<xs:attribute name="Extension" type="ST_Extension" use="required"/>
|
||||
<xs:attribute name="ContentType" type="ST_ContentType" use="required"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="CT_Override">
|
||||
<xs:attribute name="ContentType" type="ST_ContentType" use="required"/>
|
||||
<xs:attribute name="PartName" type="xs:anyURI" use="required"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="ST_ContentType">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern
|
||||
value="(((([\p{IsBasicLatin}-[\p{Cc}\(\)<>@,;:\\"/\[\]\?=\{\}\s\t]])+))/((([\p{IsBasicLatin}-[\p{Cc}\(\)<>@,;:\\"/\[\]\?=\{\}\s\t]])+))((\s+)*;(\s+)*(((([\p{IsBasicLatin}-[\p{Cc}\(\)<>@,;:\\"/\[\]\?=\{\}\s\t]])+))=((([\p{IsBasicLatin}-[\p{Cc}\(\)<>@,;:\\"/\[\]\?=\{\}\s\t]])+)|("(([\p{IsLatin-1Supplement}\p{IsBasicLatin}-[\p{Cc}"\n\r]]|(\s+))|(\\[\p{IsBasicLatin}]))*"))))*)"
|
||||
/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="ST_Extension">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern
|
||||
value="([!$&'\(\)\*\+,:=]|(%[0-9a-fA-F][0-9a-fA-F])|[:@]|[a-zA-Z0-9\-_~])+"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:schema>
|
||||
50
skills/ppt/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd
Executable file
50
skills/ppt/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd
Executable file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema targetNamespace="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
|
||||
xmlns="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:dcterms="http://purl.org/dc/terms/" elementFormDefault="qualified" blockDefault="#all">
|
||||
|
||||
<xs:import namespace="http://purl.org/dc/elements/1.1/"
|
||||
schemaLocation="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd"/>
|
||||
<xs:import namespace="http://purl.org/dc/terms/"
|
||||
schemaLocation="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd"/>
|
||||
<xs:import id="xml" namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
|
||||
<xs:element name="coreProperties" type="CT_CoreProperties"/>
|
||||
|
||||
<xs:complexType name="CT_CoreProperties">
|
||||
<xs:all>
|
||||
<xs:element name="category" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
<xs:element name="contentStatus" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
<xs:element ref="dcterms:created" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element ref="dc:creator" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element ref="dc:description" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element ref="dc:identifier" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="keywords" minOccurs="0" maxOccurs="1" type="CT_Keywords"/>
|
||||
<xs:element ref="dc:language" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="lastModifiedBy" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
<xs:element name="lastPrinted" minOccurs="0" maxOccurs="1" type="xs:dateTime"/>
|
||||
<xs:element ref="dcterms:modified" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="revision" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
<xs:element ref="dc:subject" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element ref="dc:title" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="CT_Keywords" mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:element name="value" minOccurs="0" maxOccurs="unbounded" type="CT_Keyword"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute ref="xml:lang" use="optional"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="CT_Keyword">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute ref="xml:lang" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
||||
49
skills/ppt/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd
Executable file
49
skills/ppt/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd
Executable file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsd:schema xmlns="http://schemas.openxmlformats.org/package/2006/digital-signature"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://schemas.openxmlformats.org/package/2006/digital-signature"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all">
|
||||
|
||||
<xsd:element name="SignatureTime" type="CT_SignatureTime"/>
|
||||
<xsd:element name="RelationshipReference" type="CT_RelationshipReference"/>
|
||||
<xsd:element name="RelationshipsGroupReference" type="CT_RelationshipsGroupReference"/>
|
||||
|
||||
<xsd:complexType name="CT_SignatureTime">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Format" type="ST_Format"/>
|
||||
<xsd:element name="Value" type="ST_Value"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="CT_RelationshipReference">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="SourceId" type="xsd:string" use="required"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="CT_RelationshipsGroupReference">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="SourceType" type="xsd:anyURI" use="required"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="ST_Format">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern
|
||||
value="(YYYY)|(YYYY-MM)|(YYYY-MM-DD)|(YYYY-MM-DDThh:mmTZD)|(YYYY-MM-DDThh:mm:ssTZD)|(YYYY-MM-DDThh:mm:ss.sTZD)"
|
||||
/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="ST_Value">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern
|
||||
value="(([0-9][0-9][0-9][0-9]))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):(((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))\.[0-9])(((\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))"
|
||||
/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
33
skills/ppt/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd
Executable file
33
skills/ppt/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd
Executable file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<xsd:schema xmlns="http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all">
|
||||
|
||||
<xsd:element name="Relationships" type="CT_Relationships"/>
|
||||
<xsd:element name="Relationship" type="CT_Relationship"/>
|
||||
|
||||
<xsd:complexType name="CT_Relationships">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="Relationship" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="CT_Relationship">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="TargetMode" type="ST_TargetMode" use="optional"/>
|
||||
<xsd:attribute name="Target" type="xsd:anyURI" use="required"/>
|
||||
<xsd:attribute name="Type" type="xsd:anyURI" use="required"/>
|
||||
<xsd:attribute name="Id" type="xsd:ID" use="required"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="ST_TargetMode">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="External"/>
|
||||
<xsd:enumeration value="Internal"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
75
skills/ppt/ooxml/schemas/mce/mc.xsd
Executable file
75
skills/ppt/ooxml/schemas/mce/mc.xsd
Executable file
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsd:schema xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
attributeFormDefault="unqualified" elementFormDefault="qualified"
|
||||
targetNamespace="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<!--
|
||||
This XSD is a modified version of the one found at:
|
||||
https://github.com/plutext/docx4j/blob/master/xsd/mce/markup-compatibility-2006-MINIMAL.xsd
|
||||
|
||||
This XSD has 2 objectives:
|
||||
|
||||
1. round tripping @mc:Ignorable
|
||||
|
||||
<w:document
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
mc:Ignorable="w14 w15 wp14">
|
||||
|
||||
2. enabling AlternateContent to be manipulated in certain elements
|
||||
(in the unusual case where the content model is xsd:any, it doesn't have to be explicitly added)
|
||||
|
||||
See further ECMA-376, 4th Edition, Office Open XML File Formats
|
||||
Part 3 : Markup Compatibility and Extensibility
|
||||
-->
|
||||
|
||||
<!-- Objective 1 -->
|
||||
<xsd:attribute name="Ignorable" type="xsd:string" />
|
||||
|
||||
<!-- Objective 2 -->
|
||||
<xsd:attribute name="MustUnderstand" type="xsd:string" />
|
||||
<xsd:attribute name="ProcessContent" type="xsd:string" />
|
||||
|
||||
<!-- An AlternateContent element shall contain one or more Choice child elements, optionally followed by a
|
||||
Fallback child element. If present, there shall be only one Fallback element, and it shall follow all Choice
|
||||
elements. -->
|
||||
<xsd:element name="AlternateContent">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Choice" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:any minOccurs="0" maxOccurs="unbounded"
|
||||
processContents="strict">
|
||||
</xsd:any>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="Requires" type="xsd:string" use="required" />
|
||||
<xsd:attribute ref="mc:Ignorable" use="optional" />
|
||||
<xsd:attribute ref="mc:MustUnderstand" use="optional" />
|
||||
<xsd:attribute ref="mc:ProcessContent" use="optional" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="Fallback" minOccurs="0" maxOccurs="1">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:any minOccurs="0" maxOccurs="unbounded"
|
||||
processContents="strict">
|
||||
</xsd:any>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute ref="mc:Ignorable" use="optional" />
|
||||
<xsd:attribute ref="mc:MustUnderstand" use="optional" />
|
||||
<xsd:attribute ref="mc:ProcessContent" use="optional" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<!-- AlternateContent elements might include the attributes Ignorable,
|
||||
MustUnderstand and ProcessContent described in this Part of ECMA-376. These
|
||||
attributes’ qualified names shall be prefixed when associated with an AlternateContent
|
||||
element. -->
|
||||
<xsd:attribute ref="mc:Ignorable" use="optional" />
|
||||
<xsd:attribute ref="mc:MustUnderstand" use="optional" />
|
||||
<xsd:attribute ref="mc:ProcessContent" use="optional" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
560
skills/ppt/ooxml/schemas/microsoft/wml-2010.xsd
Executable file
560
skills/ppt/ooxml/schemas/microsoft/wml-2010.xsd
Executable file
@@ -0,0 +1,560 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns="http://schemas.microsoft.com/office/word/2010/wordml" targetNamespace="http://schemas.microsoft.com/office/word/2010/wordml">
|
||||
<!-- <xsd:import id="rel" namespace="http://schemas.openxmlformats.org/officeDocument/2006/relationships" schemaLocation="orel.xsd"/> -->
|
||||
<xsd:import id="w" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<!-- <xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main" schemaLocation="oartbasetypes.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/drawingml/2006/main" schemaLocation="oartsplineproperties.xsd"/> -->
|
||||
<xsd:complexType name="CT_LongHexNumber">
|
||||
<xsd:attribute name="val" type="w:ST_LongHexNumber" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_OnOff">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="true"/>
|
||||
<xsd:enumeration value="false"/>
|
||||
<xsd:enumeration value="0"/>
|
||||
<xsd:enumeration value="1"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_OnOff">
|
||||
<xsd:attribute name="val" type="ST_OnOff"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="docId" type="CT_LongHexNumber"/>
|
||||
<xsd:element name="conflictMode" type="CT_OnOff"/>
|
||||
<xsd:attributeGroup name="AG_Parids">
|
||||
<xsd:attribute name="paraId" type="w:ST_LongHexNumber"/>
|
||||
<xsd:attribute name="textId" type="w:ST_LongHexNumber"/>
|
||||
</xsd:attributeGroup>
|
||||
<xsd:attribute name="anchorId" type="w:ST_LongHexNumber"/>
|
||||
<xsd:attribute name="noSpellErr" type="ST_OnOff"/>
|
||||
<xsd:element name="customXmlConflictInsRangeStart" type="w:CT_TrackChange"/>
|
||||
<xsd:element name="customXmlConflictInsRangeEnd" type="w:CT_Markup"/>
|
||||
<xsd:element name="customXmlConflictDelRangeStart" type="w:CT_TrackChange"/>
|
||||
<xsd:element name="customXmlConflictDelRangeEnd" type="w:CT_Markup"/>
|
||||
<xsd:group name="EG_RunLevelConflicts">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="conflictIns" type="w:CT_RunTrackChange" minOccurs="0"/>
|
||||
<xsd:element name="conflictDel" type="w:CT_RunTrackChange" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:group name="EG_Conflicts">
|
||||
<xsd:choice>
|
||||
<xsd:element name="conflictIns" type="w:CT_TrackChange" minOccurs="0"/>
|
||||
<xsd:element name="conflictDel" type="w:CT_TrackChange" minOccurs="0"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_Percentage">
|
||||
<xsd:attribute name="val" type="a:ST_Percentage" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PositiveFixedPercentage">
|
||||
<xsd:attribute name="val" type="a:ST_PositiveFixedPercentage" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PositivePercentage">
|
||||
<xsd:attribute name="val" type="a:ST_PositivePercentage" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_SchemeColorVal">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="bg1"/>
|
||||
<xsd:enumeration value="tx1"/>
|
||||
<xsd:enumeration value="bg2"/>
|
||||
<xsd:enumeration value="tx2"/>
|
||||
<xsd:enumeration value="accent1"/>
|
||||
<xsd:enumeration value="accent2"/>
|
||||
<xsd:enumeration value="accent3"/>
|
||||
<xsd:enumeration value="accent4"/>
|
||||
<xsd:enumeration value="accent5"/>
|
||||
<xsd:enumeration value="accent6"/>
|
||||
<xsd:enumeration value="hlink"/>
|
||||
<xsd:enumeration value="folHlink"/>
|
||||
<xsd:enumeration value="dk1"/>
|
||||
<xsd:enumeration value="lt1"/>
|
||||
<xsd:enumeration value="dk2"/>
|
||||
<xsd:enumeration value="lt2"/>
|
||||
<xsd:enumeration value="phClr"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_RectAlignment">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="tl"/>
|
||||
<xsd:enumeration value="t"/>
|
||||
<xsd:enumeration value="tr"/>
|
||||
<xsd:enumeration value="l"/>
|
||||
<xsd:enumeration value="ctr"/>
|
||||
<xsd:enumeration value="r"/>
|
||||
<xsd:enumeration value="bl"/>
|
||||
<xsd:enumeration value="b"/>
|
||||
<xsd:enumeration value="br"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PathShadeType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="shape"/>
|
||||
<xsd:enumeration value="circle"/>
|
||||
<xsd:enumeration value="rect"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_LineCap">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="rnd"/>
|
||||
<xsd:enumeration value="sq"/>
|
||||
<xsd:enumeration value="flat"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PresetLineDashVal">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="solid"/>
|
||||
<xsd:enumeration value="dot"/>
|
||||
<xsd:enumeration value="sysDot"/>
|
||||
<xsd:enumeration value="dash"/>
|
||||
<xsd:enumeration value="sysDash"/>
|
||||
<xsd:enumeration value="lgDash"/>
|
||||
<xsd:enumeration value="dashDot"/>
|
||||
<xsd:enumeration value="sysDashDot"/>
|
||||
<xsd:enumeration value="lgDashDot"/>
|
||||
<xsd:enumeration value="lgDashDotDot"/>
|
||||
<xsd:enumeration value="sysDashDotDot"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_PenAlignment">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="ctr"/>
|
||||
<xsd:enumeration value="in"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_CompoundLine">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="sng"/>
|
||||
<xsd:enumeration value="dbl"/>
|
||||
<xsd:enumeration value="thickThin"/>
|
||||
<xsd:enumeration value="thinThick"/>
|
||||
<xsd:enumeration value="tri"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_RelativeRect">
|
||||
<xsd:attribute name="l" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="t" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="r" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="b" use="optional" type="a:ST_Percentage"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ColorTransform">
|
||||
<xsd:choice>
|
||||
<xsd:element name="tint" type="CT_PositiveFixedPercentage"/>
|
||||
<xsd:element name="shade" type="CT_PositiveFixedPercentage"/>
|
||||
<xsd:element name="alpha" type="CT_PositiveFixedPercentage"/>
|
||||
<xsd:element name="hueMod" type="CT_PositivePercentage"/>
|
||||
<xsd:element name="sat" type="CT_Percentage"/>
|
||||
<xsd:element name="satOff" type="CT_Percentage"/>
|
||||
<xsd:element name="satMod" type="CT_Percentage"/>
|
||||
<xsd:element name="lum" type="CT_Percentage"/>
|
||||
<xsd:element name="lumOff" type="CT_Percentage"/>
|
||||
<xsd:element name="lumMod" type="CT_Percentage"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_SRgbColor">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorTransform" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="val" type="s:ST_HexColorRGB" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SchemeColor">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorTransform" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="val" type="ST_SchemeColorVal" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ColorChoice">
|
||||
<xsd:choice>
|
||||
<xsd:element name="srgbClr" type="CT_SRgbColor"/>
|
||||
<xsd:element name="schemeClr" type="CT_SchemeColor"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_Color">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorChoice"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GradientStop">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorChoice"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="pos" type="a:ST_PositiveFixedPercentage" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GradientStopList">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="gs" type="CT_GradientStop" minOccurs="2" maxOccurs="10"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_LinearShadeProperties">
|
||||
<xsd:attribute name="ang" type="a:ST_PositiveFixedAngle" use="optional"/>
|
||||
<xsd:attribute name="scaled" type="ST_OnOff" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PathShadeProperties">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="fillToRect" type="CT_RelativeRect" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="path" type="ST_PathShadeType" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_ShadeProperties">
|
||||
<xsd:choice>
|
||||
<xsd:element name="lin" type="CT_LinearShadeProperties"/>
|
||||
<xsd:element name="path" type="CT_PathShadeProperties"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_SolidColorFillProperties">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorChoice" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_GradientFillProperties">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="gsLst" type="CT_GradientStopList" minOccurs="0"/>
|
||||
<xsd:group ref="EG_ShadeProperties" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_FillProperties">
|
||||
<xsd:choice>
|
||||
<xsd:element name="noFill" type="w:CT_Empty"/>
|
||||
<xsd:element name="solidFill" type="CT_SolidColorFillProperties"/>
|
||||
<xsd:element name="gradFill" type="CT_GradientFillProperties"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_PresetLineDashProperties">
|
||||
<xsd:attribute name="val" type="ST_PresetLineDashVal" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_LineDashProperties">
|
||||
<xsd:choice>
|
||||
<xsd:element name="prstDash" type="CT_PresetLineDashProperties"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:complexType name="CT_LineJoinMiterProperties">
|
||||
<xsd:attribute name="lim" type="a:ST_PositivePercentage" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_LineJoinProperties">
|
||||
<xsd:choice>
|
||||
<xsd:element name="round" type="w:CT_Empty"/>
|
||||
<xsd:element name="bevel" type="w:CT_Empty"/>
|
||||
<xsd:element name="miter" type="CT_LineJoinMiterProperties"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
<xsd:simpleType name="ST_PresetCameraType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="legacyObliqueTopLeft"/>
|
||||
<xsd:enumeration value="legacyObliqueTop"/>
|
||||
<xsd:enumeration value="legacyObliqueTopRight"/>
|
||||
<xsd:enumeration value="legacyObliqueLeft"/>
|
||||
<xsd:enumeration value="legacyObliqueFront"/>
|
||||
<xsd:enumeration value="legacyObliqueRight"/>
|
||||
<xsd:enumeration value="legacyObliqueBottomLeft"/>
|
||||
<xsd:enumeration value="legacyObliqueBottom"/>
|
||||
<xsd:enumeration value="legacyObliqueBottomRight"/>
|
||||
<xsd:enumeration value="legacyPerspectiveTopLeft"/>
|
||||
<xsd:enumeration value="legacyPerspectiveTop"/>
|
||||
<xsd:enumeration value="legacyPerspectiveTopRight"/>
|
||||
<xsd:enumeration value="legacyPerspectiveLeft"/>
|
||||
<xsd:enumeration value="legacyPerspectiveFront"/>
|
||||
<xsd:enumeration value="legacyPerspectiveRight"/>
|
||||
<xsd:enumeration value="legacyPerspectiveBottomLeft"/>
|
||||
<xsd:enumeration value="legacyPerspectiveBottom"/>
|
||||
<xsd:enumeration value="legacyPerspectiveBottomRight"/>
|
||||
<xsd:enumeration value="orthographicFront"/>
|
||||
<xsd:enumeration value="isometricTopUp"/>
|
||||
<xsd:enumeration value="isometricTopDown"/>
|
||||
<xsd:enumeration value="isometricBottomUp"/>
|
||||
<xsd:enumeration value="isometricBottomDown"/>
|
||||
<xsd:enumeration value="isometricLeftUp"/>
|
||||
<xsd:enumeration value="isometricLeftDown"/>
|
||||
<xsd:enumeration value="isometricRightUp"/>
|
||||
<xsd:enumeration value="isometricRightDown"/>
|
||||
<xsd:enumeration value="isometricOffAxis1Left"/>
|
||||
<xsd:enumeration value="isometricOffAxis1Right"/>
|
||||
<xsd:enumeration value="isometricOffAxis1Top"/>
|
||||
<xsd:enumeration value="isometricOffAxis2Left"/>
|
||||
<xsd:enumeration value="isometricOffAxis2Right"/>
|
||||
<xsd:enumeration value="isometricOffAxis2Top"/>
|
||||
<xsd:enumeration value="isometricOffAxis3Left"/>
|
||||
<xsd:enumeration value="isometricOffAxis3Right"/>
|
||||
<xsd:enumeration value="isometricOffAxis3Bottom"/>
|
||||
<xsd:enumeration value="isometricOffAxis4Left"/>
|
||||
<xsd:enumeration value="isometricOffAxis4Right"/>
|
||||
<xsd:enumeration value="isometricOffAxis4Bottom"/>
|
||||
<xsd:enumeration value="obliqueTopLeft"/>
|
||||
<xsd:enumeration value="obliqueTop"/>
|
||||
<xsd:enumeration value="obliqueTopRight"/>
|
||||
<xsd:enumeration value="obliqueLeft"/>
|
||||
<xsd:enumeration value="obliqueRight"/>
|
||||
<xsd:enumeration value="obliqueBottomLeft"/>
|
||||
<xsd:enumeration value="obliqueBottom"/>
|
||||
<xsd:enumeration value="obliqueBottomRight"/>
|
||||
<xsd:enumeration value="perspectiveFront"/>
|
||||
<xsd:enumeration value="perspectiveLeft"/>
|
||||
<xsd:enumeration value="perspectiveRight"/>
|
||||
<xsd:enumeration value="perspectiveAbove"/>
|
||||
<xsd:enumeration value="perspectiveBelow"/>
|
||||
<xsd:enumeration value="perspectiveAboveLeftFacing"/>
|
||||
<xsd:enumeration value="perspectiveAboveRightFacing"/>
|
||||
<xsd:enumeration value="perspectiveContrastingLeftFacing"/>
|
||||
<xsd:enumeration value="perspectiveContrastingRightFacing"/>
|
||||
<xsd:enumeration value="perspectiveHeroicLeftFacing"/>
|
||||
<xsd:enumeration value="perspectiveHeroicRightFacing"/>
|
||||
<xsd:enumeration value="perspectiveHeroicExtremeLeftFacing"/>
|
||||
<xsd:enumeration value="perspectiveHeroicExtremeRightFacing"/>
|
||||
<xsd:enumeration value="perspectiveRelaxed"/>
|
||||
<xsd:enumeration value="perspectiveRelaxedModerately"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Camera">
|
||||
<xsd:attribute name="prst" use="required" type="ST_PresetCameraType"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SphereCoords">
|
||||
<xsd:attribute name="lat" type="a:ST_PositiveFixedAngle" use="required"/>
|
||||
<xsd:attribute name="lon" type="a:ST_PositiveFixedAngle" use="required"/>
|
||||
<xsd:attribute name="rev" type="a:ST_PositiveFixedAngle" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_LightRigType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="legacyFlat1"/>
|
||||
<xsd:enumeration value="legacyFlat2"/>
|
||||
<xsd:enumeration value="legacyFlat3"/>
|
||||
<xsd:enumeration value="legacyFlat4"/>
|
||||
<xsd:enumeration value="legacyNormal1"/>
|
||||
<xsd:enumeration value="legacyNormal2"/>
|
||||
<xsd:enumeration value="legacyNormal3"/>
|
||||
<xsd:enumeration value="legacyNormal4"/>
|
||||
<xsd:enumeration value="legacyHarsh1"/>
|
||||
<xsd:enumeration value="legacyHarsh2"/>
|
||||
<xsd:enumeration value="legacyHarsh3"/>
|
||||
<xsd:enumeration value="legacyHarsh4"/>
|
||||
<xsd:enumeration value="threePt"/>
|
||||
<xsd:enumeration value="balanced"/>
|
||||
<xsd:enumeration value="soft"/>
|
||||
<xsd:enumeration value="harsh"/>
|
||||
<xsd:enumeration value="flood"/>
|
||||
<xsd:enumeration value="contrasting"/>
|
||||
<xsd:enumeration value="morning"/>
|
||||
<xsd:enumeration value="sunrise"/>
|
||||
<xsd:enumeration value="sunset"/>
|
||||
<xsd:enumeration value="chilly"/>
|
||||
<xsd:enumeration value="freezing"/>
|
||||
<xsd:enumeration value="flat"/>
|
||||
<xsd:enumeration value="twoPt"/>
|
||||
<xsd:enumeration value="glow"/>
|
||||
<xsd:enumeration value="brightRoom"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="ST_LightRigDirection">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="tl"/>
|
||||
<xsd:enumeration value="t"/>
|
||||
<xsd:enumeration value="tr"/>
|
||||
<xsd:enumeration value="l"/>
|
||||
<xsd:enumeration value="r"/>
|
||||
<xsd:enumeration value="bl"/>
|
||||
<xsd:enumeration value="b"/>
|
||||
<xsd:enumeration value="br"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_LightRig">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="rot" type="CT_SphereCoords" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="rig" type="ST_LightRigType" use="required"/>
|
||||
<xsd:attribute name="dir" type="ST_LightRigDirection" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_BevelPresetType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="relaxedInset"/>
|
||||
<xsd:enumeration value="circle"/>
|
||||
<xsd:enumeration value="slope"/>
|
||||
<xsd:enumeration value="cross"/>
|
||||
<xsd:enumeration value="angle"/>
|
||||
<xsd:enumeration value="softRound"/>
|
||||
<xsd:enumeration value="convex"/>
|
||||
<xsd:enumeration value="coolSlant"/>
|
||||
<xsd:enumeration value="divot"/>
|
||||
<xsd:enumeration value="riblet"/>
|
||||
<xsd:enumeration value="hardEdge"/>
|
||||
<xsd:enumeration value="artDeco"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Bevel">
|
||||
<xsd:attribute name="w" type="a:ST_PositiveCoordinate" use="optional"/>
|
||||
<xsd:attribute name="h" type="a:ST_PositiveCoordinate" use="optional"/>
|
||||
<xsd:attribute name="prst" type="ST_BevelPresetType" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_PresetMaterialType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="legacyMatte"/>
|
||||
<xsd:enumeration value="legacyPlastic"/>
|
||||
<xsd:enumeration value="legacyMetal"/>
|
||||
<xsd:enumeration value="legacyWireframe"/>
|
||||
<xsd:enumeration value="matte"/>
|
||||
<xsd:enumeration value="plastic"/>
|
||||
<xsd:enumeration value="metal"/>
|
||||
<xsd:enumeration value="warmMatte"/>
|
||||
<xsd:enumeration value="translucentPowder"/>
|
||||
<xsd:enumeration value="powder"/>
|
||||
<xsd:enumeration value="dkEdge"/>
|
||||
<xsd:enumeration value="softEdge"/>
|
||||
<xsd:enumeration value="clear"/>
|
||||
<xsd:enumeration value="flat"/>
|
||||
<xsd:enumeration value="softmetal"/>
|
||||
<xsd:enumeration value="none"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Glow">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorChoice"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="rad" use="optional" type="a:ST_PositiveCoordinate"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Shadow">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_ColorChoice"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="blurRad" use="optional" type="a:ST_PositiveCoordinate"/>
|
||||
<xsd:attribute name="dist" use="optional" type="a:ST_PositiveCoordinate"/>
|
||||
<xsd:attribute name="dir" use="optional" type="a:ST_PositiveFixedAngle"/>
|
||||
<xsd:attribute name="sx" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="sy" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="kx" use="optional" type="a:ST_FixedAngle"/>
|
||||
<xsd:attribute name="ky" use="optional" type="a:ST_FixedAngle"/>
|
||||
<xsd:attribute name="algn" use="optional" type="ST_RectAlignment"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Reflection">
|
||||
<xsd:attribute name="blurRad" use="optional" type="a:ST_PositiveCoordinate"/>
|
||||
<xsd:attribute name="stA" use="optional" type="a:ST_PositiveFixedPercentage"/>
|
||||
<xsd:attribute name="stPos" use="optional" type="a:ST_PositiveFixedPercentage"/>
|
||||
<xsd:attribute name="endA" use="optional" type="a:ST_PositiveFixedPercentage"/>
|
||||
<xsd:attribute name="endPos" use="optional" type="a:ST_PositiveFixedPercentage"/>
|
||||
<xsd:attribute name="dist" use="optional" type="a:ST_PositiveCoordinate"/>
|
||||
<xsd:attribute name="dir" use="optional" type="a:ST_PositiveFixedAngle"/>
|
||||
<xsd:attribute name="fadeDir" use="optional" type="a:ST_PositiveFixedAngle"/>
|
||||
<xsd:attribute name="sx" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="sy" use="optional" type="a:ST_Percentage"/>
|
||||
<xsd:attribute name="kx" use="optional" type="a:ST_FixedAngle"/>
|
||||
<xsd:attribute name="ky" use="optional" type="a:ST_FixedAngle"/>
|
||||
<xsd:attribute name="algn" use="optional" type="ST_RectAlignment"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_FillTextEffect">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_FillProperties" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_TextOutlineEffect">
|
||||
<xsd:sequence>
|
||||
<xsd:group ref="EG_FillProperties" minOccurs="0"/>
|
||||
<xsd:group ref="EG_LineDashProperties" minOccurs="0"/>
|
||||
<xsd:group ref="EG_LineJoinProperties" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="w" use="optional" type="a:ST_LineWidth"/>
|
||||
<xsd:attribute name="cap" use="optional" type="ST_LineCap"/>
|
||||
<xsd:attribute name="cmpd" use="optional" type="ST_CompoundLine"/>
|
||||
<xsd:attribute name="algn" use="optional" type="ST_PenAlignment"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Scene3D">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="camera" type="CT_Camera"/>
|
||||
<xsd:element name="lightRig" type="CT_LightRig"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Props3D">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="bevelT" type="CT_Bevel" minOccurs="0"/>
|
||||
<xsd:element name="bevelB" type="CT_Bevel" minOccurs="0"/>
|
||||
<xsd:element name="extrusionClr" type="CT_Color" minOccurs="0"/>
|
||||
<xsd:element name="contourClr" type="CT_Color" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="extrusionH" type="a:ST_PositiveCoordinate" use="optional"/>
|
||||
<xsd:attribute name="contourW" type="a:ST_PositiveCoordinate" use="optional"/>
|
||||
<xsd:attribute name="prstMaterial" type="ST_PresetMaterialType" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_RPrTextEffects">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="glow" minOccurs="0" type="CT_Glow"/>
|
||||
<xsd:element name="shadow" minOccurs="0" type="CT_Shadow"/>
|
||||
<xsd:element name="reflection" minOccurs="0" type="CT_Reflection"/>
|
||||
<xsd:element name="textOutline" minOccurs="0" type="CT_TextOutlineEffect"/>
|
||||
<xsd:element name="textFill" minOccurs="0" type="CT_FillTextEffect"/>
|
||||
<xsd:element name="scene3d" minOccurs="0" type="CT_Scene3D"/>
|
||||
<xsd:element name="props3d" minOccurs="0" type="CT_Props3D"/>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:simpleType name="ST_Ligatures">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="standard"/>
|
||||
<xsd:enumeration value="contextual"/>
|
||||
<xsd:enumeration value="historical"/>
|
||||
<xsd:enumeration value="discretional"/>
|
||||
<xsd:enumeration value="standardContextual"/>
|
||||
<xsd:enumeration value="standardHistorical"/>
|
||||
<xsd:enumeration value="contextualHistorical"/>
|
||||
<xsd:enumeration value="standardDiscretional"/>
|
||||
<xsd:enumeration value="contextualDiscretional"/>
|
||||
<xsd:enumeration value="historicalDiscretional"/>
|
||||
<xsd:enumeration value="standardContextualHistorical"/>
|
||||
<xsd:enumeration value="standardContextualDiscretional"/>
|
||||
<xsd:enumeration value="standardHistoricalDiscretional"/>
|
||||
<xsd:enumeration value="contextualHistoricalDiscretional"/>
|
||||
<xsd:enumeration value="all"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Ligatures">
|
||||
<xsd:attribute name="val" type="ST_Ligatures" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_NumForm">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="default"/>
|
||||
<xsd:enumeration value="lining"/>
|
||||
<xsd:enumeration value="oldStyle"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_NumForm">
|
||||
<xsd:attribute name="val" type="ST_NumForm" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_NumSpacing">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="default"/>
|
||||
<xsd:enumeration value="proportional"/>
|
||||
<xsd:enumeration value="tabular"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_NumSpacing">
|
||||
<xsd:attribute name="val" type="ST_NumSpacing" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_StyleSet">
|
||||
<xsd:attribute name="id" type="s:ST_UnsignedDecimalNumber" use="required"/>
|
||||
<xsd:attribute name="val" type="ST_OnOff" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_StylisticSets">
|
||||
<xsd:sequence minOccurs="0">
|
||||
<xsd:element name="styleSet" minOccurs="0" maxOccurs="unbounded" type="CT_StyleSet"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:group name="EG_RPrOpenType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ligatures" minOccurs="0" type="CT_Ligatures"/>
|
||||
<xsd:element name="numForm" minOccurs="0" type="CT_NumForm"/>
|
||||
<xsd:element name="numSpacing" minOccurs="0" type="CT_NumSpacing"/>
|
||||
<xsd:element name="stylisticSets" minOccurs="0" type="CT_StylisticSets"/>
|
||||
<xsd:element name="cntxtAlts" minOccurs="0" type="CT_OnOff"/>
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
<xsd:element name="discardImageEditingData" type="CT_OnOff"/>
|
||||
<xsd:element name="defaultImageDpi" type="CT_DefaultImageDpi"/>
|
||||
<xsd:complexType name="CT_DefaultImageDpi">
|
||||
<xsd:attribute name="val" type="w:ST_DecimalNumber" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="entityPicker" type="w:CT_Empty"/>
|
||||
<xsd:complexType name="CT_SdtCheckboxSymbol">
|
||||
<xsd:attribute name="font" type="s:ST_String"/>
|
||||
<xsd:attribute name="val" type="w:ST_ShortHexNumber"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_SdtCheckbox">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="checked" type="CT_OnOff" minOccurs="0"/>
|
||||
<xsd:element name="checkedState" type="CT_SdtCheckboxSymbol" minOccurs="0"/>
|
||||
<xsd:element name="uncheckedState" type="CT_SdtCheckboxSymbol" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="checkbox" type="CT_SdtCheckbox"/>
|
||||
</xsd:schema>
|
||||
67
skills/ppt/ooxml/schemas/microsoft/wml-2012.xsd
Executable file
67
skills/ppt/ooxml/schemas/microsoft/wml-2012.xsd
Executable file
@@ -0,0 +1,67 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2012/wordml" targetNamespace="http://schemas.microsoft.com/office/word/2012/wordml">
|
||||
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:import namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" schemaLocation="../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:element name="color" type="w12:CT_Color"/>
|
||||
<xsd:simpleType name="ST_SdtAppearance">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="boundingBox"/>
|
||||
<xsd:enumeration value="tags"/>
|
||||
<xsd:enumeration value="hidden"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:element name="dataBinding" type="w12:CT_DataBinding"/>
|
||||
<xsd:complexType name="CT_SdtAppearance">
|
||||
<xsd:attribute name="val" type="ST_SdtAppearance"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="appearance" type="CT_SdtAppearance"/>
|
||||
<xsd:complexType name="CT_CommentsEx">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="commentEx" type="CT_CommentEx" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_CommentEx">
|
||||
<xsd:attribute name="paraId" type="w12:ST_LongHexNumber" use="required"/>
|
||||
<xsd:attribute name="paraIdParent" type="w12:ST_LongHexNumber" use="optional"/>
|
||||
<xsd:attribute name="done" type="s:ST_OnOff" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="commentsEx" type="CT_CommentsEx"/>
|
||||
<xsd:complexType name="CT_People">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="person" type="CT_Person" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_PresenceInfo">
|
||||
<xsd:attribute name="providerId" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="userId" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_Person">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="presenceInfo" type="CT_PresenceInfo" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="author" type="s:ST_String" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="people" type="CT_People"/>
|
||||
<xsd:complexType name="CT_SdtRepeatedSection">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="sectionTitle" type="w12:CT_String" minOccurs="0"/>
|
||||
<xsd:element name="doNotAllowInsertDeleteSection" type="w12:CT_OnOff" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="ST_Guid">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:pattern value="\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:complexType name="CT_Guid">
|
||||
<xsd:attribute name="val" type="ST_Guid"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="repeatingSection" type="CT_SdtRepeatedSection"/>
|
||||
<xsd:element name="repeatingSectionItem" type="w12:CT_Empty"/>
|
||||
<xsd:element name="chartTrackingRefBased" type="w12:CT_OnOff"/>
|
||||
<xsd:element name="collapsed" type="w12:CT_OnOff"/>
|
||||
<xsd:element name="docId" type="CT_Guid"/>
|
||||
<xsd:element name="footnoteColumns" type="w12:CT_DecimalNumber"/>
|
||||
<xsd:element name="webExtensionLinked" type="w12:CT_OnOff"/>
|
||||
<xsd:element name="webExtensionCreated" type="w12:CT_OnOff"/>
|
||||
<xsd:attribute name="restartNumberingAfterBreak" type="s:ST_OnOff"/>
|
||||
</xsd:schema>
|
||||
14
skills/ppt/ooxml/schemas/microsoft/wml-2018.xsd
Executable file
14
skills/ppt/ooxml/schemas/microsoft/wml-2018.xsd
Executable file
@@ -0,0 +1,14 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2018/wordml" targetNamespace="http://schemas.microsoft.com/office/word/2018/wordml">
|
||||
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:complexType name="CT_Extension">
|
||||
<xsd:sequence>
|
||||
<xsd:any processContents="lax"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="uri" type="xsd:token"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_ExtensionList">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="ext" type="CT_Extension" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
20
skills/ppt/ooxml/schemas/microsoft/wml-cex-2018.xsd
Executable file
20
skills/ppt/ooxml/schemas/microsoft/wml-cex-2018.xsd
Executable file
@@ -0,0 +1,20 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2018/wordml/cex" targetNamespace="http://schemas.microsoft.com/office/word/2018/wordml/cex">
|
||||
<xsd:import id="w16" namespace="http://schemas.microsoft.com/office/word/2018/wordml" schemaLocation="wml-2018.xsd"/>
|
||||
<xsd:import id="w" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:import id="s" namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" schemaLocation="../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd"/>
|
||||
<xsd:complexType name="CT_CommentsExtensible">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="commentExtensible" type="CT_CommentExtensible" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="extLst" type="w16:CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_CommentExtensible">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="extLst" type="w16:CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="durableId" type="w:ST_LongHexNumber" use="required"/>
|
||||
<xsd:attribute name="dateUtc" type="w:ST_DateTime" use="optional"/>
|
||||
<xsd:attribute name="intelligentPlaceholder" type="s:ST_OnOff" use="optional"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="commentsExtensible" type="CT_CommentsExtensible"/>
|
||||
</xsd:schema>
|
||||
13
skills/ppt/ooxml/schemas/microsoft/wml-cid-2016.xsd
Executable file
13
skills/ppt/ooxml/schemas/microsoft/wml-cid-2016.xsd
Executable file
@@ -0,0 +1,13 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2016/wordml/cid" targetNamespace="http://schemas.microsoft.com/office/word/2016/wordml/cid">
|
||||
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:complexType name="CT_CommentsIds">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="commentId" type="CT_CommentId" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="CT_CommentId">
|
||||
<xsd:attribute name="paraId" type="w12:ST_LongHexNumber" use="required"/>
|
||||
<xsd:attribute name="durableId" type="w12:ST_LongHexNumber" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="commentsIds" type="CT_CommentsIds"/>
|
||||
</xsd:schema>
|
||||
4
skills/ppt/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd
Executable file
4
skills/ppt/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd
Executable file
@@ -0,0 +1,4 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" targetNamespace="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash">
|
||||
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:attribute name="storeItemChecksum" type="w12:ST_String"/>
|
||||
</xsd:schema>
|
||||
8
skills/ppt/ooxml/schemas/microsoft/wml-symex-2015.xsd
Executable file
8
skills/ppt/ooxml/schemas/microsoft/wml-symex-2015.xsd
Executable file
@@ -0,0 +1,8 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2015/wordml/symex" targetNamespace="http://schemas.microsoft.com/office/word/2015/wordml/symex">
|
||||
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
||||
<xsd:complexType name="CT_SymEx">
|
||||
<xsd:attribute name="font" type="w12:ST_String"/>
|
||||
<xsd:attribute name="char" type="w12:ST_LongHexNumber"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="symEx" type="CT_SymEx"/>
|
||||
</xsd:schema>
|
||||
159
skills/ppt/ooxml/scripts/pack.py
Executable file
159
skills/ppt/ooxml/scripts/pack.py
Executable file
@@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Tool to pack a directory into a .docx, .pptx, or .xlsx file with XML formatting undone.
|
||||
|
||||
Example usage:
|
||||
python pack.py <input_directory> <office_file> [--force]
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import defusedxml.minidom
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Pack a directory into an Office file")
|
||||
parser.add_argument("input_directory", help="Unpacked Office document directory")
|
||||
parser.add_argument("output_file", help="Output Office file (.docx/.pptx/.xlsx)")
|
||||
parser.add_argument("--force", action="store_true", help="Skip validation")
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
success = pack_document(
|
||||
args.input_directory, args.output_file, validate=not args.force
|
||||
)
|
||||
|
||||
# Show warning if validation was skipped
|
||||
if args.force:
|
||||
print("Warning: Skipped validation, file may be corrupt", file=sys.stderr)
|
||||
# Exit with error if validation failed
|
||||
elif not success:
|
||||
print("Contents would produce a corrupt file.", file=sys.stderr)
|
||||
print("Please validate XML before repacking.", file=sys.stderr)
|
||||
print("Use --force to skip validation and pack anyway.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
except ValueError as e:
|
||||
sys.exit(f"Error: {e}")
|
||||
|
||||
|
||||
def pack_document(input_dir, output_file, validate=False):
|
||||
"""Pack a directory into an Office file (.docx/.pptx/.xlsx).
|
||||
|
||||
Args:
|
||||
input_dir: Path to unpacked Office document directory
|
||||
output_file: Path to output Office file
|
||||
validate: If True, validates with soffice (default: False)
|
||||
|
||||
Returns:
|
||||
bool: True if successful, False if validation failed
|
||||
"""
|
||||
input_dir = Path(input_dir)
|
||||
output_file = Path(output_file)
|
||||
|
||||
if not input_dir.is_dir():
|
||||
raise ValueError(f"{input_dir} is not a directory")
|
||||
if output_file.suffix.lower() not in {".docx", ".pptx", ".xlsx"}:
|
||||
raise ValueError(f"{output_file} must be a .docx, .pptx, or .xlsx file")
|
||||
|
||||
# Work in temporary directory to avoid modifying original
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_content_dir = Path(temp_dir) / "content"
|
||||
shutil.copytree(input_dir, temp_content_dir)
|
||||
|
||||
# Process XML files to remove pretty-printing whitespace
|
||||
for pattern in ["*.xml", "*.rels"]:
|
||||
for xml_file in temp_content_dir.rglob(pattern):
|
||||
condense_xml(xml_file)
|
||||
|
||||
# Create final Office file as zip archive
|
||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
with zipfile.ZipFile(output_file, "w", zipfile.ZIP_DEFLATED) as zf:
|
||||
for f in temp_content_dir.rglob("*"):
|
||||
if f.is_file():
|
||||
zf.write(f, f.relative_to(temp_content_dir))
|
||||
|
||||
# Validate if requested
|
||||
if validate:
|
||||
if not validate_document(output_file):
|
||||
output_file.unlink() # Delete the corrupt file
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def validate_document(doc_path):
|
||||
"""Validate document by converting to HTML with soffice."""
|
||||
# Determine the correct filter based on file extension
|
||||
match doc_path.suffix.lower():
|
||||
case ".docx":
|
||||
filter_name = "html:HTML"
|
||||
case ".pptx":
|
||||
filter_name = "html:impress_html_Export"
|
||||
case ".xlsx":
|
||||
filter_name = "html:HTML (StarCalc)"
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[
|
||||
"soffice",
|
||||
"--headless",
|
||||
"--convert-to",
|
||||
filter_name,
|
||||
"--outdir",
|
||||
temp_dir,
|
||||
str(doc_path),
|
||||
],
|
||||
capture_output=True,
|
||||
timeout=10,
|
||||
text=True,
|
||||
)
|
||||
if not (Path(temp_dir) / f"{doc_path.stem}.html").exists():
|
||||
error_msg = result.stderr.strip() or "Document validation failed"
|
||||
print(f"Validation error: {error_msg}", file=sys.stderr)
|
||||
return False
|
||||
return True
|
||||
except FileNotFoundError:
|
||||
print("Warning: soffice not found. Skipping validation.", file=sys.stderr)
|
||||
return True
|
||||
except subprocess.TimeoutExpired:
|
||||
print("Validation error: Timeout during conversion", file=sys.stderr)
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Validation error: {e}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
||||
def condense_xml(xml_file):
|
||||
"""Strip unnecessary whitespace and remove comments."""
|
||||
with open(xml_file, "r", encoding="utf-8") as f:
|
||||
dom = defusedxml.minidom.parse(f)
|
||||
|
||||
# Process each element to remove whitespace and comments
|
||||
for element in dom.getElementsByTagName("*"):
|
||||
# Skip w:t elements and their processing
|
||||
if element.tagName.endswith(":t"):
|
||||
continue
|
||||
|
||||
# Remove whitespace-only text nodes and comment nodes
|
||||
for child in list(element.childNodes):
|
||||
if (
|
||||
child.nodeType == child.TEXT_NODE
|
||||
and child.nodeValue
|
||||
and child.nodeValue.strip() == ""
|
||||
) or child.nodeType == child.COMMENT_NODE:
|
||||
element.removeChild(child)
|
||||
|
||||
# Write back the condensed XML
|
||||
with open(xml_file, "wb") as f:
|
||||
f.write(dom.toxml(encoding="UTF-8"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
45
skills/ppt/ooxml/scripts/unpack.py
Executable file
45
skills/ppt/ooxml/scripts/unpack.py
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Unpack and format XML contents of Office files (.docx, .pptx, .xlsx)"""
|
||||
|
||||
import argparse
|
||||
import random
|
||||
import zipfile
|
||||
import defusedxml.minidom
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Unpack an Office file into a directory")
|
||||
parser.add_argument("office_file", help="Office file (.docx/.pptx/.xlsx)")
|
||||
parser.add_argument("output_dir", help="Output directory")
|
||||
args = parser.parse_args()
|
||||
unpack_document(args.office_file, args.output_dir)
|
||||
|
||||
|
||||
def unpack_document(input_file, output_dir):
|
||||
"""Unpack an Office file into a directory and pretty-print all XML files."""
|
||||
output_path = Path(output_dir)
|
||||
output_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with zipfile.ZipFile(input_file) as zf:
|
||||
zf.extractall(output_path)
|
||||
|
||||
for pattern in ["*.xml", "*.rels"]:
|
||||
for xml_file in output_path.rglob(pattern):
|
||||
pretty_print_xml(xml_file)
|
||||
|
||||
# For .docx files, suggest an RSID for tracked changes
|
||||
if str(input_file).endswith(".docx"):
|
||||
suggested_rsid = "".join(random.choices("0123456789ABCDEF", k=8))
|
||||
print(f"Suggested RSID for edit session: {suggested_rsid}")
|
||||
|
||||
|
||||
def pretty_print_xml(xml_file):
|
||||
"""Pretty-print a single XML file in place."""
|
||||
content = xml_file.read_text(encoding="utf-8")
|
||||
dom = defusedxml.minidom.parseString(content)
|
||||
xml_file.write_bytes(dom.toprettyxml(indent=" ", encoding="ascii"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
70
skills/ppt/ooxml/scripts/validate.py
Executable file
70
skills/ppt/ooxml/scripts/validate.py
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Command line tool to validate Office document XML files against XSD schemas and tracked changes.
|
||||
|
||||
Usage:
|
||||
python validate.py <dir> --original <original_file>
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from validation import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Validate Office document XML files")
|
||||
parser.add_argument(
|
||||
"unpacked_dir",
|
||||
help="Path to unpacked Office document directory",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--original",
|
||||
required=True,
|
||||
help="Path to original file (.docx/.pptx/.xlsx)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
action="store_true",
|
||||
help="Enable verbose output",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
# Validate paths
|
||||
unpacked_dir = Path(args.unpacked_dir)
|
||||
original_file = Path(args.original)
|
||||
file_extension = original_file.suffix.lower()
|
||||
if not unpacked_dir.is_dir():
|
||||
sys.exit(f"Error: {unpacked_dir} is not a directory")
|
||||
if not original_file.is_file():
|
||||
sys.exit(f"Error: {original_file} is not a file")
|
||||
if file_extension not in [".docx", ".pptx", ".xlsx"]:
|
||||
sys.exit(f"Error: {original_file} must be a .docx, .pptx, or .xlsx file")
|
||||
|
||||
# Run validations
|
||||
match file_extension:
|
||||
case ".docx":
|
||||
validators = [DOCXSchemaValidator, RedliningValidator]
|
||||
case ".pptx":
|
||||
validators = [PPTXSchemaValidator]
|
||||
case _:
|
||||
print(f"Error: Validation not supported for file type {file_extension}")
|
||||
sys.exit(1)
|
||||
|
||||
# Run validators
|
||||
success = True
|
||||
for V in validators:
|
||||
validator = V(unpacked_dir, original_file, verbose=args.verbose)
|
||||
if not validator.validate():
|
||||
success = False
|
||||
|
||||
if success:
|
||||
print("All validations PASSED!")
|
||||
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
15
skills/ppt/ooxml/scripts/validation/__init__.py
Executable file
15
skills/ppt/ooxml/scripts/validation/__init__.py
Executable file
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Validation modules for Word document processing.
|
||||
"""
|
||||
|
||||
from .base import BaseSchemaValidator
|
||||
from .docx import DOCXSchemaValidator
|
||||
from .pptx import PPTXSchemaValidator
|
||||
from .redlining import RedliningValidator
|
||||
|
||||
__all__ = [
|
||||
"BaseSchemaValidator",
|
||||
"DOCXSchemaValidator",
|
||||
"PPTXSchemaValidator",
|
||||
"RedliningValidator",
|
||||
]
|
||||
BIN
skills/ppt/ooxml/scripts/validation/__pycache__/__init__.cpython-313.pyc
Executable file
BIN
skills/ppt/ooxml/scripts/validation/__pycache__/__init__.cpython-313.pyc
Executable file
Binary file not shown.
BIN
skills/ppt/ooxml/scripts/validation/__pycache__/base.cpython-313.pyc
Executable file
BIN
skills/ppt/ooxml/scripts/validation/__pycache__/base.cpython-313.pyc
Executable file
Binary file not shown.
BIN
skills/ppt/ooxml/scripts/validation/__pycache__/docx.cpython-313.pyc
Executable file
BIN
skills/ppt/ooxml/scripts/validation/__pycache__/docx.cpython-313.pyc
Executable file
Binary file not shown.
BIN
skills/ppt/ooxml/scripts/validation/__pycache__/pptx.cpython-313.pyc
Executable file
BIN
skills/ppt/ooxml/scripts/validation/__pycache__/pptx.cpython-313.pyc
Executable file
Binary file not shown.
BIN
skills/ppt/ooxml/scripts/validation/__pycache__/redlining.cpython-313.pyc
Executable file
BIN
skills/ppt/ooxml/scripts/validation/__pycache__/redlining.cpython-313.pyc
Executable file
Binary file not shown.
948
skills/ppt/ooxml/scripts/validation/base.py
Executable file
948
skills/ppt/ooxml/scripts/validation/base.py
Executable file
@@ -0,0 +1,948 @@
|
||||
"""
|
||||
Base validator with common validation logic for document files.
|
||||
"""
|
||||
|
||||
import re
|
||||
import tempfile
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
import lxml.etree
|
||||
|
||||
|
||||
class BaseSchemaValidator:
|
||||
"""Base validator with common validation logic for document files."""
|
||||
|
||||
# Elements whose 'id' attributes must be unique within their file
|
||||
# Format: element_name -> (attribute_name, scope)
|
||||
# scope can be 'file' (unique within file) or 'global' (unique across all files)
|
||||
UNIQUE_ID_REQUIREMENTS = {
|
||||
# Word elements
|
||||
"comment": ("id", "file"), # Comment IDs in comments.xml
|
||||
"commentrangestart": ("id", "file"), # Must match comment IDs
|
||||
"commentrangeend": ("id", "file"), # Must match comment IDs
|
||||
"bookmarkstart": ("id", "file"), # Bookmark start IDs
|
||||
"bookmarkend": ("id", "file"), # Bookmark end IDs
|
||||
# Note: ins and del (track changes) can share IDs when part of same revision
|
||||
# PowerPoint elements
|
||||
"sldid": ("id", "file"), # Slide IDs in presentation.xml
|
||||
"sldmasterid": ("id", "global"), # Slide master IDs must be globally unique
|
||||
"sldlayoutid": ("id", "global"), # Slide layout IDs must be globally unique
|
||||
"cm": ("authorid", "file"), # Comment author IDs
|
||||
# Excel elements
|
||||
"sheet": ("sheetid", "file"), # Sheet IDs in workbook.xml
|
||||
"definedname": ("id", "file"), # Named range IDs
|
||||
# Drawing/Shape elements (all formats)
|
||||
"cxnsp": ("id", "file"), # Connection shape IDs
|
||||
"sp": ("id", "file"), # Shape IDs
|
||||
"pic": ("id", "file"), # Picture IDs
|
||||
"grpsp": ("id", "file"), # Group shape IDs
|
||||
}
|
||||
|
||||
# Mapping of element names to expected relationship types
|
||||
# Subclasses should override this with format-specific mappings
|
||||
ELEMENT_RELATIONSHIP_TYPES = {}
|
||||
|
||||
# Unified schema mappings for all Office document types
|
||||
SCHEMA_MAPPINGS = {
|
||||
# Document type specific schemas
|
||||
"word": "ISO-IEC29500-4_2016/wml.xsd", # Word documents
|
||||
"ppt": "ISO-IEC29500-4_2016/pml.xsd", # PowerPoint presentations
|
||||
"xl": "ISO-IEC29500-4_2016/sml.xsd", # Excel spreadsheets
|
||||
# Common file types
|
||||
"[Content_Types].xml": "ecma/fouth-edition/opc-contentTypes.xsd",
|
||||
"app.xml": "ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd",
|
||||
"core.xml": "ecma/fouth-edition/opc-coreProperties.xsd",
|
||||
"custom.xml": "ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd",
|
||||
".rels": "ecma/fouth-edition/opc-relationships.xsd",
|
||||
# Word-specific files
|
||||
"people.xml": "microsoft/wml-2012.xsd",
|
||||
"commentsIds.xml": "microsoft/wml-cid-2016.xsd",
|
||||
"commentsExtensible.xml": "microsoft/wml-cex-2018.xsd",
|
||||
"commentsExtended.xml": "microsoft/wml-2012.xsd",
|
||||
# Chart files (common across document types)
|
||||
"chart": "ISO-IEC29500-4_2016/dml-chart.xsd",
|
||||
# Theme files (common across document types)
|
||||
"theme": "ISO-IEC29500-4_2016/dml-main.xsd",
|
||||
# Drawing and media files
|
||||
"drawing": "ISO-IEC29500-4_2016/dml-main.xsd",
|
||||
}
|
||||
|
||||
# Unified namespace constants
|
||||
MC_NAMESPACE = "http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace"
|
||||
|
||||
# Common OOXML namespaces used across validators
|
||||
PACKAGE_RELATIONSHIPS_NAMESPACE = (
|
||||
"http://schemas.openxmlformats.org/package/2006/relationships"
|
||||
)
|
||||
OFFICE_RELATIONSHIPS_NAMESPACE = (
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
)
|
||||
CONTENT_TYPES_NAMESPACE = (
|
||||
"http://schemas.openxmlformats.org/package/2006/content-types"
|
||||
)
|
||||
|
||||
# Folders where we should clean ignorable namespaces
|
||||
MAIN_CONTENT_FOLDERS = {"word", "ppt", "xl"}
|
||||
|
||||
# All allowed OOXML namespaces (superset of all document types)
|
||||
OOXML_NAMESPACES = {
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/math",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
||||
"http://schemas.openxmlformats.org/schemaLibrary/2006/main",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/chart",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/diagram",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/picture",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
|
||||
"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
|
||||
"http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
||||
"http://schemas.openxmlformats.org/presentationml/2006/main",
|
||||
"http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes",
|
||||
"http://www.w3.org/XML/1998/namespace",
|
||||
}
|
||||
|
||||
def __init__(self, unpacked_dir, original_file, verbose=False):
|
||||
self.unpacked_dir = Path(unpacked_dir).resolve()
|
||||
self.original_file = Path(original_file)
|
||||
self.verbose = verbose
|
||||
|
||||
# Set schemas directory
|
||||
self.schemas_dir = Path(__file__).parent.parent.parent / "schemas"
|
||||
|
||||
# Get all XML and .rels files
|
||||
patterns = ["*.xml", "*.rels"]
|
||||
self.xml_files = [
|
||||
f for pattern in patterns for f in self.unpacked_dir.rglob(pattern)
|
||||
]
|
||||
|
||||
if not self.xml_files:
|
||||
print(f"Warning: No XML files found in {self.unpacked_dir}")
|
||||
|
||||
def validate(self):
|
||||
"""Run all validation checks and return True if all pass."""
|
||||
raise NotImplementedError("Subclasses must implement the validate method")
|
||||
|
||||
def validate_xml(self):
|
||||
"""Validate that all XML files are well-formed."""
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
# Try to parse the XML file
|
||||
lxml.etree.parse(str(xml_file))
|
||||
except lxml.etree.XMLSyntaxError as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {e.lineno}: {e.msg}"
|
||||
)
|
||||
except Exception as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Unexpected error: {str(e)}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} XML violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All XML files are well-formed")
|
||||
return True
|
||||
|
||||
def validate_namespaces(self):
|
||||
"""Validate that namespace prefixes in Ignorable attributes are declared."""
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
declared = set(root.nsmap.keys()) - {None} # Exclude default namespace
|
||||
|
||||
for attr_val in [
|
||||
v for k, v in root.attrib.items() if k.endswith("Ignorable")
|
||||
]:
|
||||
undeclared = set(attr_val.split()) - declared
|
||||
errors.extend(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Namespace '{ns}' in Ignorable but not declared"
|
||||
for ns in undeclared
|
||||
)
|
||||
except lxml.etree.XMLSyntaxError:
|
||||
continue
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - {len(errors)} namespace issues:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
if self.verbose:
|
||||
print("PASSED - All namespace prefixes properly declared")
|
||||
return True
|
||||
|
||||
def validate_unique_ids(self):
|
||||
"""Validate that specific IDs are unique according to OOXML requirements."""
|
||||
errors = []
|
||||
global_ids = {} # Track globally unique IDs across all files
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
file_ids = {} # Track IDs that must be unique within this file
|
||||
|
||||
# Remove all mc:AlternateContent elements from the tree
|
||||
mc_elements = root.xpath(
|
||||
".//mc:AlternateContent", namespaces={"mc": self.MC_NAMESPACE}
|
||||
)
|
||||
for elem in mc_elements:
|
||||
elem.getparent().remove(elem)
|
||||
|
||||
# Now check IDs in the cleaned tree
|
||||
for elem in root.iter():
|
||||
# Get the element name without namespace
|
||||
tag = (
|
||||
elem.tag.split("}")[-1].lower()
|
||||
if "}" in elem.tag
|
||||
else elem.tag.lower()
|
||||
)
|
||||
|
||||
# Check if this element type has ID uniqueness requirements
|
||||
if tag in self.UNIQUE_ID_REQUIREMENTS:
|
||||
attr_name, scope = self.UNIQUE_ID_REQUIREMENTS[tag]
|
||||
|
||||
# Look for the specified attribute
|
||||
id_value = None
|
||||
for attr, value in elem.attrib.items():
|
||||
attr_local = (
|
||||
attr.split("}")[-1].lower()
|
||||
if "}" in attr
|
||||
else attr.lower()
|
||||
)
|
||||
if attr_local == attr_name:
|
||||
id_value = value
|
||||
break
|
||||
|
||||
if id_value is not None:
|
||||
if scope == "global":
|
||||
# Check global uniqueness
|
||||
if id_value in global_ids:
|
||||
prev_file, prev_line, prev_tag = global_ids[
|
||||
id_value
|
||||
]
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {elem.sourceline}: Global ID '{id_value}' in <{tag}> "
|
||||
f"already used in {prev_file} at line {prev_line} in <{prev_tag}>"
|
||||
)
|
||||
else:
|
||||
global_ids[id_value] = (
|
||||
xml_file.relative_to(self.unpacked_dir),
|
||||
elem.sourceline,
|
||||
tag,
|
||||
)
|
||||
elif scope == "file":
|
||||
# Check file-level uniqueness
|
||||
key = (tag, attr_name)
|
||||
if key not in file_ids:
|
||||
file_ids[key] = {}
|
||||
|
||||
if id_value in file_ids[key]:
|
||||
prev_line = file_ids[key][id_value]
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {elem.sourceline}: Duplicate {attr_name}='{id_value}' in <{tag}> "
|
||||
f"(first occurrence at line {prev_line})"
|
||||
)
|
||||
else:
|
||||
file_ids[key][id_value] = elem.sourceline
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} ID uniqueness violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All required IDs are unique")
|
||||
return True
|
||||
|
||||
def validate_file_references(self):
|
||||
"""
|
||||
Validate that all .rels files properly reference files and that all files are referenced.
|
||||
"""
|
||||
errors = []
|
||||
|
||||
# Find all .rels files
|
||||
rels_files = list(self.unpacked_dir.rglob("*.rels"))
|
||||
|
||||
if not rels_files:
|
||||
if self.verbose:
|
||||
print("PASSED - No .rels files found")
|
||||
return True
|
||||
|
||||
# Get all files in the unpacked directory (excluding reference files)
|
||||
all_files = []
|
||||
for file_path in self.unpacked_dir.rglob("*"):
|
||||
if (
|
||||
file_path.is_file()
|
||||
and file_path.name != "[Content_Types].xml"
|
||||
and not file_path.name.endswith(".rels")
|
||||
): # This file is not referenced by .rels
|
||||
all_files.append(file_path.resolve())
|
||||
|
||||
# Track all files that are referenced by any .rels file
|
||||
all_referenced_files = set()
|
||||
|
||||
if self.verbose:
|
||||
print(
|
||||
f"Found {len(rels_files)} .rels files and {len(all_files)} target files"
|
||||
)
|
||||
|
||||
# Check each .rels file
|
||||
for rels_file in rels_files:
|
||||
try:
|
||||
# Parse relationships file
|
||||
rels_root = lxml.etree.parse(str(rels_file)).getroot()
|
||||
|
||||
# Get the directory where this .rels file is located
|
||||
rels_dir = rels_file.parent
|
||||
|
||||
# Find all relationships and their targets
|
||||
referenced_files = set()
|
||||
broken_refs = []
|
||||
|
||||
for rel in rels_root.findall(
|
||||
".//ns:Relationship",
|
||||
namespaces={"ns": self.PACKAGE_RELATIONSHIPS_NAMESPACE},
|
||||
):
|
||||
target = rel.get("Target")
|
||||
if target and not target.startswith(
|
||||
("http", "mailto:")
|
||||
): # Skip external URLs
|
||||
# Resolve the target path relative to the .rels file location
|
||||
if rels_file.name == ".rels":
|
||||
# Root .rels file - targets are relative to unpacked_dir
|
||||
target_path = self.unpacked_dir / target
|
||||
else:
|
||||
# Other .rels files - targets are relative to their parent's parent
|
||||
# e.g., word/_rels/document.xml.rels -> targets relative to word/
|
||||
base_dir = rels_dir.parent
|
||||
target_path = base_dir / target
|
||||
|
||||
# Normalize the path and check if it exists
|
||||
try:
|
||||
target_path = target_path.resolve()
|
||||
if target_path.exists() and target_path.is_file():
|
||||
referenced_files.add(target_path)
|
||||
all_referenced_files.add(target_path)
|
||||
else:
|
||||
broken_refs.append((target, rel.sourceline))
|
||||
except (OSError, ValueError):
|
||||
broken_refs.append((target, rel.sourceline))
|
||||
|
||||
# Report broken references
|
||||
if broken_refs:
|
||||
rel_path = rels_file.relative_to(self.unpacked_dir)
|
||||
for broken_ref, line_num in broken_refs:
|
||||
errors.append(
|
||||
f" {rel_path}: Line {line_num}: Broken reference to {broken_ref}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
rel_path = rels_file.relative_to(self.unpacked_dir)
|
||||
errors.append(f" Error parsing {rel_path}: {e}")
|
||||
|
||||
# Check for unreferenced files (files that exist but are not referenced anywhere)
|
||||
unreferenced_files = set(all_files) - all_referenced_files
|
||||
|
||||
if unreferenced_files:
|
||||
for unref_file in sorted(unreferenced_files):
|
||||
unref_rel_path = unref_file.relative_to(self.unpacked_dir)
|
||||
errors.append(f" Unreferenced file: {unref_rel_path}")
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} relationship validation errors:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
print(
|
||||
"CRITICAL: These errors will cause the document to appear corrupt. "
|
||||
+ "Broken references MUST be fixed, "
|
||||
+ "and unreferenced files MUST be referenced or removed."
|
||||
)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print(
|
||||
"PASSED - All references are valid and all files are properly referenced"
|
||||
)
|
||||
return True
|
||||
|
||||
def validate_all_relationship_ids(self):
|
||||
"""
|
||||
Validate that all r:id attributes in XML files reference existing IDs
|
||||
in their corresponding .rels files, and optionally validate relationship types.
|
||||
"""
|
||||
errors = []
|
||||
|
||||
# Process each XML file that might contain r:id references
|
||||
for xml_file in self.xml_files:
|
||||
# Skip .rels files themselves
|
||||
if xml_file.suffix == ".rels":
|
||||
continue
|
||||
|
||||
# Determine the corresponding .rels file
|
||||
# For dir/file.xml, it's dir/_rels/file.xml.rels
|
||||
rels_dir = xml_file.parent / "_rels"
|
||||
rels_file = rels_dir / f"{xml_file.name}.rels"
|
||||
|
||||
# Skip if there's no corresponding .rels file (that's okay)
|
||||
if not rels_file.exists():
|
||||
continue
|
||||
|
||||
try:
|
||||
# Parse the .rels file to get valid relationship IDs and their types
|
||||
rels_root = lxml.etree.parse(str(rels_file)).getroot()
|
||||
rid_to_type = {}
|
||||
|
||||
for rel in rels_root.findall(
|
||||
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
||||
):
|
||||
rid = rel.get("Id")
|
||||
rel_type = rel.get("Type", "")
|
||||
if rid:
|
||||
# Check for duplicate rIds
|
||||
if rid in rid_to_type:
|
||||
rels_rel_path = rels_file.relative_to(self.unpacked_dir)
|
||||
errors.append(
|
||||
f" {rels_rel_path}: Line {rel.sourceline}: "
|
||||
f"Duplicate relationship ID '{rid}' (IDs must be unique)"
|
||||
)
|
||||
# Extract just the type name from the full URL
|
||||
type_name = (
|
||||
rel_type.split("/")[-1] if "/" in rel_type else rel_type
|
||||
)
|
||||
rid_to_type[rid] = type_name
|
||||
|
||||
# Parse the XML file to find all r:id references
|
||||
xml_root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
|
||||
# Find all elements with r:id attributes
|
||||
for elem in xml_root.iter():
|
||||
# Check for r:id attribute (relationship ID)
|
||||
rid_attr = elem.get(f"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id")
|
||||
if rid_attr:
|
||||
xml_rel_path = xml_file.relative_to(self.unpacked_dir)
|
||||
elem_name = (
|
||||
elem.tag.split("}")[-1] if "}" in elem.tag else elem.tag
|
||||
)
|
||||
|
||||
# Check if the ID exists
|
||||
if rid_attr not in rid_to_type:
|
||||
errors.append(
|
||||
f" {xml_rel_path}: Line {elem.sourceline}: "
|
||||
f"<{elem_name}> references non-existent relationship '{rid_attr}' "
|
||||
f"(valid IDs: {', '.join(sorted(rid_to_type.keys())[:5])}{'...' if len(rid_to_type) > 5 else ''})"
|
||||
)
|
||||
# Check if we have type expectations for this element
|
||||
elif self.ELEMENT_RELATIONSHIP_TYPES:
|
||||
expected_type = self._get_expected_relationship_type(
|
||||
elem_name
|
||||
)
|
||||
if expected_type:
|
||||
actual_type = rid_to_type[rid_attr]
|
||||
# Check if the actual type matches or contains the expected type
|
||||
if expected_type not in actual_type.lower():
|
||||
errors.append(
|
||||
f" {xml_rel_path}: Line {elem.sourceline}: "
|
||||
f"<{elem_name}> references '{rid_attr}' which points to '{actual_type}' "
|
||||
f"but should point to a '{expected_type}' relationship"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
xml_rel_path = xml_file.relative_to(self.unpacked_dir)
|
||||
errors.append(f" Error processing {xml_rel_path}: {e}")
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} relationship ID reference errors:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
print("\nThese ID mismatches will cause the document to appear corrupt!")
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All relationship ID references are valid")
|
||||
return True
|
||||
|
||||
def _get_expected_relationship_type(self, element_name):
|
||||
"""
|
||||
Get the expected relationship type for an element.
|
||||
First checks the explicit mapping, then tries pattern detection.
|
||||
"""
|
||||
# Normalize element name to lowercase
|
||||
elem_lower = element_name.lower()
|
||||
|
||||
# Check explicit mapping first
|
||||
if elem_lower in self.ELEMENT_RELATIONSHIP_TYPES:
|
||||
return self.ELEMENT_RELATIONSHIP_TYPES[elem_lower]
|
||||
|
||||
# Try pattern detection for common patterns
|
||||
# Pattern 1: Elements ending in "Id" often expect a relationship of the prefix type
|
||||
if elem_lower.endswith("id") and len(elem_lower) > 2:
|
||||
# e.g., "sldId" -> "sld", "sldMasterId" -> "sldMaster"
|
||||
prefix = elem_lower[:-2] # Remove "id"
|
||||
# Check if this might be a compound like "sldMasterId"
|
||||
if prefix.endswith("master"):
|
||||
return prefix.lower()
|
||||
elif prefix.endswith("layout"):
|
||||
return prefix.lower()
|
||||
else:
|
||||
# Simple case like "sldId" -> "slide"
|
||||
# Common transformations
|
||||
if prefix == "sld":
|
||||
return "slide"
|
||||
return prefix.lower()
|
||||
|
||||
# Pattern 2: Elements ending in "Reference" expect a relationship of the prefix type
|
||||
if elem_lower.endswith("reference") and len(elem_lower) > 9:
|
||||
prefix = elem_lower[:-9] # Remove "reference"
|
||||
return prefix.lower()
|
||||
|
||||
return None
|
||||
|
||||
def validate_content_types(self):
|
||||
"""Validate that all content files are properly declared in [Content_Types].xml."""
|
||||
errors = []
|
||||
|
||||
# Find [Content_Types].xml file
|
||||
content_types_file = self.unpacked_dir / "[Content_Types].xml"
|
||||
if not content_types_file.exists():
|
||||
print("FAILED - [Content_Types].xml file not found")
|
||||
return False
|
||||
|
||||
try:
|
||||
# Parse and get all declared parts and extensions
|
||||
root = lxml.etree.parse(str(content_types_file)).getroot()
|
||||
declared_parts = set()
|
||||
declared_extensions = set()
|
||||
|
||||
# Get Override declarations (specific files)
|
||||
for override in root.findall(
|
||||
f".//{{{self.CONTENT_TYPES_NAMESPACE}}}Override"
|
||||
):
|
||||
part_name = override.get("PartName")
|
||||
if part_name is not None:
|
||||
declared_parts.add(part_name.lstrip("/"))
|
||||
|
||||
# Get Default declarations (by extension)
|
||||
for default in root.findall(
|
||||
f".//{{{self.CONTENT_TYPES_NAMESPACE}}}Default"
|
||||
):
|
||||
extension = default.get("Extension")
|
||||
if extension is not None:
|
||||
declared_extensions.add(extension.lower())
|
||||
|
||||
# Root elements that require content type declaration
|
||||
declarable_roots = {
|
||||
"sld",
|
||||
"sldLayout",
|
||||
"sldMaster",
|
||||
"presentation", # PowerPoint
|
||||
"document", # Word
|
||||
"workbook",
|
||||
"worksheet", # Excel
|
||||
"theme", # Common
|
||||
}
|
||||
|
||||
# Common media file extensions that should be declared
|
||||
media_extensions = {
|
||||
"png": "image/png",
|
||||
"jpg": "image/jpeg",
|
||||
"jpeg": "image/jpeg",
|
||||
"gif": "image/gif",
|
||||
"bmp": "image/bmp",
|
||||
"tiff": "image/tiff",
|
||||
"wmf": "image/x-wmf",
|
||||
"emf": "image/x-emf",
|
||||
}
|
||||
|
||||
# Get all files in the unpacked directory
|
||||
all_files = list(self.unpacked_dir.rglob("*"))
|
||||
all_files = [f for f in all_files if f.is_file()]
|
||||
|
||||
# Check all XML files for Override declarations
|
||||
for xml_file in self.xml_files:
|
||||
path_str = str(xml_file.relative_to(self.unpacked_dir)).replace(
|
||||
"\\", "/"
|
||||
)
|
||||
|
||||
# Skip non-content files
|
||||
if any(
|
||||
skip in path_str
|
||||
for skip in [".rels", "[Content_Types]", "docProps/", "_rels/"]
|
||||
):
|
||||
continue
|
||||
|
||||
try:
|
||||
root_tag = lxml.etree.parse(str(xml_file)).getroot().tag
|
||||
root_name = root_tag.split("}")[-1] if "}" in root_tag else root_tag
|
||||
|
||||
if root_name in declarable_roots and path_str not in declared_parts:
|
||||
errors.append(
|
||||
f" {path_str}: File with <{root_name}> root not declared in [Content_Types].xml"
|
||||
)
|
||||
|
||||
except Exception:
|
||||
continue # Skip unparseable files
|
||||
|
||||
# Check all non-XML files for Default extension declarations
|
||||
for file_path in all_files:
|
||||
# Skip XML files and metadata files (already checked above)
|
||||
if file_path.suffix.lower() in {".xml", ".rels"}:
|
||||
continue
|
||||
if file_path.name == "[Content_Types].xml":
|
||||
continue
|
||||
if "_rels" in file_path.parts or "docProps" in file_path.parts:
|
||||
continue
|
||||
|
||||
extension = file_path.suffix.lstrip(".").lower()
|
||||
if extension and extension not in declared_extensions:
|
||||
# Check if it's a known media extension that should be declared
|
||||
if extension in media_extensions:
|
||||
relative_path = file_path.relative_to(self.unpacked_dir)
|
||||
errors.append(
|
||||
f' {relative_path}: File with extension \'{extension}\' not declared in [Content_Types].xml - should add: <Default Extension="{extension}" ContentType="{media_extensions[extension]}"/>'
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
errors.append(f" Error parsing [Content_Types].xml: {e}")
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} content type declaration errors:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print(
|
||||
"PASSED - All content files are properly declared in [Content_Types].xml"
|
||||
)
|
||||
return True
|
||||
|
||||
def validate_file_against_xsd(self, xml_file, verbose=False):
|
||||
"""Validate a single XML file against XSD schema, comparing with original.
|
||||
|
||||
Args:
|
||||
xml_file: Path to XML file to validate
|
||||
verbose: Enable verbose output
|
||||
|
||||
Returns:
|
||||
tuple: (is_valid, new_errors_set) where is_valid is True/False/None (skipped)
|
||||
"""
|
||||
# Resolve both paths to handle symlinks
|
||||
xml_file = Path(xml_file).resolve()
|
||||
unpacked_dir = self.unpacked_dir.resolve()
|
||||
|
||||
# Validate current file
|
||||
is_valid, current_errors = self._validate_single_file_xsd(
|
||||
xml_file, unpacked_dir
|
||||
)
|
||||
|
||||
if is_valid is None:
|
||||
return None, set() # Skipped
|
||||
elif is_valid:
|
||||
return True, set() # Valid, no errors
|
||||
|
||||
# Get errors from original file for this specific file
|
||||
original_errors = self._get_original_file_errors(xml_file)
|
||||
|
||||
# Compare with original (both are guaranteed to be sets here)
|
||||
assert current_errors is not None
|
||||
new_errors = current_errors - original_errors
|
||||
|
||||
if new_errors:
|
||||
if verbose:
|
||||
relative_path = xml_file.relative_to(unpacked_dir)
|
||||
print(f"FAILED - {relative_path}: {len(new_errors)} new error(s)")
|
||||
for error in list(new_errors)[:3]:
|
||||
truncated = error[:250] + "..." if len(error) > 250 else error
|
||||
print(f" - {truncated}")
|
||||
return False, new_errors
|
||||
else:
|
||||
# All errors existed in original
|
||||
if verbose:
|
||||
print(
|
||||
f"PASSED - No new errors (original had {len(current_errors)} errors)"
|
||||
)
|
||||
return True, set()
|
||||
|
||||
def validate_against_xsd(self):
|
||||
"""Validate XML files against XSD schemas, showing only new errors compared to original."""
|
||||
new_errors = []
|
||||
original_error_count = 0
|
||||
valid_count = 0
|
||||
skipped_count = 0
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
relative_path = str(xml_file.relative_to(self.unpacked_dir))
|
||||
is_valid, new_file_errors = self.validate_file_against_xsd(
|
||||
xml_file, verbose=False
|
||||
)
|
||||
|
||||
if is_valid is None:
|
||||
skipped_count += 1
|
||||
continue
|
||||
elif is_valid and not new_file_errors:
|
||||
valid_count += 1
|
||||
continue
|
||||
elif is_valid:
|
||||
# Had errors but all existed in original
|
||||
original_error_count += 1
|
||||
valid_count += 1
|
||||
continue
|
||||
|
||||
# Has new errors
|
||||
new_errors.append(f" {relative_path}: {len(new_file_errors)} new error(s)")
|
||||
for error in list(new_file_errors)[:3]: # Show first 3 errors
|
||||
new_errors.append(
|
||||
f" - {error[:250]}..." if len(error) > 250 else f" - {error}"
|
||||
)
|
||||
|
||||
# Print summary
|
||||
if self.verbose:
|
||||
print(f"Validated {len(self.xml_files)} files:")
|
||||
print(f" - Valid: {valid_count}")
|
||||
print(f" - Skipped (no schema): {skipped_count}")
|
||||
if original_error_count:
|
||||
print(f" - With original errors (ignored): {original_error_count}")
|
||||
print(
|
||||
f" - With NEW errors: {len(new_errors) > 0 and len([e for e in new_errors if not e.startswith(' ')]) or 0}"
|
||||
)
|
||||
|
||||
if new_errors:
|
||||
print("\nFAILED - Found NEW validation errors:")
|
||||
for error in new_errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("\nPASSED - No new XSD validation errors introduced")
|
||||
return True
|
||||
|
||||
def _get_schema_path(self, xml_file):
|
||||
"""Determine the appropriate schema path for an XML file."""
|
||||
# Check exact filename match
|
||||
if xml_file.name in self.SCHEMA_MAPPINGS:
|
||||
return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.name]
|
||||
|
||||
# Check .rels files
|
||||
if xml_file.suffix == ".rels":
|
||||
return self.schemas_dir / self.SCHEMA_MAPPINGS[".rels"]
|
||||
|
||||
# Check chart files
|
||||
if "charts/" in str(xml_file) and xml_file.name.startswith("chart"):
|
||||
return self.schemas_dir / self.SCHEMA_MAPPINGS["chart"]
|
||||
|
||||
# Check theme files
|
||||
if "theme/" in str(xml_file) and xml_file.name.startswith("theme"):
|
||||
return self.schemas_dir / self.SCHEMA_MAPPINGS["theme"]
|
||||
|
||||
# Check if file is in a main content folder and use appropriate schema
|
||||
if xml_file.parent.name in self.MAIN_CONTENT_FOLDERS:
|
||||
return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.parent.name]
|
||||
|
||||
return None
|
||||
|
||||
def _clean_ignorable_namespaces(self, xml_doc):
|
||||
"""Remove attributes and elements not in allowed namespaces."""
|
||||
# Create a clean copy
|
||||
xml_string = lxml.etree.tostring(xml_doc, encoding="unicode")
|
||||
xml_copy = lxml.etree.fromstring(xml_string)
|
||||
|
||||
# Remove attributes not in allowed namespaces
|
||||
for elem in xml_copy.iter():
|
||||
attrs_to_remove = []
|
||||
|
||||
for attr in elem.attrib:
|
||||
# Check if attribute is from a namespace other than allowed ones
|
||||
if "{" in attr:
|
||||
ns = attr.split("}")[0][1:]
|
||||
if ns not in self.OOXML_NAMESPACES:
|
||||
attrs_to_remove.append(attr)
|
||||
|
||||
# Remove collected attributes
|
||||
for attr in attrs_to_remove:
|
||||
del elem.attrib[attr]
|
||||
|
||||
# Remove elements not in allowed namespaces
|
||||
self._remove_ignorable_elements(xml_copy)
|
||||
|
||||
return lxml.etree.ElementTree(xml_copy)
|
||||
|
||||
def _remove_ignorable_elements(self, root):
|
||||
"""Recursively remove all elements not in allowed namespaces."""
|
||||
elements_to_remove = []
|
||||
|
||||
# Find elements to remove
|
||||
for elem in list(root):
|
||||
# Skip non-element nodes (comments, processing instructions, etc.)
|
||||
if not hasattr(elem, "tag") or callable(elem.tag):
|
||||
continue
|
||||
|
||||
tag_str = str(elem.tag)
|
||||
if tag_str.startswith("{"):
|
||||
ns = tag_str.split("}")[0][1:]
|
||||
if ns not in self.OOXML_NAMESPACES:
|
||||
elements_to_remove.append(elem)
|
||||
continue
|
||||
|
||||
# Recursively clean child elements
|
||||
self._remove_ignorable_elements(elem)
|
||||
|
||||
# Remove collected elements
|
||||
for elem in elements_to_remove:
|
||||
root.remove(elem)
|
||||
|
||||
def _preprocess_for_mc_ignorable(self, xml_doc):
|
||||
"""Preprocess XML to handle mc:Ignorable attribute properly."""
|
||||
# Remove mc:Ignorable attributes before validation
|
||||
root = xml_doc.getroot()
|
||||
|
||||
# Remove mc:Ignorable attribute from root
|
||||
if f"{{{self.MC_NAMESPACE}}}Ignorable" in root.attrib:
|
||||
del root.attrib[f"{{{self.MC_NAMESPACE}}}Ignorable"]
|
||||
|
||||
return xml_doc
|
||||
|
||||
def _validate_single_file_xsd(self, xml_file, base_path):
|
||||
"""Validate a single XML file against XSD schema. Returns (is_valid, errors_set)."""
|
||||
schema_path = self._get_schema_path(xml_file)
|
||||
if not schema_path:
|
||||
return None, None # Skip file
|
||||
|
||||
try:
|
||||
# Load schema
|
||||
with open(schema_path, "rb") as xsd_file:
|
||||
parser = lxml.etree.XMLParser()
|
||||
xsd_doc = lxml.etree.parse(
|
||||
xsd_file, parser=parser, base_url=str(schema_path)
|
||||
)
|
||||
schema = lxml.etree.XMLSchema(xsd_doc)
|
||||
|
||||
# Load and preprocess XML
|
||||
with open(xml_file, "r") as f:
|
||||
xml_doc = lxml.etree.parse(f)
|
||||
|
||||
xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc)
|
||||
xml_doc = self._preprocess_for_mc_ignorable(xml_doc)
|
||||
|
||||
# Clean ignorable namespaces if needed
|
||||
relative_path = xml_file.relative_to(base_path)
|
||||
if (
|
||||
relative_path.parts
|
||||
and relative_path.parts[0] in self.MAIN_CONTENT_FOLDERS
|
||||
):
|
||||
xml_doc = self._clean_ignorable_namespaces(xml_doc)
|
||||
|
||||
# Validate
|
||||
if schema.validate(xml_doc):
|
||||
return True, set()
|
||||
else:
|
||||
errors = set()
|
||||
for error in schema.error_log:
|
||||
# Store normalized error message (without line numbers for comparison)
|
||||
errors.add(error.message)
|
||||
return False, errors
|
||||
|
||||
except Exception as e:
|
||||
return False, {str(e)}
|
||||
|
||||
def _get_original_file_errors(self, xml_file):
|
||||
"""Get XSD validation errors from a single file in the original document.
|
||||
|
||||
Args:
|
||||
xml_file: Path to the XML file in unpacked_dir to check
|
||||
|
||||
Returns:
|
||||
set: Set of error messages from the original file
|
||||
"""
|
||||
# Resolve both paths to handle symlinks (e.g., /var vs /private/var on macOS)
|
||||
xml_file = Path(xml_file).resolve()
|
||||
unpacked_dir = self.unpacked_dir.resolve()
|
||||
relative_path = xml_file.relative_to(unpacked_dir)
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
|
||||
# Extract original file
|
||||
with zipfile.ZipFile(self.original_file, "r") as zip_ref:
|
||||
zip_ref.extractall(temp_path)
|
||||
|
||||
# Find corresponding file in original
|
||||
original_xml_file = temp_path / relative_path
|
||||
|
||||
if not original_xml_file.exists():
|
||||
# File didn't exist in original, so no original errors
|
||||
return set()
|
||||
|
||||
# Validate the specific file in original
|
||||
is_valid, errors = self._validate_single_file_xsd(
|
||||
original_xml_file, temp_path
|
||||
)
|
||||
return errors if errors else set()
|
||||
|
||||
def _remove_template_tags_from_text_nodes(self, xml_doc):
|
||||
"""Remove template tags from XML text nodes and collect warnings.
|
||||
|
||||
Template tags follow the pattern {{ ... }} and are used as placeholders
|
||||
for content replacement. They should be removed from text content before
|
||||
XSD validation while preserving XML structure.
|
||||
|
||||
Returns:
|
||||
tuple: (cleaned_xml_doc, warnings_list)
|
||||
"""
|
||||
warnings = []
|
||||
template_pattern = re.compile(r"\{\{[^}]*\}\}")
|
||||
|
||||
# Create a copy of the document to avoid modifying the original
|
||||
xml_string = lxml.etree.tostring(xml_doc, encoding="unicode")
|
||||
xml_copy = lxml.etree.fromstring(xml_string)
|
||||
|
||||
def process_text_content(text, content_type):
|
||||
if not text:
|
||||
return text
|
||||
matches = list(template_pattern.finditer(text))
|
||||
if matches:
|
||||
for match in matches:
|
||||
warnings.append(
|
||||
f"Found template tag in {content_type}: {match.group()}"
|
||||
)
|
||||
return template_pattern.sub("", text)
|
||||
return text
|
||||
|
||||
# Process all text nodes in the document
|
||||
for elem in xml_copy.iter():
|
||||
# Skip processing if this is a w:t element
|
||||
if not hasattr(elem, "tag") or callable(elem.tag):
|
||||
continue
|
||||
tag_str = str(elem.tag)
|
||||
if tag_str.endswith("}t") or tag_str == "t":
|
||||
continue
|
||||
|
||||
elem.text = process_text_content(elem.text, "text content")
|
||||
elem.tail = process_text_content(elem.tail, "tail content")
|
||||
|
||||
return lxml.etree.ElementTree(xml_copy), warnings
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise RuntimeError("This module should not be run directly.")
|
||||
274
skills/ppt/ooxml/scripts/validation/docx.py
Executable file
274
skills/ppt/ooxml/scripts/validation/docx.py
Executable file
@@ -0,0 +1,274 @@
|
||||
"""
|
||||
Validator for Word document XML files against XSD schemas.
|
||||
"""
|
||||
|
||||
import re
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
import lxml.etree
|
||||
|
||||
from .base import BaseSchemaValidator
|
||||
|
||||
|
||||
class DOCXSchemaValidator(BaseSchemaValidator):
|
||||
"""Validator for Word document XML files against XSD schemas."""
|
||||
|
||||
# Word-specific namespace
|
||||
WORD_2006_NAMESPACE = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
|
||||
# Word-specific element to relationship type mappings
|
||||
# Start with empty mapping - add specific cases as we discover them
|
||||
ELEMENT_RELATIONSHIP_TYPES = {}
|
||||
|
||||
def validate(self):
|
||||
"""Run all validation checks and return True if all pass."""
|
||||
# Test 0: XML well-formedness
|
||||
if not self.validate_xml():
|
||||
return False
|
||||
|
||||
# Test 1: Namespace declarations
|
||||
all_valid = True
|
||||
if not self.validate_namespaces():
|
||||
all_valid = False
|
||||
|
||||
# Test 2: Unique IDs
|
||||
if not self.validate_unique_ids():
|
||||
all_valid = False
|
||||
|
||||
# Test 3: Relationship and file reference validation
|
||||
if not self.validate_file_references():
|
||||
all_valid = False
|
||||
|
||||
# Test 4: Content type declarations
|
||||
if not self.validate_content_types():
|
||||
all_valid = False
|
||||
|
||||
# Test 5: XSD schema validation
|
||||
if not self.validate_against_xsd():
|
||||
all_valid = False
|
||||
|
||||
# Test 6: Whitespace preservation
|
||||
if not self.validate_whitespace_preservation():
|
||||
all_valid = False
|
||||
|
||||
# Test 7: Deletion validation
|
||||
if not self.validate_deletions():
|
||||
all_valid = False
|
||||
|
||||
# Test 8: Insertion validation
|
||||
if not self.validate_insertions():
|
||||
all_valid = False
|
||||
|
||||
# Test 9: Relationship ID reference validation
|
||||
if not self.validate_all_relationship_ids():
|
||||
all_valid = False
|
||||
|
||||
# Count and compare paragraphs
|
||||
self.compare_paragraph_counts()
|
||||
|
||||
return all_valid
|
||||
|
||||
def validate_whitespace_preservation(self):
|
||||
"""
|
||||
Validate that w:t elements with whitespace have xml:space='preserve'.
|
||||
"""
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
# Only check document.xml files
|
||||
if xml_file.name != "document.xml":
|
||||
continue
|
||||
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
|
||||
# Find all w:t elements
|
||||
for elem in root.iter(f"{{{self.WORD_2006_NAMESPACE}}}t"):
|
||||
if elem.text:
|
||||
text = elem.text
|
||||
# Check if text starts or ends with whitespace
|
||||
if re.match(r"^\s.*", text) or re.match(r".*\s$", text):
|
||||
# Check if xml:space="preserve" attribute exists
|
||||
xml_space_attr = f"{{{self.XML_NAMESPACE}}}space"
|
||||
if (
|
||||
xml_space_attr not in elem.attrib
|
||||
or elem.attrib[xml_space_attr] != "preserve"
|
||||
):
|
||||
# Show a preview of the text
|
||||
text_preview = (
|
||||
repr(text)[:50] + "..."
|
||||
if len(repr(text)) > 50
|
||||
else repr(text)
|
||||
)
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {elem.sourceline}: w:t element with whitespace missing xml:space='preserve': {text_preview}"
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} whitespace preservation violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All whitespace is properly preserved")
|
||||
return True
|
||||
|
||||
def validate_deletions(self):
|
||||
"""
|
||||
Validate that w:t elements are not within w:del elements.
|
||||
For some reason, XSD validation does not catch this, so we do it manually.
|
||||
"""
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
# Only check document.xml files
|
||||
if xml_file.name != "document.xml":
|
||||
continue
|
||||
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
|
||||
# Find all w:t elements that are descendants of w:del elements
|
||||
namespaces = {"w": self.WORD_2006_NAMESPACE}
|
||||
xpath_expression = ".//w:del//w:t"
|
||||
problematic_t_elements = root.xpath(
|
||||
xpath_expression, namespaces=namespaces
|
||||
)
|
||||
for t_elem in problematic_t_elements:
|
||||
if t_elem.text:
|
||||
# Show a preview of the text
|
||||
text_preview = (
|
||||
repr(t_elem.text)[:50] + "..."
|
||||
if len(repr(t_elem.text)) > 50
|
||||
else repr(t_elem.text)
|
||||
)
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {t_elem.sourceline}: <w:t> found within <w:del>: {text_preview}"
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} deletion validation violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - No w:t elements found within w:del elements")
|
||||
return True
|
||||
|
||||
def count_paragraphs_in_unpacked(self):
|
||||
"""Count the number of paragraphs in the unpacked document."""
|
||||
count = 0
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
# Only check document.xml files
|
||||
if xml_file.name != "document.xml":
|
||||
continue
|
||||
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
# Count all w:p elements
|
||||
paragraphs = root.findall(f".//{{{self.WORD_2006_NAMESPACE}}}p")
|
||||
count = len(paragraphs)
|
||||
except Exception as e:
|
||||
print(f"Error counting paragraphs in unpacked document: {e}")
|
||||
|
||||
return count
|
||||
|
||||
def count_paragraphs_in_original(self):
|
||||
"""Count the number of paragraphs in the original docx file."""
|
||||
count = 0
|
||||
|
||||
try:
|
||||
# Create temporary directory to unpack original
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
# Unpack original docx
|
||||
with zipfile.ZipFile(self.original_file, "r") as zip_ref:
|
||||
zip_ref.extractall(temp_dir)
|
||||
|
||||
# Parse document.xml
|
||||
doc_xml_path = temp_dir + "/word/document.xml"
|
||||
root = lxml.etree.parse(doc_xml_path).getroot()
|
||||
|
||||
# Count all w:p elements
|
||||
paragraphs = root.findall(f".//{{{self.WORD_2006_NAMESPACE}}}p")
|
||||
count = len(paragraphs)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error counting paragraphs in original document: {e}")
|
||||
|
||||
return count
|
||||
|
||||
def validate_insertions(self):
|
||||
"""
|
||||
Validate that w:delText elements are not within w:ins elements.
|
||||
w:delText is only allowed in w:ins if nested within a w:del.
|
||||
"""
|
||||
errors = []
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
if xml_file.name != "document.xml":
|
||||
continue
|
||||
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
namespaces = {"w": self.WORD_2006_NAMESPACE}
|
||||
|
||||
# Find w:delText in w:ins that are NOT within w:del
|
||||
invalid_elements = root.xpath(
|
||||
".//w:ins//w:delText[not(ancestor::w:del)]",
|
||||
namespaces=namespaces
|
||||
)
|
||||
|
||||
for elem in invalid_elements:
|
||||
text_preview = (
|
||||
repr(elem.text or "")[:50] + "..."
|
||||
if len(repr(elem.text or "")) > 50
|
||||
else repr(elem.text or "")
|
||||
)
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {elem.sourceline}: <w:delText> within <w:ins>: {text_preview}"
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} insertion validation violations:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - No w:delText elements within w:ins elements")
|
||||
return True
|
||||
|
||||
def compare_paragraph_counts(self):
|
||||
"""Compare paragraph counts between original and new document."""
|
||||
original_count = self.count_paragraphs_in_original()
|
||||
new_count = self.count_paragraphs_in_unpacked()
|
||||
|
||||
diff = new_count - original_count
|
||||
diff_str = f"+{diff}" if diff > 0 else str(diff)
|
||||
print(f"\nParagraphs: {original_count} → {new_count} ({diff_str})")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise RuntimeError("This module should not be run directly.")
|
||||
309
skills/ppt/ooxml/scripts/validation/pptx.py
Executable file
309
skills/ppt/ooxml/scripts/validation/pptx.py
Executable file
@@ -0,0 +1,309 @@
|
||||
"""
|
||||
Validator for PowerPoint presentation XML files against XSD schemas.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
import lxml.etree
|
||||
|
||||
from .base import BaseSchemaValidator
|
||||
|
||||
|
||||
class PPTXSchemaValidator(BaseSchemaValidator):
|
||||
"""Validator for PowerPoint presentation XML files against XSD schemas."""
|
||||
|
||||
# PowerPoint presentation namespace
|
||||
PRESENTATIONML_NAMESPACE = (
|
||||
"http://schemas.openxmlformats.org/presentationml/2006/main"
|
||||
)
|
||||
|
||||
# PowerPoint-specific element to relationship type mappings
|
||||
ELEMENT_RELATIONSHIP_TYPES = {
|
||||
"sldid": "slide",
|
||||
"sldmasterid": "slidemaster",
|
||||
"notesmasterid": "notesmaster",
|
||||
"sldlayoutid": "slidelayout",
|
||||
"themeid": "theme",
|
||||
"tablestyleid": "tablestyles",
|
||||
}
|
||||
|
||||
def validate(self):
|
||||
"""Run all validation checks and return True if all pass."""
|
||||
# Test 0: XML well-formedness
|
||||
if not self.validate_xml():
|
||||
return False
|
||||
|
||||
# Test 1: Namespace declarations
|
||||
all_valid = True
|
||||
if not self.validate_namespaces():
|
||||
all_valid = False
|
||||
|
||||
# Test 2: Unique IDs
|
||||
if not self.validate_unique_ids():
|
||||
all_valid = False
|
||||
|
||||
# Test 3: UUID ID validation
|
||||
if not self.validate_uuid_ids():
|
||||
all_valid = False
|
||||
|
||||
# Test 4: Relationship and file reference validation
|
||||
if not self.validate_file_references():
|
||||
all_valid = False
|
||||
|
||||
# Test 5: Slide layout ID validation
|
||||
if not self.validate_slide_layout_ids():
|
||||
all_valid = False
|
||||
|
||||
# Test 6: Content type declarations
|
||||
if not self.validate_content_types():
|
||||
all_valid = False
|
||||
|
||||
# Test 7: XSD schema validation
|
||||
if not self.validate_against_xsd():
|
||||
all_valid = False
|
||||
|
||||
# Test 8: Notes slide reference validation
|
||||
if not self.validate_notes_slide_references():
|
||||
all_valid = False
|
||||
|
||||
# Test 9: Relationship ID reference validation
|
||||
if not self.validate_all_relationship_ids():
|
||||
all_valid = False
|
||||
|
||||
# Test 10: Duplicate slide layout references validation
|
||||
if not self.validate_no_duplicate_slide_layouts():
|
||||
all_valid = False
|
||||
|
||||
return all_valid
|
||||
|
||||
def validate_uuid_ids(self):
|
||||
"""Validate that ID attributes that look like UUIDs contain only hex values."""
|
||||
errors = []
|
||||
# UUID pattern: 8-4-4-4-12 hex digits with optional braces/hyphens
|
||||
uuid_pattern = re.compile(
|
||||
r"^[\{\(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[\}\)]?$"
|
||||
)
|
||||
|
||||
for xml_file in self.xml_files:
|
||||
try:
|
||||
root = lxml.etree.parse(str(xml_file)).getroot()
|
||||
|
||||
# Check all elements for ID attributes
|
||||
for elem in root.iter():
|
||||
for attr, value in elem.attrib.items():
|
||||
# Check if this is an ID attribute
|
||||
attr_name = attr.split("}")[-1].lower()
|
||||
if attr_name == "id" or attr_name.endswith("id"):
|
||||
# Check if value looks like a UUID (has the right length and pattern structure)
|
||||
if self._looks_like_uuid(value):
|
||||
# Validate that it contains only hex characters in the right positions
|
||||
if not uuid_pattern.match(value):
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {elem.sourceline}: ID '{value}' appears to be a UUID but contains invalid hex characters"
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} UUID ID validation errors:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All UUID-like IDs contain valid hex values")
|
||||
return True
|
||||
|
||||
def _looks_like_uuid(self, value):
|
||||
"""Check if a value has the general structure of a UUID."""
|
||||
# Remove common UUID delimiters
|
||||
clean_value = value.strip("{}()").replace("-", "")
|
||||
# Check if it's 32 hex-like characters (could include invalid hex chars)
|
||||
return len(clean_value) == 32 and all(c.isalnum() for c in clean_value)
|
||||
|
||||
def validate_slide_layout_ids(self):
|
||||
"""Validate that sldLayoutId elements in slide masters reference valid slide layouts."""
|
||||
errors = []
|
||||
|
||||
# Find all slide master files
|
||||
slide_masters = list(self.unpacked_dir.glob("ppt/slideMasters/*.xml"))
|
||||
|
||||
if not slide_masters:
|
||||
if self.verbose:
|
||||
print("PASSED - No slide masters found")
|
||||
return True
|
||||
|
||||
for slide_master in slide_masters:
|
||||
try:
|
||||
# Parse the slide master file
|
||||
root = lxml.etree.parse(str(slide_master)).getroot()
|
||||
|
||||
# Find the corresponding _rels file for this slide master
|
||||
rels_file = slide_master.parent / "_rels" / f"{slide_master.name}.rels"
|
||||
|
||||
if not rels_file.exists():
|
||||
errors.append(
|
||||
f" {slide_master.relative_to(self.unpacked_dir)}: "
|
||||
f"Missing relationships file: {rels_file.relative_to(self.unpacked_dir)}"
|
||||
)
|
||||
continue
|
||||
|
||||
# Parse the relationships file
|
||||
rels_root = lxml.etree.parse(str(rels_file)).getroot()
|
||||
|
||||
# Build a set of valid relationship IDs that point to slide layouts
|
||||
valid_layout_rids = set()
|
||||
for rel in rels_root.findall(
|
||||
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
||||
):
|
||||
rel_type = rel.get("Type", "")
|
||||
if "slideLayout" in rel_type:
|
||||
valid_layout_rids.add(rel.get("Id"))
|
||||
|
||||
# Find all sldLayoutId elements in the slide master
|
||||
for sld_layout_id in root.findall(
|
||||
f".//{{{self.PRESENTATIONML_NAMESPACE}}}sldLayoutId"
|
||||
):
|
||||
r_id = sld_layout_id.get(
|
||||
f"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id"
|
||||
)
|
||||
layout_id = sld_layout_id.get("id")
|
||||
|
||||
if r_id and r_id not in valid_layout_rids:
|
||||
errors.append(
|
||||
f" {slide_master.relative_to(self.unpacked_dir)}: "
|
||||
f"Line {sld_layout_id.sourceline}: sldLayoutId with id='{layout_id}' "
|
||||
f"references r:id='{r_id}' which is not found in slide layout relationships"
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {slide_master.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print(f"FAILED - Found {len(errors)} slide layout ID validation errors:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
print(
|
||||
"Remove invalid references or add missing slide layouts to the relationships file."
|
||||
)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All slide layout IDs reference valid slide layouts")
|
||||
return True
|
||||
|
||||
def validate_no_duplicate_slide_layouts(self):
|
||||
"""Validate that each slide has exactly one slideLayout reference."""
|
||||
errors = []
|
||||
slide_rels_files = list(self.unpacked_dir.glob("ppt/slides/_rels/*.xml.rels"))
|
||||
|
||||
for rels_file in slide_rels_files:
|
||||
try:
|
||||
root = lxml.etree.parse(str(rels_file)).getroot()
|
||||
|
||||
# Find all slideLayout relationships
|
||||
layout_rels = [
|
||||
rel
|
||||
for rel in root.findall(
|
||||
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
||||
)
|
||||
if "slideLayout" in rel.get("Type", "")
|
||||
]
|
||||
|
||||
if len(layout_rels) > 1:
|
||||
errors.append(
|
||||
f" {rels_file.relative_to(self.unpacked_dir)}: has {len(layout_rels)} slideLayout references"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
errors.append(
|
||||
f" {rels_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
if errors:
|
||||
print("FAILED - Found slides with duplicate slideLayout references:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All slides have exactly one slideLayout reference")
|
||||
return True
|
||||
|
||||
def validate_notes_slide_references(self):
|
||||
"""Validate that each notesSlide file is referenced by only one slide."""
|
||||
errors = []
|
||||
notes_slide_references = {} # Track which slides reference each notesSlide
|
||||
|
||||
# Find all slide relationship files
|
||||
slide_rels_files = list(self.unpacked_dir.glob("ppt/slides/_rels/*.xml.rels"))
|
||||
|
||||
if not slide_rels_files:
|
||||
if self.verbose:
|
||||
print("PASSED - No slide relationship files found")
|
||||
return True
|
||||
|
||||
for rels_file in slide_rels_files:
|
||||
try:
|
||||
# Parse the relationships file
|
||||
root = lxml.etree.parse(str(rels_file)).getroot()
|
||||
|
||||
# Find all notesSlide relationships
|
||||
for rel in root.findall(
|
||||
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
||||
):
|
||||
rel_type = rel.get("Type", "")
|
||||
if "notesSlide" in rel_type:
|
||||
target = rel.get("Target", "")
|
||||
if target:
|
||||
# Normalize the target path to handle relative paths
|
||||
normalized_target = target.replace("../", "")
|
||||
|
||||
# Track which slide references this notesSlide
|
||||
slide_name = rels_file.stem.replace(
|
||||
".xml", ""
|
||||
) # e.g., "slide1"
|
||||
|
||||
if normalized_target not in notes_slide_references:
|
||||
notes_slide_references[normalized_target] = []
|
||||
notes_slide_references[normalized_target].append(
|
||||
(slide_name, rels_file)
|
||||
)
|
||||
|
||||
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
||||
errors.append(
|
||||
f" {rels_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
||||
)
|
||||
|
||||
# Check for duplicate references
|
||||
for target, references in notes_slide_references.items():
|
||||
if len(references) > 1:
|
||||
slide_names = [ref[0] for ref in references]
|
||||
errors.append(
|
||||
f" Notes slide '{target}' is referenced by multiple slides: {', '.join(slide_names)}"
|
||||
)
|
||||
for slide_name, rels_file in references:
|
||||
errors.append(f" - {rels_file.relative_to(self.unpacked_dir)}")
|
||||
|
||||
if errors:
|
||||
print(
|
||||
f"FAILED - Found {len([e for e in errors if not e.startswith(' ')])} notes slide reference validation errors:"
|
||||
)
|
||||
for error in errors:
|
||||
print(error)
|
||||
print("Each slide may optionally have its own slide file.")
|
||||
return False
|
||||
else:
|
||||
if self.verbose:
|
||||
print("PASSED - All notes slide references are unique")
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise RuntimeError("This module should not be run directly.")
|
||||
279
skills/ppt/ooxml/scripts/validation/redlining.py
Executable file
279
skills/ppt/ooxml/scripts/validation/redlining.py
Executable file
@@ -0,0 +1,279 @@
|
||||
"""
|
||||
Validator for tracked changes in Word documents.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import tempfile
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class RedliningValidator:
|
||||
"""Validator for tracked changes in Word documents."""
|
||||
|
||||
def __init__(self, unpacked_dir, original_docx, verbose=False):
|
||||
self.unpacked_dir = Path(unpacked_dir)
|
||||
self.original_docx = Path(original_docx)
|
||||
self.verbose = verbose
|
||||
self.namespaces = {
|
||||
"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
}
|
||||
|
||||
def validate(self):
|
||||
"""Main validation method that returns True if valid, False otherwise."""
|
||||
# Verify unpacked directory exists and has correct structure
|
||||
modified_file = self.unpacked_dir / "word" / "document.xml"
|
||||
if not modified_file.exists():
|
||||
print(f"FAILED - Modified document.xml not found at {modified_file}")
|
||||
return False
|
||||
|
||||
# First, check if there are any tracked changes by Z.AI to validate
|
||||
try:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
tree = ET.parse(modified_file)
|
||||
root = tree.getroot()
|
||||
|
||||
# Check for w:del or w:ins tags authored by Z.AI
|
||||
del_elements = root.findall(".//w:del", self.namespaces)
|
||||
ins_elements = root.findall(".//w:ins", self.namespaces)
|
||||
|
||||
# Filter to only include changes by Z.AI
|
||||
zai_del_elements = [
|
||||
elem
|
||||
for elem in del_elements
|
||||
if elem.get(f"{{{self.namespaces['w']}}}author") == "Z.AI"
|
||||
]
|
||||
zai_ins_elements = [
|
||||
elem
|
||||
for elem in ins_elements
|
||||
if elem.get(f"{{{self.namespaces['w']}}}author") == "Z.AI"
|
||||
]
|
||||
|
||||
# Redlining validation is only needed if tracked changes by Z.AI have been used.
|
||||
if not zai_del_elements and not zai_ins_elements:
|
||||
if self.verbose:
|
||||
print("PASSED - No tracked changes by Z.AI found.")
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
# If we can't parse the XML, continue with full validation
|
||||
pass
|
||||
|
||||
# Create temporary directory for unpacking original docx
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
|
||||
# Unpack original docx
|
||||
try:
|
||||
with zipfile.ZipFile(self.original_docx, "r") as zip_ref:
|
||||
zip_ref.extractall(temp_path)
|
||||
except Exception as e:
|
||||
print(f"FAILED - Error unpacking original docx: {e}")
|
||||
return False
|
||||
|
||||
original_file = temp_path / "word" / "document.xml"
|
||||
if not original_file.exists():
|
||||
print(
|
||||
f"FAILED - Original document.xml not found in {self.original_docx}"
|
||||
)
|
||||
return False
|
||||
|
||||
# Parse both XML files using xml.etree.ElementTree for redlining validation
|
||||
try:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
modified_tree = ET.parse(modified_file)
|
||||
modified_root = modified_tree.getroot()
|
||||
original_tree = ET.parse(original_file)
|
||||
original_root = original_tree.getroot()
|
||||
except ET.ParseError as e:
|
||||
print(f"FAILED - Error parsing XML files: {e}")
|
||||
return False
|
||||
|
||||
# Remove Z.AI's tracked changes from both documents
|
||||
self._remove_zai_tracked_changes(original_root)
|
||||
self._remove_zai_tracked_changes(modified_root)
|
||||
|
||||
# Extract and compare text content
|
||||
modified_text = self._extract_text_content(modified_root)
|
||||
original_text = self._extract_text_content(original_root)
|
||||
|
||||
if modified_text != original_text:
|
||||
# Show detailed character-level differences for each paragraph
|
||||
error_message = self._generate_detailed_diff(
|
||||
original_text, modified_text
|
||||
)
|
||||
print(error_message)
|
||||
return False
|
||||
|
||||
if self.verbose:
|
||||
print("PASSED - All changes by Z.AI are properly tracked")
|
||||
return True
|
||||
|
||||
def _generate_detailed_diff(self, original_text, modified_text):
|
||||
"""Generate detailed word-level differences using git word diff."""
|
||||
error_parts = [
|
||||
"FAILED - Document text doesn't match after removing Z.AI's tracked changes",
|
||||
"",
|
||||
"Likely causes:",
|
||||
" 1. Modified text inside another author's <w:ins> or <w:del> tags",
|
||||
" 2. Made edits without proper tracked changes",
|
||||
" 3. Didn't nest <w:del> inside <w:ins> when deleting another's insertion",
|
||||
"",
|
||||
"For pre-redlined documents, use correct patterns:",
|
||||
" - To reject another's INSERTION: Nest <w:del> inside their <w:ins>",
|
||||
" - To restore another's DELETION: Add new <w:ins> AFTER their <w:del>",
|
||||
"",
|
||||
]
|
||||
|
||||
# Show git word diff
|
||||
git_diff = self._get_git_word_diff(original_text, modified_text)
|
||||
if git_diff:
|
||||
error_parts.extend(["Differences:", "============", git_diff])
|
||||
else:
|
||||
error_parts.append("Unable to generate word diff (git not available)")
|
||||
|
||||
return "\n".join(error_parts)
|
||||
|
||||
def _get_git_word_diff(self, original_text, modified_text):
|
||||
"""Generate word diff using git with character-level precision."""
|
||||
try:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
|
||||
# Create two files
|
||||
original_file = temp_path / "original.txt"
|
||||
modified_file = temp_path / "modified.txt"
|
||||
|
||||
original_file.write_text(original_text, encoding="utf-8")
|
||||
modified_file.write_text(modified_text, encoding="utf-8")
|
||||
|
||||
# Try character-level diff first for precise differences
|
||||
result = subprocess.run(
|
||||
[
|
||||
"git",
|
||||
"diff",
|
||||
"--word-diff=plain",
|
||||
"--word-diff-regex=.", # Character-by-character diff
|
||||
"-U0", # Zero lines of context - show only changed lines
|
||||
"--no-index",
|
||||
str(original_file),
|
||||
str(modified_file),
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
if result.stdout.strip():
|
||||
# Clean up the output - remove git diff header lines
|
||||
lines = result.stdout.split("\n")
|
||||
# Skip the header lines (diff --git, index, +++, ---, @@)
|
||||
content_lines = []
|
||||
in_content = False
|
||||
for line in lines:
|
||||
if line.startswith("@@"):
|
||||
in_content = True
|
||||
continue
|
||||
if in_content and line.strip():
|
||||
content_lines.append(line)
|
||||
|
||||
if content_lines:
|
||||
return "\n".join(content_lines)
|
||||
|
||||
# Fallback to word-level diff if character-level is too verbose
|
||||
result = subprocess.run(
|
||||
[
|
||||
"git",
|
||||
"diff",
|
||||
"--word-diff=plain",
|
||||
"-U0", # Zero lines of context
|
||||
"--no-index",
|
||||
str(original_file),
|
||||
str(modified_file),
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
if result.stdout.strip():
|
||||
lines = result.stdout.split("\n")
|
||||
content_lines = []
|
||||
in_content = False
|
||||
for line in lines:
|
||||
if line.startswith("@@"):
|
||||
in_content = True
|
||||
continue
|
||||
if in_content and line.strip():
|
||||
content_lines.append(line)
|
||||
return "\n".join(content_lines)
|
||||
|
||||
except (subprocess.CalledProcessError, FileNotFoundError, Exception):
|
||||
# Git not available or other error, return None to use fallback
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
def _remove_zai_tracked_changes(self, root):
|
||||
"""Remove tracked changes authored by Z.AI from the XML root."""
|
||||
ins_tag = f"{{{self.namespaces['w']}}}ins"
|
||||
del_tag = f"{{{self.namespaces['w']}}}del"
|
||||
author_attr = f"{{{self.namespaces['w']}}}author"
|
||||
|
||||
# Remove w:ins elements
|
||||
for parent in root.iter():
|
||||
to_remove = []
|
||||
for child in parent:
|
||||
if child.tag == ins_tag and child.get(author_attr) == "Z.AI":
|
||||
to_remove.append(child)
|
||||
for elem in to_remove:
|
||||
parent.remove(elem)
|
||||
|
||||
# Unwrap content in w:del elements where author is "Z.AI"
|
||||
deltext_tag = f"{{{self.namespaces['w']}}}delText"
|
||||
t_tag = f"{{{self.namespaces['w']}}}t"
|
||||
|
||||
for parent in root.iter():
|
||||
to_process = []
|
||||
for child in parent:
|
||||
if child.tag == del_tag and child.get(author_attr) == "Z.AI":
|
||||
to_process.append((child, list(parent).index(child)))
|
||||
|
||||
# Process in reverse order to maintain indices
|
||||
for del_elem, del_index in reversed(to_process):
|
||||
# Convert w:delText to w:t before moving
|
||||
for elem in del_elem.iter():
|
||||
if elem.tag == deltext_tag:
|
||||
elem.tag = t_tag
|
||||
|
||||
# Move all children of w:del to its parent before removing w:del
|
||||
for child in reversed(list(del_elem)):
|
||||
parent.insert(del_index, child)
|
||||
parent.remove(del_elem)
|
||||
|
||||
def _extract_text_content(self, root):
|
||||
"""Extract text content from Word XML, preserving paragraph structure.
|
||||
|
||||
Empty paragraphs are skipped to avoid false positives when tracked
|
||||
insertions add only structural elements without text content.
|
||||
"""
|
||||
p_tag = f"{{{self.namespaces['w']}}}p"
|
||||
t_tag = f"{{{self.namespaces['w']}}}t"
|
||||
|
||||
paragraphs = []
|
||||
for p_elem in root.findall(f".//{p_tag}"):
|
||||
# Get all text elements within this paragraph
|
||||
text_parts = []
|
||||
for t_elem in p_elem.findall(f".//{t_tag}"):
|
||||
if t_elem.text:
|
||||
text_parts.append(t_elem.text)
|
||||
paragraph_text = "".join(text_parts)
|
||||
# Skip empty paragraphs - they don't affect content validation
|
||||
if paragraph_text:
|
||||
paragraphs.append(paragraph_text)
|
||||
|
||||
return "\n".join(paragraphs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise RuntimeError("This module should not be run directly.")
|
||||
721
skills/ppt/references/beamer.md
Executable file
721
skills/ppt/references/beamer.md
Executable file
@@ -0,0 +1,721 @@
|
||||
# Route: LaTeX Beamer → PDF (via Tectonic)
|
||||
|
||||
Write LaTeX Beamer source, then compile to PDF:
|
||||
|
||||
```bash
|
||||
python3 scripts/pdf.py convert.latex main.tex
|
||||
python3 scripts/pdf.py convert.latex main.tex --runs 2 # for ToC / refs
|
||||
```
|
||||
|
||||
Tectonic compiles the full Beamer document — all features work: overlays,
|
||||
TikZ, custom themes, math, transitions, fragile frames, appendix.
|
||||
|
||||
---
|
||||
|
||||
## 1. Compilation
|
||||
|
||||
```bash
|
||||
# Standard build
|
||||
python3 scripts/pdf.py convert.latex main.tex
|
||||
|
||||
# Two passes (resolves ToC, \ref, section counters in overlays)
|
||||
python3 scripts/pdf.py convert.latex main.tex --runs 2
|
||||
|
||||
# Verbose log (see all Tectonic output)
|
||||
python3 scripts/pdf.py convert.latex main.tex --keep-logs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Beamer Document Structure
|
||||
|
||||
### Minimal Working Example
|
||||
|
||||
```latex
|
||||
\documentclass[aspectratio=169, 11pt]{beamer}
|
||||
\usepackage[fontset=fandol]{ctex} % CJK support (Tectonic auto-downloads)
|
||||
\usetheme{Madrid}
|
||||
|
||||
\title{Introduction to Quantum Computing}
|
||||
\author{Prof. Zhang}
|
||||
\institute{Tsinghua University}
|
||||
\date{\today}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{frame}
|
||||
\titlepage
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Table of Contents}
|
||||
\tableofcontents
|
||||
\end{frame}
|
||||
|
||||
\section{Quantum Bits}
|
||||
|
||||
\begin{frame}{Quantum States}
|
||||
\[ |\psi\rangle = \alpha|0\rangle + \beta|1\rangle, \quad |\alpha|^2+|\beta|^2=1 \]
|
||||
\end{frame}
|
||||
|
||||
\end{document}
|
||||
```
|
||||
|
||||
**Core elements:**
|
||||
- `\documentclass{beamer}` — Presentation document class
|
||||
- Preamble — Theme, colors, fonts, global settings
|
||||
- `\begin{frame}...\end{frame}` — Each frame = one slide
|
||||
|
||||
---
|
||||
|
||||
## 3. Theme System (Complete Reference)
|
||||
|
||||
Beamer themes consist of five independent layers that can be freely combined:
|
||||
|
||||
### 3.1 Presentation Themes (control overall layout)
|
||||
|
||||
| Theme | Features | Suitable For |
|
||||
|---|---|---|
|
||||
| `default` | Minimal, no decoration | Formal academic, minimalist |
|
||||
| `Madrid` | Bottom info bar + section navigation | University courses, academic talks |
|
||||
| `Berlin` | Top mini-frames + side color blocks | Long technical presentations |
|
||||
| `Warsaw` | Top circular navigation + gradient title | Structured content |
|
||||
| `CambridgeUS` | Two-tone minimalist | Math-heavy presentations |
|
||||
| `Boadilla` | Clean footer | Business, concise style |
|
||||
| `Singapore` | Top dot navigation | Modern feel, multi-section |
|
||||
| `AnnArbor` | Yellow-blue dual tone | Michigan style |
|
||||
| `Antibes` | Blue sidebar tree | Multi-subsection structure |
|
||||
| `Bergen` | Blue title bar | Formal academic |
|
||||
| `Copenhagen` | Top bar + navigation | Classic blue scheme |
|
||||
| `Darmstadt` | Top progress dots | Multi-section structure |
|
||||
| `Dresden` | Top mini-frames | Similar to Berlin |
|
||||
| `Frankfurt` | Top dots | Clear section structure |
|
||||
| `Goettingen` | Right sidebar | Navigation-focused |
|
||||
| `Luebeck` | Top blue bar | Clean modern |
|
||||
| `Malmoe` | Minimal title | Content-first |
|
||||
| `Montpellier` | Top tree navigation | Hierarchical content |
|
||||
| `Pittsburgh` | No color blocks, minimal | White scheme |
|
||||
| `Rochester` | Dark title | Dark scheme |
|
||||
| `Szeged` | Blue title bar | Hungarian style |
|
||||
|
||||
```latex
|
||||
\usetheme{Madrid}
|
||||
```
|
||||
|
||||
### 3.2 Color Themes
|
||||
|
||||
| Color Theme | Dominant Color |
|
||||
|---|---|
|
||||
| `default` | Dark blue |
|
||||
| `albatross` | Yellow tones |
|
||||
| `beaver` | Dark red / maroon |
|
||||
| `beetle` | Gray-blue |
|
||||
| `crane` | Orange-yellow |
|
||||
| `dolphin` | Blue-white |
|
||||
| `dove` | Gray-white (near monochrome) |
|
||||
| `fly` | Gray tones |
|
||||
| `lily` | Red-blue |
|
||||
| `orchid` | Purple tones |
|
||||
| `rose` | Pink |
|
||||
| `seagull` | Gray |
|
||||
| `seahorse` | Blue-purple |
|
||||
| `whale` | Deep sea blue |
|
||||
| `wolverine` | Yellow-blue contrast |
|
||||
|
||||
```latex
|
||||
\usecolortheme{dolphin}
|
||||
```
|
||||
|
||||
### 3.3 Font Themes
|
||||
|
||||
```latex
|
||||
\usefonttheme{default} % Sans-serif (Beamer default)
|
||||
\usefonttheme{serif} % Serif font (academic feel)
|
||||
\usefonttheme{structurebold} % Bold structural elements
|
||||
\usefonttheme{structureitalic} % Italic structural elements
|
||||
\usefonttheme{structuresmallcapsserif} % Small caps serif
|
||||
\usefonttheme{professionalfonts} % Keep math fonts unchanged
|
||||
```
|
||||
|
||||
### 3.4 Inner Themes (control list, block, and title styles)
|
||||
|
||||
```latex
|
||||
\useinnertheme{default} % Triangle bullet points
|
||||
\useinnertheme{circles} % Circle bullet points
|
||||
\useinnertheme{rectangles} % Square bullet points
|
||||
\useinnertheme{rounded} % Rounded blocks
|
||||
\useinnertheme{inmargin} % Margin numbers
|
||||
```
|
||||
|
||||
### 3.5 Outer Themes (control header, footer, and sidebar)
|
||||
|
||||
```latex
|
||||
\useoutertheme{default} % No decoration
|
||||
\useoutertheme{infolines} % Bottom three-column info
|
||||
\useoutertheme{miniframes} % Top mini-frame navigation
|
||||
\useoutertheme{shadow} % Shadow title
|
||||
\useoutertheme{sidebar} % Sidebar
|
||||
\useoutertheme{smoothbars} % Gradient top bar
|
||||
\useoutertheme{smoothtree} % Gradient tree
|
||||
\useoutertheme{split} % Top-bottom split
|
||||
\useoutertheme{tree} % Tree navigation
|
||||
```
|
||||
|
||||
### 3.6 Custom Colors
|
||||
|
||||
```latex
|
||||
\definecolor{myblue}{HTML}{2B5EA7}
|
||||
\definecolor{mygray}{HTML}{F0F0F0}
|
||||
|
||||
\setbeamercolor{frametitle}{bg=myblue, fg=white}
|
||||
\setbeamercolor{structure}{fg=myblue}
|
||||
\setbeamercolor{block title}{bg=myblue!85, fg=white}
|
||||
\setbeamercolor{block body}{bg=myblue!8}
|
||||
\setbeamercolor{alerted text}{fg=red!70!black}
|
||||
\setbeamercolor{title}{fg=white}
|
||||
\setbeamercolor{subtitle}{fg=white!80}
|
||||
```
|
||||
|
||||
### 3.7 Common Template Customizations
|
||||
|
||||
```latex
|
||||
% Remove navigation symbols (almost always needed)
|
||||
\setbeamertemplate{navigation symbols}{}
|
||||
|
||||
% Custom footer (frame number)
|
||||
\setbeamertemplate{footline}{%
|
||||
\hfill\insertframenumber/\inserttotalframenumber\hspace{1em}\vspace{0.5em}
|
||||
}
|
||||
|
||||
% Custom bullet points
|
||||
\setbeamertemplate{itemize item}{\textbullet}
|
||||
\setbeamertemplate{itemize subitem}{--}
|
||||
|
||||
% Logo (bottom-right corner)
|
||||
\logo{\includegraphics[height=0.7cm]{logo.png}}
|
||||
|
||||
% Rounded blocks
|
||||
\setbeamertemplate{blocks}[rounded][shadow=true]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Overlays & Stepwise Reveal
|
||||
|
||||
Tectonic fully supports all overlay syntax — rendered as separate pages in the PDF.
|
||||
|
||||
### 4.1 Basic Overlay Specifications
|
||||
|
||||
```latex
|
||||
\item<1-> % Show from layer 1, persist
|
||||
\item<2-> % Show from layer 2
|
||||
\item<1-3> % Show on layers 1 to 3 only
|
||||
\item<2> % Show on layer 2 only
|
||||
\item<-3> % Show before layer 3
|
||||
```
|
||||
|
||||
### 4.2 \pause — Simplest Stepwise Reveal
|
||||
|
||||
```latex
|
||||
\begin{frame}{Research Workflow}
|
||||
Data collection phase
|
||||
\pause
|
||||
Feature engineering phase
|
||||
\pause
|
||||
Model training phase
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 4.3 List Stepwise Reveal
|
||||
|
||||
```latex
|
||||
\begin{frame}{Research Contributions}
|
||||
\begin{itemize}
|
||||
\item<1-> Propose a novel loss function
|
||||
\item<2-> Prove theoretical convergence
|
||||
\item<3-> Outperform SOTA on five benchmarks
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 4.4 \only vs \uncover vs \visible
|
||||
|
||||
```latex
|
||||
% \only: no space reserved (causes layout jump)
|
||||
\only<1>{Step one explanation}
|
||||
\only<2>{Step two explanation}
|
||||
|
||||
% \uncover: reserves space but transparent (recommended, stable layout)
|
||||
\uncover<2->{Follow-up steps explanation}
|
||||
|
||||
% \visible: reserves space but not rendered
|
||||
\visible<3->{Step three}
|
||||
```
|
||||
|
||||
### 4.5 \alert — Highlight Specific Layers
|
||||
|
||||
```latex
|
||||
\begin{frame}{Key Findings}
|
||||
\begin{itemize}
|
||||
\item \alert<1>{Accuracy improved by 13\%}
|
||||
\item \alert<2>{Inference speed improved 2.4x}
|
||||
\item \alert<3>{Memory reduced by 40\%}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 4.6 \textcolor & Conditional Content
|
||||
|
||||
```latex
|
||||
\begin{frame}{Comparison}
|
||||
Baseline method: \textcolor{red}{82\%}\\
|
||||
\only<2->{Our method: \textcolor{green!60!black}{\textbf{93\%}}}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 4.7 Block Overlays
|
||||
|
||||
```latex
|
||||
\begin{frame}{Analysis}
|
||||
\begin{block}<1-2>{Problem Definition}
|
||||
Formal description ...
|
||||
\end{block}
|
||||
\begin{block}<2->{Solution}
|
||||
Core approach ...
|
||||
\end{block}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Content Layout Templates
|
||||
|
||||
### 5.1 Block Series (Three Styles)
|
||||
|
||||
```latex
|
||||
\begin{frame}{Core Findings}
|
||||
\begin{block}{Main Conclusion}
|
||||
The new method outperforms baselines in both accuracy and speed.
|
||||
\end{block}
|
||||
|
||||
\begin{alertblock}{Caveats}
|
||||
Results are validated on specific datasets; generalization needs further study.
|
||||
\end{alertblock}
|
||||
|
||||
\begin{exampleblock}{Example}
|
||||
Achieved 99.1\% accuracy on the MNIST dataset.
|
||||
\end{exampleblock}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 5.2 Column Layout
|
||||
|
||||
```latex
|
||||
\begin{frame}{Experimental Comparison}
|
||||
\begin{columns}[T] % [T] top-aligned
|
||||
\column{0.48\textwidth}
|
||||
\begin{block}{Baseline Method}
|
||||
Accuracy: 82\% \\
|
||||
Time: 3.2 hours
|
||||
\end{block}
|
||||
|
||||
\column{0.48\textwidth}
|
||||
\begin{block}{Our Method}
|
||||
Accuracy: \textbf{91\%} \\
|
||||
Time: \textbf{1.7 hours}
|
||||
\end{block}
|
||||
\end{columns}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
Column alignment options: `[T]` top-aligned · `[c]` centered · `[b]` bottom-aligned
|
||||
|
||||
### 5.3 Math Formula Frame
|
||||
|
||||
```latex
|
||||
\begin{frame}{Loss Function}
|
||||
\begin{equation*}
|
||||
\mathcal{L} = -\sum_{i=1}^{N} y_i \log \hat{y}_i + \lambda \|\theta\|_2^2
|
||||
\end{equation*}
|
||||
\begin{itemize}
|
||||
\item $y_i$: Ground truth label
|
||||
\item $\hat{y}_i$: Predicted probability
|
||||
\item $\lambda$: Regularization coefficient
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 5.4 Theorem Environment
|
||||
|
||||
```latex
|
||||
\begin{frame}{Convergence Theorem}
|
||||
\begin{theorem}[Convergence Rate]
|
||||
Under Lipschitz conditions, gradient descent converges at $O(1/\sqrt{T})$.
|
||||
\end{theorem}
|
||||
|
||||
\begin{proof}
|
||||
Follows from Lipschitz continuity and step size $\eta = 1/L$.\qed
|
||||
\end{proof}
|
||||
|
||||
\begin{corollary}
|
||||
The stochastic gradient variant converges in expectation at $O(1/\sqrt{T})$.
|
||||
\end{corollary}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 5.5 Table Frame
|
||||
|
||||
```latex
|
||||
\begin{frame}{Performance Comparison}
|
||||
\centering
|
||||
\begin{tabular}{lcc}
|
||||
\toprule
|
||||
Method & Accuracy & Time(s) \\
|
||||
\midrule
|
||||
SVM & 0.85 & 120 \\
|
||||
Random Forest & 0.89 & 65 \\
|
||||
\textbf{Ours} & \textbf{0.93} & \textbf{42} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 5.6 TikZ Flowchart
|
||||
|
||||
TikZ is fully supported in Tectonic — no pre-rendering needed:
|
||||
|
||||
```latex
|
||||
\begin{frame}{Algorithm Pipeline}
|
||||
\centering
|
||||
\begin{tikzpicture}[
|
||||
node distance=2cm,
|
||||
box/.style={rectangle, rounded corners=4pt, draw=myblue, thick,
|
||||
fill=myblue!10, minimum width=2.2cm, minimum height=0.9cm, font=\small},
|
||||
arr/.style={-Stealth, thick, myblue}
|
||||
]
|
||||
\node[box] (A) {Input Data};
|
||||
\node[box, right of=A] (B) {Feature Extraction};
|
||||
\node[box, right of=B] (C) {Model Inference};
|
||||
\node[box, right of=C] (D) {Output Results};
|
||||
\draw[arr] (A) -- (B);
|
||||
\draw[arr] (B) -- (C);
|
||||
\draw[arr] (C) -- (D);
|
||||
\end{tikzpicture}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 5.7 Code Display Frame
|
||||
|
||||
```latex
|
||||
\begin{frame}[fragile]{Training Loop} % [fragile] is required
|
||||
\begin{verbatim}
|
||||
for epoch in range(epochs):
|
||||
for batch in dataloader:
|
||||
optimizer.zero_grad()
|
||||
loss = model(batch)
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
\end{verbatim}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
Or use `listings` for syntax highlighting (more polished):
|
||||
|
||||
```latex
|
||||
\usepackage{listings}
|
||||
\lstset{
|
||||
basicstyle=\ttfamily\small,
|
||||
keywordstyle=\color{blue}\bfseries,
|
||||
commentstyle=\color{gray},
|
||||
backgroundcolor=\color{gray!5},
|
||||
numbers=left, numberstyle=\tiny\color{gray},
|
||||
frame=single, framerule=0.5pt
|
||||
}
|
||||
|
||||
\begin{frame}[fragile]{Python Code}
|
||||
\begin{lstlisting}[language=Python]
|
||||
def train(model, dataloader):
|
||||
for batch in dataloader:
|
||||
loss = model(batch)
|
||||
loss.backward()
|
||||
\end{lstlisting}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 5.8 Image Frame
|
||||
|
||||
```latex
|
||||
\begin{frame}{System Architecture}
|
||||
\centering
|
||||
\includegraphics[width=0.85\textwidth]{figures/architecture.png}
|
||||
\captionof{figure}{End-to-end training pipeline}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 5.9 Custom Checklist Frame
|
||||
|
||||
```latex
|
||||
\begin{frame}{Summary of Contributions}
|
||||
\begin{itemize}
|
||||
\item[\checkmark] New method proposed: ...
|
||||
\item[\checkmark] Theoretical proof: ...
|
||||
\item[\checkmark] Experimental validation: ...
|
||||
\item[$\square$] Future work: ...
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Advanced Features
|
||||
|
||||
### 6.1 Progress Bar (Manual Implementation)
|
||||
|
||||
```latex
|
||||
% Define in preamble
|
||||
\definecolor{progressbar}{HTML}{2B5EA7}
|
||||
\setbeamertemplate{footline}{
|
||||
\begin{beamercolorbox}[wd=\paperwidth,ht=2pt]{progressbar}
|
||||
\rule{\dimexpr\paperwidth*\insertframenumber/\inserttotalframenumber}{2pt}
|
||||
\end{beamercolorbox}
|
||||
\vspace{2pt}
|
||||
\hfill\tiny\insertframenumber/\inserttotalframenumber\hspace{1em}\vspace{3pt}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 Section Title Pages (Automatic)
|
||||
|
||||
```latex
|
||||
% Add in preamble — auto-inserts a section title page before each \section
|
||||
\AtBeginSection[]{
|
||||
\begin{frame}
|
||||
\vfill
|
||||
\centering
|
||||
\begin{beamercolorbox}[sep=8pt,center,shadow=true,rounded=true]{title}
|
||||
\usebeamerfont{title}\insertsectionhead\par
|
||||
\end{beamercolorbox}
|
||||
\vfill
|
||||
\end{frame}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 Handout Mode
|
||||
|
||||
```latex
|
||||
% Generate overlay-free handout version (only final state of each frame)
|
||||
\documentclass[handout, aspectratio=169]{beamer}
|
||||
```
|
||||
|
||||
Combine with `pgfpages` to compress multiple frames onto one page:
|
||||
|
||||
```latex
|
||||
\usepackage{pgfpages}
|
||||
\pgfpagesuselayout{4 on 1}[a4paper, border shrink=5mm]
|
||||
```
|
||||
|
||||
### 6.4 Frame Reuse (\againframe)
|
||||
|
||||
```latex
|
||||
\begin{frame}[label=keyresult]{Key Result}
|
||||
Accuracy improved by 13\%.
|
||||
\end{frame}
|
||||
|
||||
% Show again at any later point
|
||||
\againframe{keyresult}
|
||||
```
|
||||
|
||||
### 6.5 Appendix (Excluded from Total Page Count)
|
||||
|
||||
```latex
|
||||
\appendix
|
||||
|
||||
\begin{frame}{Appendix: Detailed Derivation}
|
||||
% Backup slides for Q&A
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
### 6.6 Speaker Notes
|
||||
|
||||
```latex
|
||||
\begin{frame}{Main Conclusions}
|
||||
\begin{itemize}
|
||||
\item Conclusion one
|
||||
\item Conclusion two
|
||||
\end{itemize}
|
||||
\note{
|
||||
Emphasize the data supporting conclusion one.\\
|
||||
Anticipate questions about dataset size.
|
||||
}
|
||||
\end{frame}
|
||||
```
|
||||
|
||||
Output PDF with notes: add in preamble:
|
||||
```latex
|
||||
\setbeameroption{show notes on second screen=right}
|
||||
```
|
||||
|
||||
### 6.7 Widescreen Aspect Ratios
|
||||
|
||||
```latex
|
||||
\documentclass[aspectratio=169]{beamer} % 16:9 (recommended)
|
||||
\documentclass[aspectratio=1610]{beamer} % 16:10
|
||||
\documentclass[aspectratio=43]{beamer} % 4:3 (traditional)
|
||||
\documentclass[aspectratio=141]{beamer} % 1.41:1 (A4)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Complete Template (Academic Presentation, 16:9, with CJK Support)
|
||||
|
||||
```latex
|
||||
\documentclass[aspectratio=169, 11pt]{beamer}
|
||||
\usepackage[fontset=fandol]{ctex}
|
||||
\usepackage{amsmath, amssymb, mathtools}
|
||||
\usepackage{booktabs}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{tikz}
|
||||
\usetikzlibrary{arrows.meta, positioning, shapes.geometric}
|
||||
|
||||
% -- Theme ---------------------------------------------------------------
|
||||
\usetheme{Madrid}
|
||||
\usecolortheme{dolphin}
|
||||
\usefonttheme{professionalfonts}
|
||||
\setbeamertemplate{navigation symbols}{}
|
||||
|
||||
% -- Colors --------------------------------------------------------------
|
||||
\definecolor{myblue}{HTML}{2B5EA7}
|
||||
\setbeamercolor{frametitle}{bg=myblue, fg=white}
|
||||
\setbeamercolor{structure}{fg=myblue}
|
||||
\setbeamercolor{block title}{bg=myblue!85, fg=white}
|
||||
\setbeamercolor{block body}{bg=myblue!8}
|
||||
|
||||
% -- Auto section title page ---------------------------------------------
|
||||
\AtBeginSection[]{
|
||||
\begin{frame}
|
||||
\vfill\centering
|
||||
\begin{beamercolorbox}[sep=8pt,center,rounded=true]{title}
|
||||
\usebeamerfont{title}\insertsectionhead\par
|
||||
\end{beamercolorbox}
|
||||
\vfill
|
||||
\end{frame}
|
||||
}
|
||||
|
||||
% -- Metadata ------------------------------------------------------------
|
||||
\title{Paper Title}
|
||||
\subtitle{Subtitle}
|
||||
\author{Author Name}
|
||||
\institute{Affiliation}
|
||||
\date{\today}
|
||||
|
||||
% ========================================================================
|
||||
\begin{document}
|
||||
|
||||
\begin{frame}
|
||||
\titlepage
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Table of Contents}
|
||||
\tableofcontents
|
||||
\end{frame}
|
||||
|
||||
\section{Introduction}
|
||||
|
||||
\begin{frame}{Research Background}
|
||||
\begin{itemize}
|
||||
\item<1-> Importance of the problem
|
||||
\item<2-> Limitations of existing methods
|
||||
\item<3-> Contributions of this work
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\section{Method}
|
||||
|
||||
\begin{frame}{Core Formula}
|
||||
\begin{equation*}
|
||||
\mathcal{L} = -\sum_{i=1}^{N} y_i \log \hat{y}_i + \lambda \|\theta\|_2^2
|
||||
\end{equation*}
|
||||
\begin{itemize}
|
||||
\item $y_i$: Ground truth label
|
||||
\item $\hat{y}_i$: Predicted probability
|
||||
\item $\lambda$: Regularization coefficient
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Method Comparison}
|
||||
\begin{columns}[T]
|
||||
\column{0.48\textwidth}
|
||||
\begin{block}{Baseline Method}
|
||||
Accuracy: 82\% \\
|
||||
Time: 3.2 hours
|
||||
\end{block}
|
||||
\column{0.48\textwidth}
|
||||
\begin{block}{Our Method}
|
||||
Accuracy: \textbf{91\%} \\
|
||||
Time: \textbf{1.7 hours}
|
||||
\end{block}
|
||||
\end{columns}
|
||||
\end{frame}
|
||||
|
||||
\section{Experiments}
|
||||
|
||||
\begin{frame}{Performance Comparison}
|
||||
\centering
|
||||
\begin{tabular}{lcc}
|
||||
\toprule
|
||||
Method & Accuracy & Time(s) \\
|
||||
\midrule
|
||||
SVM & 0.85 & 120 \\
|
||||
Random Forest & 0.89 & 65 \\
|
||||
\textbf{Ours} & \textbf{0.93} & \textbf{42} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{frame}
|
||||
|
||||
\section{Conclusion}
|
||||
|
||||
\begin{frame}{Summary}
|
||||
\begin{itemize}
|
||||
\item[\checkmark] Contribution 1: Proposed new method
|
||||
\item[\checkmark] Contribution 2: Theoretical proof
|
||||
\item[\checkmark] Contribution 3: Experimental validation
|
||||
\end{itemize}
|
||||
\begin{block}{Future Work}
|
||||
Extend to larger-scale datasets and explore cross-domain generalization.
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\centering\Large Thank You!\\[0.8em]
|
||||
\normalsize Questions Welcome
|
||||
\end{frame}
|
||||
|
||||
\end{document}
|
||||
```
|
||||
|
||||
Compile:
|
||||
```bash
|
||||
python3 scripts/pdf.py convert.latex main.tex --runs 2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Common Issues & Fixes
|
||||
|
||||
| Issue | Cause | Fix |
|
||||
|---|---|---|
|
||||
| CJK characters display as boxes | Missing CJK font package | Add `\usepackage[fontset=fandol]{ctex}` |
|
||||
| `??` appears in ToC or references | Only compiled once | Add `--runs 2` |
|
||||
| `[fragile]` missing error | verbatim/lstlisting frame | Add `[fragile]` after `\begin{frame}` |
|
||||
| Overlay not working | Forgot `\pause` or `<n->` in frame | Check overlay specification syntax |
|
||||
| TikZ compilation failure | Missing tikzlibrary | Add `\usetikzlibrary{...}` |
|
||||
| Math font distortion | Missing professionalfonts | Add `\usefonttheme{professionalfonts}` |
|
||||
| Frame exceeds one page (content overflow) | Too much content | Add `[allowframebreaks]` or split frame |
|
||||
|
||||
---
|
||||
|
||||
## 9. Dependencies
|
||||
|
||||
| Tool | Purpose |
|
||||
|---|---|
|
||||
| `scripts/tectonic` | LaTeX compilation engine (local binary) |
|
||||
| `scripts/pdf.py convert.latex` | Tectonic wrapper with log filtering + PDF stats |
|
||||
342
skills/ppt/references/latex.md
Executable file
342
skills/ppt/references/latex.md
Executable file
@@ -0,0 +1,342 @@
|
||||
# Route 3: Academic & Scientific PDF via LaTeX
|
||||
|
||||
Produce publication-grade PDFs from `.tex` source files compiled with Tectonic. Suited for academic papers, theses, mathematical manuscripts, IEEE/ACM-format submissions, and any document where the user explicitly requests LaTeX.
|
||||
|
||||
**Guiding principle**: when someone asks for "a LaTeX PDF," they expect a polished, professional result — not a bare-minimum compilation.
|
||||
|
||||
---
|
||||
|
||||
## Environment Preparation
|
||||
|
||||
|
||||
The binary of Tectonic lands at `scripts/tectonic`.
|
||||
|
||||
### Compilation — Always Use the Wrapper Script
|
||||
|
||||
All compilations **must** go through `scripts/pdf.py convert.latex`. It handles:
|
||||
- Stripping noisy package-download logs
|
||||
- Filtering progress chatter
|
||||
- Surfacing genuine errors and warnings
|
||||
- Reporting PDF statistics (file size, page count, word estimate, image tally)
|
||||
|
||||
**Do not invoke Tectonic directly.**
|
||||
|
||||
```bash
|
||||
# One-pass build
|
||||
python3 scripts/pdf.py convert.latex main.tex
|
||||
|
||||
# Two passes (resolves cross-references)
|
||||
python3 scripts/pdf.py convert.latex main.tex --runs 2
|
||||
|
||||
# Verbose mode (retains full log output)
|
||||
python3 scripts/pdf.py convert.latex main.tex --keep-logs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pre-Writing Planning
|
||||
|
||||
Before touching `.tex` code, determine the document's category and let that shape your approach.
|
||||
|
||||
### Recognising the Document Type
|
||||
|
||||
| Type | Typical outputs | Key concern |
|
||||
|------|----------------|-------------|
|
||||
| **Scholarly** | Journal articles, conference proceedings, regulatory specs | Rigorous adherence to academic conventions; bibliography accuracy |
|
||||
| **Utilitarian** | Technical reports, reference manuals, product specs | Pack maximum information while preserving scannability |
|
||||
| **Persuasive** | Funding proposals, pitch documents, project roadmaps | Clean professionalism throughout, with one or two visual high-points (title page, KPI dashboards) |
|
||||
| **Expressive** | Design portfolios, brand guidebooks, showcases | Bold typographic and chromatic choices; deliberate rule-breaking that amplifies impact |
|
||||
|
||||
### Fallback Aesthetic (No Style Specified)
|
||||
|
||||
When the user gives no visual direction, apply a **measured, high-craft** system:
|
||||
|
||||
1. **Contrast** — clear figure-ground separation; headings visually distinct from running text
|
||||
2. **Hierarchy** — establish reading order through deliberate variation in size, weight, and hue
|
||||
3. **White space** — ample margins and leading to let the page breathe
|
||||
4. **Coherence** — one typeface family, one accent colour, one spacing rhythm
|
||||
|
||||
#### Enrichment Elements (Add Proactively When Appropriate)
|
||||
|
||||
- **Decorative**: shaded callout boxes, sidebars, comparison panels → `tcolorbox`
|
||||
- **Scholarly**: theorem / definition / proof environments → `amsthm` + `tcolorbox`; process diagrams → TikZ
|
||||
- **Page furniture**: running headers and footers → `fancyhdr`; chapter openers → `titlesec`
|
||||
|
||||
Introduce these components on your own initiative whenever the content benefits — don't wait to be told.
|
||||
|
||||
---
|
||||
|
||||
## Mandatory Rules
|
||||
|
||||
### Rule 1 — Every Build Diagnostic Demands Attention
|
||||
|
||||
The wrapper classifies compiler output into three tiers:
|
||||
|
||||
| Tier | Impact | Required response |
|
||||
|------|--------|-------------------|
|
||||
| **Errors** | Build aborts | Resolve before anything else |
|
||||
| **Layout defects** | Overfull / underfull boxes, unavailable font shapes, missing glyphs | Repair prior to delivery |
|
||||
| **Advisories** | Remaining warnings | Assess individually; fix whenever feasible |
|
||||
|
||||
**Never acceptable**: shrugging off warnings with "they don't affect the final PDF." Every diagnostic merits investigation.
|
||||
|
||||
### Rule 2 — Modular Files for Larger Works
|
||||
|
||||
A single generation turn can comfortably handle roughly **500 lines** of TeX.
|
||||
|
||||
**When to split**:
|
||||
- Anticipated output exceeds 5 pages, **or**
|
||||
- Three or more heavyweight elements are present (wide tables, block equations, TikZ graphics)
|
||||
|
||||
Stitch modules together with `\input{chapter1}`, `\input{chapter2}`, etc.
|
||||
|
||||
### Rule 3 — Foundation Preamble
|
||||
|
||||
```latex
|
||||
\documentclass{article}
|
||||
|
||||
% Essentials
|
||||
\usepackage{graphicx}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{geometry}
|
||||
\usepackage{amsmath} % Load before hyperref
|
||||
|
||||
% hyperref — ALWAYS last among content packages
|
||||
\usepackage[
|
||||
colorlinks=true,
|
||||
linkcolor=blue,
|
||||
citecolor=darkgray,
|
||||
urlcolor=blue,
|
||||
bookmarks=true,
|
||||
bookmarksnumbered=true,
|
||||
unicode=true
|
||||
]{hyperref}
|
||||
|
||||
% Page dimensions
|
||||
\geometry{a4paper, top=2.5cm, bottom=2.5cm, left=3cm, right=2.5cm}
|
||||
% CV variant: \geometry{a4paper, margin=1.5cm}
|
||||
|
||||
% Superscript citation numbers (scholarly convention)
|
||||
\usepackage[numbers,super,sort&compress]{natbib}
|
||||
\bibliographystyle{unsrtnat}
|
||||
|
||||
% Commonly needed extras
|
||||
\usepackage{tcolorbox}
|
||||
\usepackage{colortbl}
|
||||
\usepackage{booktabs}
|
||||
\usepackage{enumitem}
|
||||
```
|
||||
|
||||
**hyperref positioning**: it must load after virtually every other package to avoid option clashes.
|
||||
|
||||
### Rule 4 — TeX Source Hygiene
|
||||
|
||||
**Prohibited patterns**:
|
||||
- Emoji glyphs (no native LaTeX engine supports them)
|
||||
- Markdown `*asterisk*` formatting (generates compile-time errors)
|
||||
|
||||
**Use instead**:
|
||||
```latex
|
||||
\textbf{bold text}
|
||||
\emph{emphasised text}
|
||||
```
|
||||
|
||||
These are frequent model-generation slips — catch them proactively.
|
||||
|
||||
### Rule 5 — Multi-Language & Font Handling
|
||||
|
||||
- `babel` and `polyglossia` are incompatible — load only one
|
||||
- When using `polyglossia`, ensure `amsmath` appears earlier in the preamble
|
||||
- Tectonic downloads standard LaTeX typefaces automatically (Latin Modern, etc.)
|
||||
- To reference system-installed fonts via `\setmainfont{}`, first probe with `fc-list :lang=ar`
|
||||
- Broadly available choices: DejaVu, Noto typeface families
|
||||
|
||||
### Rule 6 — Clickable Navigation Is Non-Negotiable
|
||||
|
||||
Interactive navigation is a baseline professional expectation.
|
||||
|
||||
#### 6.1 Table of Contents
|
||||
```latex
|
||||
\tableofcontents % Entries are auto-linked courtesy of hyperref
|
||||
\listoffigures
|
||||
\listoftables
|
||||
```
|
||||
|
||||
#### 6.2 Internal Cross-References
|
||||
|
||||
**Attach labels** right after each numbered element:
|
||||
```latex
|
||||
\section{Background}\label{sec:bg}
|
||||
|
||||
\begin{figure}[htbp]
|
||||
\includegraphics{...}
|
||||
\caption{Overview diagram}\label{fig:overview}
|
||||
\end{figure}
|
||||
|
||||
\begin{table}[htbp]
|
||||
\caption{Benchmark results}\label{tab:bench}
|
||||
...
|
||||
\end{table}
|
||||
|
||||
\begin{equation}\label{eq:energy}
|
||||
E = mc^2
|
||||
\end{equation}
|
||||
```
|
||||
|
||||
**Cite these labels** (each produces a live hyperlink):
|
||||
```latex
|
||||
As noted in Section~\ref{sec:bg}...
|
||||
Figure~\ref{fig:overview} illustrates...
|
||||
Table~\ref{tab:bench} summarises...
|
||||
Equation~\eqref{eq:energy} yields... % \eqref auto-wraps in parentheses
|
||||
See page~\pageref{sec:bg}...
|
||||
```
|
||||
|
||||
**Good habits**:
|
||||
- Place a non-breaking space `~` before `\ref` to avoid orphaned line breaks
|
||||
- Prefer `\eqref{}` for equations (auto-wraps the number in parentheses)
|
||||
- Adopt a consistent label-prefix convention: `sec:`, `fig:`, `tab:`, `eq:`, `lst:`
|
||||
|
||||
#### 6.3 Bibliography
|
||||
|
||||
**Superscript numerals (preferred academic style)**:
|
||||
```latex
|
||||
\usepackage[numbers,super,sort&compress]{natbib}
|
||||
\bibliographystyle{unsrtnat}
|
||||
|
||||
Prior work\cite{smith2023} shows... % → shows^[1]
|
||||
Several studies\cite{a,b,c} agree... % → agree^[1–3]
|
||||
|
||||
\bibliography{refs}
|
||||
```
|
||||
|
||||
**Numeric bracket alternative**:
|
||||
```latex
|
||||
\usepackage[numbers]{natbib}
|
||||
\bibliographystyle{plainnat}
|
||||
|
||||
\cite{smith2023} % [1]
|
||||
\citep{smith2023} % (Smith, 2023)
|
||||
\citet{smith2023} % Smith (2023)
|
||||
```
|
||||
|
||||
**biblatex pathway**:
|
||||
```latex
|
||||
\usepackage[backend=biber,style=numeric-comp]{biblatex}
|
||||
\addbibresource{refs.bib}
|
||||
|
||||
Per~\cite{smith2023}...
|
||||
\printbibliography
|
||||
```
|
||||
|
||||
#### 6.4 External Links
|
||||
```latex
|
||||
\url{https://example.com}
|
||||
\href{https://example.com}{Visible label}
|
||||
\href{mailto:a@b.com}{a@b.com}
|
||||
```
|
||||
|
||||
#### 6.5 PDF Metadata & Outline
|
||||
```latex
|
||||
\hypersetup{
|
||||
pdftitle={Document Title},
|
||||
pdfauthor={Author Name},
|
||||
pdfsubject={Topic},
|
||||
pdfkeywords={keyword1, keyword2}
|
||||
}
|
||||
```
|
||||
Bookmark trees are auto-generated from `\section` / `\chapter` hierarchy.
|
||||
|
||||
#### 6.6 Why Multiple Passes Matter
|
||||
|
||||
Label resolution requires at least two compilation passes:
|
||||
```bash
|
||||
# Resolve section / figure / table labels
|
||||
python3 scripts/pdf.py convert.latex main.tex --runs 2
|
||||
|
||||
# Also resolves bibliography back-references
|
||||
python3 scripts/pdf.py convert.latex main.tex --runs 3
|
||||
```
|
||||
|
||||
If `??` placeholders persist after two passes, verify that every `\label` string has an exact `\ref` match.
|
||||
|
||||
#### 6.7 Navigation Troubleshooting
|
||||
|
||||
| Observation | Root cause | Resolution |
|
||||
|-------------|-----------|------------|
|
||||
| `??` in place of numbers | Only a single pass was run | Recompile with `--runs 2` |
|
||||
| All links render in black | hyperref colour options omitted | Enable `colorlinks=true` |
|
||||
| TOC items are not clickable | hyperref package missing | Load the package |
|
||||
| `[?]` beside citations | `.bib` path incorrect or biber step skipped | Confirm path; rebuild |
|
||||
| Bookmark pane empty | `bookmarks` option set to false | Switch to `bookmarks=true` |
|
||||
|
||||
---
|
||||
|
||||
## Package Catalogue
|
||||
|
||||
### Foundational
|
||||
- `hyperref` (Rule 3)
|
||||
- `geometry` (Rule 3)
|
||||
- `listings` — `\lstset{basicstyle=\ttfamily\small, numbers=left, backgroundcolor=\color{gray!5}}`
|
||||
- `enumitem` — `\setlist[itemize]{itemsep=0.3em, leftmargin=1.5em}`
|
||||
|
||||
### Tabular
|
||||
`booktabs` · `longtable` · `multirow` · `array` · `colortbl`
|
||||
|
||||
### Visual & Charting
|
||||
`tikz` · `pgfplots` · `float` · `wrapfig` · `subfig` / `subcaption`
|
||||
|
||||
### International & Typography
|
||||
`fontspec` (XeLaTeX / LuaLaTeX) · `ctex`
|
||||
|
||||
### Mathematical
|
||||
`amsmath` · `amssymb` · `amsthm` · `natbib` · `biblatex` · `siunitx`
|
||||
|
||||
### Algorithmic & Domain-Specific
|
||||
`algorithm` + `algpseudocode` · `chemfig`
|
||||
|
||||
### Page Design
|
||||
`tcolorbox` · `fancyhdr` · `titlesec` · `tocloft` · `multicol` · `setspace` · `microtype` · `parskip` · `adjustbox` · `marginnote`
|
||||
|
||||
### Code Listings
|
||||
`listings` · `minted` (depends on Pygments)
|
||||
|
||||
---
|
||||
|
||||
## Scripts & Backends
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
| `pdf.py convert.latex` | Tectonic wrapper — log sanitisation, error highlighting, PDF metrics |
|
||||
|
||||
| Engine | Notes |
|
||||
|--------|-------|
|
||||
| Tectonic | Stand-alone LaTeX engine; packages are fetched transparently on demand |
|
||||
|
||||
---
|
||||
|
||||
## Operational Notes
|
||||
|
||||
### CJK Without Manual Font Setup
|
||||
Tectonic resolves CJK font bundles on the fly — zero manual installation:
|
||||
|
||||
```latex
|
||||
\usepackage{ctex} % Tectonic pulls the font files automatically
|
||||
```
|
||||
|
||||
### Cold-Start Latency
|
||||
The very first compilation of a new document triggers package downloads:
|
||||
- Initial build: 1–5 min (depends on network speed)
|
||||
- Repeat builds with warm cache: 10–30 s
|
||||
|
||||
### Working Without Internet
|
||||
Previously fetched packages are stored under `~/.cache/Tectonic/`. When offline, only cached packages are available; attempting to use a new one will fail.
|
||||
|
||||
### Tectonic vs a Full TeX Live Installation
|
||||
|
||||
| Dimension | Tectonic | Traditional pdflatex |
|
||||
|-----------|----------|---------------------|
|
||||
| Package acquisition | On-demand, transparent | Manual via `tlmgr` |
|
||||
| Multi-pass compilation | Handled by the engine | Explicit re-invocations required |
|
||||
| Reference resolution | Automatic | Requires bibtex/biber cycles |
|
||||
| Disk footprint | Single binary | Full TeX Live ≈ 4 GB |
|
||||
73
skills/ppt/references/paper-navbar.tex
Executable file
73
skills/ppt/references/paper-navbar.tex
Executable file
@@ -0,0 +1,73 @@
|
||||
% ========================================================================
|
||||
% Paper Presentation Navigation for Beamer
|
||||
% ========================================================================
|
||||
% Usage: \input{paper-navbar.tex} in the preamble (after \usetheme and color definitions)
|
||||
%
|
||||
% Provides:
|
||||
% - Top navigation bar: section names + miniframe dots (no subsection row)
|
||||
% - Bottom footer: Author | Paper Title | Journal, Year | Page number
|
||||
% - All colors follow myblue (adapts to any Preset Color Palette)
|
||||
%
|
||||
% Prerequisites (must be defined before \input):
|
||||
% - \definecolor{myblue}{HTML}{...} (from chosen Preset Color Palette)
|
||||
% - \useoutertheme{miniframes} (required for top navigation)
|
||||
%
|
||||
% Paper metadata setup (in preamble, after \input):
|
||||
% \title[Short Title]{Full Title}
|
||||
% \author[Author (Affiliation)]{Full Author List}
|
||||
% \date[Journal Name, Year]{} % leave empty if no journal: \date[]{}
|
||||
% ========================================================================
|
||||
|
||||
% ── Unify header and footer colors (follow myblue) ─────────────────────
|
||||
% Top navbar: light tint of theme color
|
||||
\setbeamercolor{section in head/foot}{bg=myblue!15, fg=myblue!80!black}
|
||||
\setbeamercolor{subsection in head/foot}{bg=myblue!15, fg=myblue!80!black}
|
||||
% Bottom footer: author/journal/page use light tint, title uses mid tint
|
||||
\setbeamercolor{author in head/foot}{bg=myblue!15, fg=myblue!80!black}
|
||||
\setbeamercolor{title in head/foot}{bg=myblue!30, fg=white}
|
||||
\setbeamercolor{date in head/foot}{bg=myblue!15, fg=myblue!80!black}
|
||||
|
||||
% ── Remove navigation symbols ─────────────────────────────────────────
|
||||
\setbeamertemplate{navigation symbols}{}
|
||||
|
||||
% ── Compress miniframes + remove subsection empty row ─────────────────
|
||||
\makeatletter
|
||||
\let\beamer@writeslidentry@miniframeson=\beamer@writeslidentry
|
||||
\def\beamer@writeslidentry@miniframesoff{%
|
||||
\expandafter\beamer@ifempty\expandafter{\beamer@framestartpage}{}%
|
||||
{\addtocontents{nav}{\protect\headcommand{%
|
||||
\protect\beamer@partpages{\the\c@page}{\the\c@page}}}}}
|
||||
\newcommand*{\miniframeson}{\let\beamer@writeslidentry=\beamer@writeslidentry@miniframeson}
|
||||
\newcommand*{\miniframesoff}{\let\beamer@writeslidentry=\beamer@writeslidentry@miniframesoff}
|
||||
\beamer@compresstrue
|
||||
\makeatother
|
||||
|
||||
% ── Top navigation: section names + miniframe dots, no subsection row ──
|
||||
\setbeamertemplate{headline}{%
|
||||
\begin{beamercolorbox}[colsep=1.5pt]{upper separation line head}
|
||||
\end{beamercolorbox}
|
||||
\begin{beamercolorbox}{section in head/foot}
|
||||
\vskip2pt\insertnavigation{\paperwidth}\vskip2pt
|
||||
\end{beamercolorbox}%
|
||||
}
|
||||
|
||||
% ── Bottom footer: Author | Paper Title | Journal | Page ──────────────
|
||||
\makeatletter
|
||||
\setbeamertemplate{footline}{%
|
||||
\leavevmode%
|
||||
\hbox{%
|
||||
\begin{beamercolorbox}[wd=.25\paperwidth,ht=2.5ex,dp=1ex,center]{author in head/foot}%
|
||||
\usebeamerfont{author in head/foot}\insertshortauthor
|
||||
\end{beamercolorbox}%
|
||||
\begin{beamercolorbox}[wd=.42\paperwidth,ht=2.5ex,dp=1ex,center]{title in head/foot}%
|
||||
\usebeamerfont{title in head/foot}\insertshorttitle
|
||||
\end{beamercolorbox}%
|
||||
\begin{beamercolorbox}[wd=.22\paperwidth,ht=2.5ex,dp=1ex,center]{date in head/foot}%
|
||||
\usebeamerfont{date in head/foot}\insertshortdate
|
||||
\end{beamercolorbox}%
|
||||
\begin{beamercolorbox}[wd=.11\paperwidth,ht=2.5ex,dp=1ex,right]{date in head/foot}%
|
||||
\usebeamerfont{date in head/foot}\insertframenumber{}/\inserttotalframenumber\kern2em
|
||||
\end{beamercolorbox}%
|
||||
}%
|
||||
}
|
||||
\makeatother
|
||||
151
skills/ppt/references/progress-navbar.tex
Executable file
151
skills/ppt/references/progress-navbar.tex
Executable file
@@ -0,0 +1,151 @@
|
||||
% ========================================================================
|
||||
% Progress Navigation Bar for Beamer
|
||||
% ========================================================================
|
||||
% Usage: \input{progress-navbar.tex} in the preamble (after \usetheme)
|
||||
%
|
||||
% Features:
|
||||
% - Dynamic equal-width boxes: each box = (paperwidth - 50pt) / total frames
|
||||
% - Three-level symbols: ≡ (home), 1/2/3 (section), ◆ (subsection), - (slide)
|
||||
% - Teal progress coloring: visited = teal!60 fill, unvisited = hollow
|
||||
% - Clickable hyperlinks on every box
|
||||
% - Automatic section/subsection title pages
|
||||
% - Requires --runs 2 for correct width calculation
|
||||
%
|
||||
% Customization:
|
||||
% - Change "teal!60" to any color (e.g. myblue!60) for different themes
|
||||
% - Change "teal" in \color{teal}\hrule for the top separator line
|
||||
% ========================================================================
|
||||
|
||||
\makeatletter
|
||||
|
||||
% ── Auto section/subsection title pages ─────────────────────────────────
|
||||
\AtBeginSection[]{\frame{\sectionpage}}
|
||||
\AtBeginSubsection[]{\frame{\subsectionpage}}
|
||||
|
||||
% ── Lengths and counters ────────────────────────────────────────────────
|
||||
\newlength{\my@unitwidth}
|
||||
\newlength{\my@tempsize}
|
||||
\newcounter{my@sectnum}
|
||||
|
||||
% ── Helper: extract last digit of section number ────────────────────────
|
||||
\newcommand{\my@lastdigit}[1]{%
|
||||
\loop\ifnum\value{#1}>9\addtocounter{#1}{-10}\repeat
|
||||
{\normalfont\arabic{#1}}%
|
||||
}
|
||||
|
||||
% ── Box primitives ──────────────────────────────────────────────────────
|
||||
\newcommand\my@fixedbox[2]{%
|
||||
\makebox[#1]{\rule[-1ex]{0pt}{3.25ex}#2}%
|
||||
}
|
||||
|
||||
\newcommand\my@colorbox[3]{%
|
||||
{\setlength{\fboxsep}{0pt}\colorbox{#1}{\my@fixedbox{#2}{#3}}}%
|
||||
}
|
||||
|
||||
% ── Level marker: b=section, m=subsection, s=slide ─────────────────────
|
||||
\def\my@temptext{}
|
||||
\def\my@level{s}
|
||||
|
||||
\newcommand{\my@navbox}[1][]{%
|
||||
\if\relax\detokenize{#1}\relax
|
||||
\def\my@tempbox{\my@fixedbox}%
|
||||
\else
|
||||
\def\my@tempbox{\my@colorbox{#1}}%
|
||||
\fi
|
||||
\if b\my@level
|
||||
\def\my@temptext{\my@lastdigit{my@sectnum}}%
|
||||
\fi
|
||||
\if m\my@level
|
||||
\def\my@temptext{$\diamond$}%
|
||||
\fi
|
||||
\if s\my@level
|
||||
\def\my@temptext{$-$}%
|
||||
\fi
|
||||
\my@tempbox{\my@unitwidth}{\my@temptext}%
|
||||
}
|
||||
|
||||
% ── Navigation box templates (home / done / todo) ──────────────────────
|
||||
\defbeamertemplate{navigation box}{home}{%
|
||||
\my@colorbox{teal!60}{\my@unitwidth}{$\equiv$}%
|
||||
}
|
||||
|
||||
\defbeamertemplate{navigation box}{done}{%
|
||||
\my@navbox[teal!60]%
|
||||
}
|
||||
|
||||
\defbeamertemplate{navigation box}{todo}{%
|
||||
\my@navbox
|
||||
}
|
||||
|
||||
% ── Box dispatch commands ──────────────────────────────────────────────
|
||||
\newcommand{\my@bigbox}{\gdef\my@level{b}\usebeamertemplate{navigation box}}
|
||||
\newcommand{\my@medbox}{\gdef\my@level{m}\usebeamertemplate{navigation box}}
|
||||
\newcommand{\my@smallbox}{\gdef\my@level{s}\usebeamertemplate{navigation box}}
|
||||
|
||||
% ── Hook into Beamer's navigation infrastructure ──────────────────────
|
||||
\renewcommand{\sectionentry}[5]{\gdef\my@currentbox{big}\setcounter{my@sectnum}{#1}}
|
||||
\renewcommand{\beamer@subsectionentry}[5]{\gdef\my@currentbox{med}}
|
||||
|
||||
\renewcommand{\slideentry}[6]{%
|
||||
\def\my@temp@i{1/1}%
|
||||
\def\my@temp@ii{#4}%
|
||||
% Default: assume done
|
||||
\ifx\my@temp@i\my@temp@ii
|
||||
\setbeamertemplate{navigation box}[home]%
|
||||
\else
|
||||
\setbeamertemplate{navigation box}[done]%
|
||||
\fi
|
||||
% Override to todo if this slide is ahead of current position
|
||||
\ifnum\c@section<#1%
|
||||
\setbeamertemplate{navigation box}[todo]%
|
||||
\else
|
||||
\ifnum\c@section=#1\ifnum\c@subsection<#2%
|
||||
\setbeamertemplate{navigation box}[todo]%
|
||||
\else
|
||||
\ifnum\c@subsection=#2\ifnum\c@subsectionslide<#3%
|
||||
\setbeamertemplate{navigation box}[todo]%
|
||||
\fi\fi
|
||||
\fi\fi
|
||||
\fi
|
||||
% Dispatch to correct level box
|
||||
\def\my@test@big{big}%
|
||||
\def\my@test@med{med}%
|
||||
\ifx\my@temp@i\my@temp@ii
|
||||
\beamer@link(#4){\my@bigbox}%
|
||||
\else
|
||||
\ifx\my@currentbox\my@test@big
|
||||
\beamer@link(#4){\my@bigbox}%
|
||||
\else\ifx\my@currentbox\my@test@med
|
||||
\beamer@link(#4){\my@medbox}%
|
||||
\else
|
||||
\beamer@link(#4){\my@smallbox}%
|
||||
\fi\fi
|
||||
\fi
|
||||
\gdef\my@currentbox{small}%
|
||||
}
|
||||
|
||||
% ── Footline template ─────────────────────────────────────────────────
|
||||
\defbeamertemplate{footline}{progress}
|
||||
{%
|
||||
% Dynamic width: divide available space equally among all frames
|
||||
\ifnum\inserttotalframenumber>0
|
||||
\setlength{\my@unitwidth}{\dimexpr(\paperwidth - 50pt)/\inserttotalframenumber\relax}%
|
||||
\else
|
||||
\setlength{\my@unitwidth}{20pt}%
|
||||
\fi
|
||||
{\color{teal}\hrule}%
|
||||
\hbox to \paperwidth{%
|
||||
\hbox to \dimexpr\paperwidth - 50pt\relax{%
|
||||
\kern2pt{\normalfont\dohead}\hfill
|
||||
}%
|
||||
\hbox to 50pt{%
|
||||
\hfill{\normalfont\insertframenumber{}/\inserttotalframenumber}\kern4pt
|
||||
}%
|
||||
}%
|
||||
}
|
||||
|
||||
% ── Activate ──────────────────────────────────────────────────────────
|
||||
\setbeamertemplate{navigation symbols}{}
|
||||
\setbeamertemplate{footline}[progress]
|
||||
|
||||
\makeatother
|
||||
BIN
skills/ppt/scripts/__pycache__/inventory.cpython-313.pyc
Executable file
BIN
skills/ppt/scripts/__pycache__/inventory.cpython-313.pyc
Executable file
Binary file not shown.
1337
skills/ppt/scripts/html2pptx.js
Executable file
1337
skills/ppt/scripts/html2pptx.js
Executable file
File diff suppressed because it is too large
Load Diff
512
skills/ppt/scripts/inventory.py
Executable file
512
skills/ppt/scripts/inventory.py
Executable file
@@ -0,0 +1,512 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Extract structured text content from PowerPoint presentations.
|
||||
|
||||
Usage:
|
||||
python inventory.py input.pptx output.json [--issues-only]
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from pptx import Presentation
|
||||
from pptx.enum.text import PP_ALIGN
|
||||
from pptx.shapes.base import BaseShape
|
||||
|
||||
# Public type alias used by replace.py: slide_id -> {shape_id -> ShapeData}
|
||||
InventoryData = Dict[str, Dict[str, "ShapeData"]]
|
||||
|
||||
_EMU = 914400 # EMUs per inch
|
||||
_BULLET_NS = "{http://schemas.openxmlformats.org/drawingml/2006/main}"
|
||||
_ALIGN_MAP = {
|
||||
PP_ALIGN.CENTER: "CENTER",
|
||||
PP_ALIGN.RIGHT: "RIGHT",
|
||||
PP_ALIGN.JUSTIFY: "JUSTIFY",
|
||||
}
|
||||
|
||||
|
||||
def _is_cjk(ch: str) -> bool:
|
||||
"""True for full-width CJK characters (Chinese, Japanese, Korean, full-width forms)."""
|
||||
cp = ord(ch)
|
||||
return (
|
||||
0x4E00 <= cp <= 0x9FFF # CJK Unified Ideographs
|
||||
or 0x3400 <= cp <= 0x4DBF # CJK Extension A
|
||||
or 0x3040 <= cp <= 0x30FF # Hiragana / Katakana
|
||||
or 0xFF00 <= cp <= 0xFFEF # Full-width ASCII & half-width Katakana
|
||||
or 0xAC00 <= cp <= 0xD7AF # Hangul syllables
|
||||
)
|
||||
|
||||
|
||||
class ParagraphData:
|
||||
"""Text and formatting for one paragraph."""
|
||||
|
||||
def __init__(self, paragraph: Any):
|
||||
self.text: str = paragraph.text.strip()
|
||||
self.bullet: bool = False
|
||||
self.level: Optional[int] = None
|
||||
self.alignment: Optional[str] = None
|
||||
self.space_before: Optional[float] = None
|
||||
self.space_after: Optional[float] = None
|
||||
self.font_name: Optional[str] = None
|
||||
self.font_size: Optional[float] = None
|
||||
self.bold: Optional[bool] = None
|
||||
self.italic: Optional[bool] = None
|
||||
self.underline: Optional[bool] = None
|
||||
self.color: Optional[str] = None
|
||||
self.theme_color: Optional[str] = None
|
||||
self.line_spacing: Optional[float] = None
|
||||
|
||||
# Bullet detection
|
||||
pPr = getattr(getattr(paragraph, "_p", None), "pPr", None)
|
||||
if pPr is not None and (
|
||||
pPr.find(f"{_BULLET_NS}buChar") is not None
|
||||
or pPr.find(f"{_BULLET_NS}buAutoNum") is not None
|
||||
):
|
||||
self.bullet = True
|
||||
self.level = getattr(paragraph, "level", None)
|
||||
|
||||
# Alignment (omit LEFT — it's the default)
|
||||
align = getattr(paragraph, "alignment", None)
|
||||
if align in _ALIGN_MAP:
|
||||
self.alignment = _ALIGN_MAP[align]
|
||||
|
||||
# Spacing
|
||||
sb = getattr(paragraph, "space_before", None)
|
||||
if sb:
|
||||
self.space_before = sb.pt
|
||||
sa = getattr(paragraph, "space_after", None)
|
||||
if sa:
|
||||
self.space_after = sa.pt
|
||||
|
||||
# Font from first run
|
||||
if paragraph.runs:
|
||||
font = paragraph.runs[0].font
|
||||
self.font_name = font.name or None
|
||||
self.font_size = font.size.pt if font.size else None
|
||||
self.bold = font.bold
|
||||
self.italic = font.italic
|
||||
self.underline = font.underline
|
||||
try:
|
||||
self.color = str(font.color.rgb) if font.color.rgb else None
|
||||
except (AttributeError, TypeError):
|
||||
try:
|
||||
tc = font.color.theme_color
|
||||
self.theme_color = tc.name if tc else None
|
||||
except (AttributeError, TypeError):
|
||||
pass
|
||||
|
||||
# Line spacing (after font so font_size is available)
|
||||
ls = getattr(paragraph, "line_spacing", None)
|
||||
if ls is not None:
|
||||
if hasattr(ls, "pt"):
|
||||
self.line_spacing = round(ls.pt, 2)
|
||||
else:
|
||||
# Multiplier — convert to points using current font size
|
||||
self.line_spacing = round(ls * (self.font_size or 12.0), 2)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
d: Dict[str, Any] = {"text": self.text}
|
||||
if self.bullet:
|
||||
d["bullet"] = True
|
||||
if self.level is not None:
|
||||
d["level"] = self.level
|
||||
if self.alignment:
|
||||
d["alignment"] = self.alignment
|
||||
for key in ("space_before", "space_after", "font_size", "line_spacing"):
|
||||
val = getattr(self, key)
|
||||
if val is not None:
|
||||
d[key] = val
|
||||
if self.font_name:
|
||||
d["font_name"] = self.font_name
|
||||
for key in ("bold", "italic", "underline"):
|
||||
val = getattr(self, key)
|
||||
if val is not None:
|
||||
d[key] = val
|
||||
if self.color:
|
||||
d["color"] = self.color
|
||||
elif self.theme_color:
|
||||
d["theme_color"] = self.theme_color
|
||||
return d
|
||||
|
||||
|
||||
class ShapeData:
|
||||
"""Position, formatting metadata, and text content for one shape."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
shape: BaseShape,
|
||||
absolute_left: Optional[int] = None,
|
||||
absolute_top: Optional[int] = None,
|
||||
slide: Optional[Any] = None,
|
||||
):
|
||||
self.shape = shape
|
||||
self.shape_id: str = "" # assigned after sorting
|
||||
|
||||
# Slide dimensions (for overflow checking)
|
||||
self.slide_width_emu: Optional[int] = None
|
||||
self.slide_height_emu: Optional[int] = None
|
||||
if slide:
|
||||
try:
|
||||
prs_xml = slide.part.package.presentation_part.presentation
|
||||
self.slide_width_emu = prs_xml.slide_width
|
||||
self.slide_height_emu = prs_xml.slide_height
|
||||
except (AttributeError, TypeError):
|
||||
pass
|
||||
|
||||
# Placeholder metadata
|
||||
self.placeholder_type: Optional[str] = None
|
||||
self.default_font_size: Optional[float] = None
|
||||
if getattr(shape, "is_placeholder", False):
|
||||
pf = shape.placeholder_format # type: ignore
|
||||
if pf and pf.type:
|
||||
self.placeholder_type = str(pf.type).split(".")[-1].split(" ")[0]
|
||||
if slide and hasattr(slide, "slide_layout"):
|
||||
self.default_font_size = _layout_font_size(shape, slide.slide_layout)
|
||||
|
||||
# Position in inches (use absolute coords for shapes inside groups)
|
||||
left_emu = absolute_left if absolute_left is not None else getattr(shape, "left", 0)
|
||||
top_emu = absolute_top if absolute_top is not None else getattr(shape, "top", 0)
|
||||
self.left = round(left_emu / _EMU, 2)
|
||||
self.top = round(top_emu / _EMU, 2)
|
||||
self.width = round(getattr(shape, "width", 0) / _EMU, 2)
|
||||
self.height = round(getattr(shape, "height", 0) / _EMU, 2)
|
||||
|
||||
# EMU positions kept for overflow arithmetic
|
||||
self.left_emu = left_emu
|
||||
self.top_emu = top_emu
|
||||
self.width_emu = getattr(shape, "width", 0)
|
||||
self.height_emu = getattr(shape, "height", 0)
|
||||
|
||||
# Issue detection
|
||||
self.frame_overflow_bottom: Optional[float] = None
|
||||
self.slide_overflow_right: Optional[float] = None
|
||||
self.slide_overflow_bottom: Optional[float] = None
|
||||
self.overlapping_shapes: Dict[str, float] = {}
|
||||
self.warnings: List[str] = []
|
||||
self._estimate_frame_overflow()
|
||||
self._calculate_slide_overflow()
|
||||
self._detect_bullet_issues()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Issue detection helpers
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _default_font_size_pts(self) -> float:
|
||||
"""Best-effort default font size from theme styles."""
|
||||
if self.default_font_size:
|
||||
return self.default_font_size
|
||||
try:
|
||||
master = self.shape.part.slide_layout.slide_master # type: ignore
|
||||
style = "titleStyle" if (self.placeholder_type and "TITLE" in self.placeholder_type) else "bodyStyle"
|
||||
for child in master.element.iter():
|
||||
tag = child.tag.split("}")[-1] if "}" in child.tag else child.tag
|
||||
if tag == style:
|
||||
for elem in child.iter():
|
||||
if "sz" in elem.attrib:
|
||||
return int(elem.attrib["sz"]) / 100.0
|
||||
except Exception:
|
||||
pass
|
||||
return 14.0 # conservative fallback
|
||||
|
||||
def _estimate_frame_overflow(self) -> None:
|
||||
"""Estimate text overflow via character-count heuristic (no external deps)."""
|
||||
if not hasattr(self.shape, "text_frame"):
|
||||
return
|
||||
tf = self.shape.text_frame # type: ignore
|
||||
if not tf or not tf.paragraphs:
|
||||
return
|
||||
|
||||
# Usable area after text frame margins
|
||||
def e2i(v: Any) -> float:
|
||||
return (v or 0) / _EMU
|
||||
|
||||
margin_h = e2i(tf.margin_top) + e2i(tf.margin_bottom)
|
||||
margin_w = e2i(tf.margin_left) + e2i(tf.margin_right)
|
||||
if margin_h == 0:
|
||||
margin_h = 0.10 # PowerPoint default: ~0.05" top + 0.05" bottom
|
||||
if margin_w == 0:
|
||||
margin_w = 0.20 # PowerPoint default: ~0.1" left + 0.1" right
|
||||
usable_w = self.width - margin_w
|
||||
usable_h = self.height - margin_h
|
||||
if usable_w <= 0 or usable_h <= 0:
|
||||
return
|
||||
|
||||
default_size = self._default_font_size_pts()
|
||||
total_h = 0.0
|
||||
|
||||
for para in tf.paragraphs:
|
||||
if not para.text.strip():
|
||||
continue
|
||||
pd = ParagraphData(para)
|
||||
size_pt = pd.font_size or default_size
|
||||
|
||||
# Estimate text width: CJK chars ≈ 1.0× font_size pts, others ≈ 0.5×
|
||||
text_w_pts = sum(
|
||||
size_pt if _is_cjk(c) else size_pt * 0.5
|
||||
for c in para.text
|
||||
)
|
||||
usable_w_pts = usable_w * 72.0
|
||||
n_lines = max(1, -(-int(text_w_pts) // max(1, int(usable_w_pts)))) # ceiling div
|
||||
|
||||
line_h_in = (pd.line_spacing or size_pt) / 72.0
|
||||
total_h += (pd.space_before or 0) / 72.0
|
||||
total_h += n_lines * line_h_in
|
||||
total_h += (pd.space_after or 0) / 72.0
|
||||
|
||||
if total_h > usable_h + 0.05: # ignore sub-0.05" rounding noise
|
||||
self.frame_overflow_bottom = round(total_h - usable_h, 2)
|
||||
|
||||
def _calculate_slide_overflow(self) -> None:
|
||||
if self.slide_width_emu is None or self.slide_height_emu is None:
|
||||
return
|
||||
r = self.left_emu + self.width_emu - self.slide_width_emu
|
||||
if r > 0:
|
||||
v = round(r / _EMU, 2)
|
||||
if v > 0.01:
|
||||
self.slide_overflow_right = v
|
||||
b = self.top_emu + self.height_emu - self.slide_height_emu
|
||||
if b > 0:
|
||||
v = round(b / _EMU, 2)
|
||||
if v > 0.01:
|
||||
self.slide_overflow_bottom = v
|
||||
|
||||
def _detect_bullet_issues(self) -> None:
|
||||
if not hasattr(self.shape, "text_frame"):
|
||||
return
|
||||
for para in self.shape.text_frame.paragraphs: # type: ignore
|
||||
text = para.text.strip()
|
||||
if text and any(text.startswith(s + " ") for s in ("•", "●", "○")):
|
||||
self.warnings.append("manual_bullet_symbol: use proper bullet formatting")
|
||||
break
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Public interface
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@property
|
||||
def paragraphs(self) -> List[ParagraphData]:
|
||||
if not hasattr(self.shape, "text_frame"):
|
||||
return []
|
||||
return [ParagraphData(p) for p in self.shape.text_frame.paragraphs if p.text.strip()] # type: ignore
|
||||
|
||||
@property
|
||||
def has_any_issues(self) -> bool:
|
||||
return bool(
|
||||
self.frame_overflow_bottom is not None
|
||||
or self.slide_overflow_right is not None
|
||||
or self.slide_overflow_bottom is not None
|
||||
or self.overlapping_shapes
|
||||
or self.warnings
|
||||
)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
d: Dict[str, Any] = {
|
||||
"left": self.left, "top": self.top,
|
||||
"width": self.width, "height": self.height,
|
||||
}
|
||||
if self.placeholder_type:
|
||||
d["placeholder_type"] = self.placeholder_type
|
||||
if self.default_font_size:
|
||||
d["default_font_size"] = self.default_font_size
|
||||
|
||||
overflow: Dict[str, Any] = {}
|
||||
if self.frame_overflow_bottom is not None:
|
||||
overflow["frame"] = {"overflow_bottom": self.frame_overflow_bottom}
|
||||
slide_ov: Dict[str, float] = {}
|
||||
if self.slide_overflow_right is not None:
|
||||
slide_ov["overflow_right"] = self.slide_overflow_right
|
||||
if self.slide_overflow_bottom is not None:
|
||||
slide_ov["overflow_bottom"] = self.slide_overflow_bottom
|
||||
if slide_ov:
|
||||
overflow["slide"] = slide_ov
|
||||
if overflow:
|
||||
d["overflow"] = overflow
|
||||
if self.overlapping_shapes:
|
||||
d["overlap"] = {"overlapping_shapes": self.overlapping_shapes}
|
||||
if self.warnings:
|
||||
d["warnings"] = self.warnings
|
||||
d["paragraphs"] = [p.to_dict() for p in self.paragraphs]
|
||||
return d
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Module-level helpers
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _layout_font_size(shape: BaseShape, slide_layout: Any) -> Optional[float]:
|
||||
"""Extract default font size from the matching layout placeholder."""
|
||||
try:
|
||||
shape_type = shape.placeholder_format.type # type: ignore
|
||||
for ph in slide_layout.placeholders:
|
||||
if ph.placeholder_format.type == shape_type:
|
||||
for elem in ph.element.iter():
|
||||
if "defRPr" in elem.tag and (sz := elem.get("sz")):
|
||||
return float(sz) / 100.0
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def _is_valid_shape(shape: BaseShape) -> bool:
|
||||
"""True if shape has meaningful text and is not a slide-number placeholder."""
|
||||
if not hasattr(shape, "text_frame"):
|
||||
return False
|
||||
tf = shape.text_frame # type: ignore
|
||||
if not tf or not tf.text.strip():
|
||||
return False
|
||||
if getattr(shape, "is_placeholder", False):
|
||||
pf = shape.placeholder_format # type: ignore
|
||||
if pf and pf.type:
|
||||
pt = str(pf.type).split(".")[-1].split(" ")[0]
|
||||
if pt == "SLIDE_NUMBER":
|
||||
return False
|
||||
if pt == "FOOTER" and tf.text.strip().isdigit():
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _collect_shapes(shape: BaseShape, parent_left: int = 0, parent_top: int = 0):
|
||||
"""Yield (shape, abs_left, abs_top) tuples, recursing into GroupShapes."""
|
||||
if hasattr(shape, "shapes"): # GroupShape
|
||||
g_left = parent_left + getattr(shape, "left", 0)
|
||||
g_top = parent_top + getattr(shape, "top", 0)
|
||||
for child in shape.shapes: # type: ignore
|
||||
yield from _collect_shapes(child, g_left, g_top)
|
||||
elif _is_valid_shape(shape):
|
||||
yield (
|
||||
shape,
|
||||
parent_left + getattr(shape, "left", 0),
|
||||
parent_top + getattr(shape, "top", 0),
|
||||
)
|
||||
|
||||
|
||||
def _sort_by_position(shapes: List[ShapeData]) -> List[ShapeData]:
|
||||
"""Sort shapes top-to-bottom, left-to-right (0.5" row tolerance)."""
|
||||
if not shapes:
|
||||
return shapes
|
||||
shapes = sorted(shapes, key=lambda s: (s.top, s.left))
|
||||
result: List[ShapeData] = []
|
||||
row = [shapes[0]]
|
||||
row_top = shapes[0].top
|
||||
for s in shapes[1:]:
|
||||
if abs(s.top - row_top) <= 0.5:
|
||||
row.append(s)
|
||||
else:
|
||||
result.extend(sorted(row, key=lambda s: s.left))
|
||||
row = [s]
|
||||
row_top = s.top
|
||||
result.extend(sorted(row, key=lambda s: s.left))
|
||||
return result
|
||||
|
||||
|
||||
def _detect_overlaps(shapes: List[ShapeData]) -> None:
|
||||
"""Populate overlapping_shapes for all pairs with meaningful overlap."""
|
||||
for i, s1 in enumerate(shapes):
|
||||
for s2 in shapes[i + 1:]:
|
||||
ow = min(s1.left + s1.width, s2.left + s2.width) - max(s1.left, s2.left)
|
||||
oh = min(s1.top + s1.height, s2.top + s2.height) - max(s1.top, s2.top)
|
||||
if ow > 0.05 and oh > 0.05:
|
||||
area = round(ow * oh, 2)
|
||||
s1.overlapping_shapes[s2.shape_id] = area
|
||||
s2.overlapping_shapes[s1.shape_id] = area
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Public API
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def extract_text_inventory(
|
||||
pptx_path: Path,
|
||||
prs: Optional[Any] = None,
|
||||
issues_only: bool = False,
|
||||
) -> InventoryData:
|
||||
"""Extract text from all slides.
|
||||
|
||||
Returns {slide-N: {shape-N: ShapeData}}, shapes sorted by visual position.
|
||||
Pass an existing Presentation object via `prs` to avoid re-loading.
|
||||
"""
|
||||
if prs is None:
|
||||
prs = Presentation(str(pptx_path))
|
||||
|
||||
inventory: InventoryData = {}
|
||||
|
||||
for slide_idx, slide in enumerate(prs.slides):
|
||||
raw = list(_collect_shapes_from_slide(slide))
|
||||
if not raw:
|
||||
continue
|
||||
|
||||
shape_data_list = [ShapeData(s, al, at, slide) for s, al, at in raw]
|
||||
sorted_shapes = _sort_by_position(shape_data_list)
|
||||
|
||||
for idx, sd in enumerate(sorted_shapes):
|
||||
sd.shape_id = f"shape-{idx}"
|
||||
|
||||
if len(sorted_shapes) > 1:
|
||||
_detect_overlaps(sorted_shapes)
|
||||
|
||||
if issues_only:
|
||||
sorted_shapes = [sd for sd in sorted_shapes if sd.has_any_issues]
|
||||
if not sorted_shapes:
|
||||
continue
|
||||
|
||||
inventory[f"slide-{slide_idx}"] = {sd.shape_id: sd for sd in sorted_shapes}
|
||||
|
||||
return inventory
|
||||
|
||||
|
||||
def _collect_shapes_from_slide(slide):
|
||||
"""Yield (shape, abs_left, abs_top) for all valid text shapes on a slide."""
|
||||
for shape in slide.shapes: # type: ignore
|
||||
yield from _collect_shapes(shape)
|
||||
|
||||
|
||||
def save_inventory(inventory: InventoryData, output_path: Path) -> None:
|
||||
"""Serialize inventory to a JSON file."""
|
||||
json_data = {
|
||||
slide_key: {k: sd.to_dict() for k, sd in shapes.items()}
|
||||
for slide_key, shapes in inventory.items()
|
||||
}
|
||||
with open(output_path, "w", encoding="utf-8") as f:
|
||||
json.dump(json_data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Extract text inventory from a PowerPoint file.")
|
||||
parser.add_argument("input", help="Input .pptx file")
|
||||
parser.add_argument("output", help="Output .json file")
|
||||
parser.add_argument("--issues-only", action="store_true",
|
||||
help="Include only shapes with overflow/overlap issues")
|
||||
args = parser.parse_args()
|
||||
|
||||
input_path = Path(args.input)
|
||||
if not input_path.exists():
|
||||
print(f"Error: File not found: {args.input}")
|
||||
sys.exit(1)
|
||||
if input_path.suffix.lower() != ".pptx":
|
||||
print("Error: Input must be a .pptx file")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
inventory = extract_text_inventory(input_path, issues_only=args.issues_only)
|
||||
output_path = Path(args.output)
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
save_inventory(inventory, output_path)
|
||||
|
||||
total = sum(len(v) for v in inventory.values())
|
||||
if args.issues_only:
|
||||
print(f"Found {total} shapes with issues across {len(inventory)} slides → {args.output}")
|
||||
else:
|
||||
print(f"Found {total} text shapes across {len(inventory)} slides → {args.output}")
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"Error: {e}")
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
2046
skills/ppt/scripts/pdf.py
Executable file
2046
skills/ppt/scripts/pdf.py
Executable file
File diff suppressed because it is too large
Load Diff
144
skills/ppt/scripts/rearrange.py
Executable file
144
skills/ppt/scripts/rearrange.py
Executable file
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Rearrange PowerPoint slides based on a sequence of indices.
|
||||
|
||||
Usage:
|
||||
python rearrange.py template.pptx output.pptx 0,34,34,50,52
|
||||
|
||||
Slides are 0-indexed. Indices can repeat to duplicate slides.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
|
||||
from pptx import Presentation
|
||||
from pptx.oxml.ns import qn
|
||||
|
||||
|
||||
def copy_slide(src_prs: Presentation, dst_prs: Presentation, index: int, dst_layouts: dict) -> None:
|
||||
"""Append a copy of slide[index] from src_prs into dst_prs."""
|
||||
src_slide = src_prs.slides[index]
|
||||
|
||||
# Match layout by name across all masters; fall back to first available layout
|
||||
layout_name = src_slide.slide_layout.name
|
||||
dst_layout = dst_layouts.get(layout_name) or dst_prs.slide_layouts[0]
|
||||
|
||||
new_slide = dst_prs.slides.add_slide(dst_layout)
|
||||
|
||||
# Clear auto-added placeholder shapes
|
||||
for shape in list(new_slide.shapes):
|
||||
sp = shape.element
|
||||
sp.getparent().remove(sp)
|
||||
|
||||
# Copy ALL non-layout relationships from source and build old→new rId mapping.
|
||||
# This covers images, media, charts, hyperlinks, videos, and any other embedded content.
|
||||
# Without this, relationship attributes (r:embed, r:id, r:link) in copied shapes would
|
||||
# reference rIds that don't exist in the new slide, causing PowerPoint repair dialogs.
|
||||
R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
SKIP_TYPES = {"slideLayout", "notesSlide", "slide"} # handled by python-pptx infrastructure
|
||||
rId_mapping: dict = {}
|
||||
for rel_id, rel in src_slide.part.rels.items():
|
||||
rel_short = rel.reltype.split("/")[-1]
|
||||
if rel_short in SKIP_TYPES:
|
||||
continue
|
||||
new_rId = new_slide.part.rels.get_or_add(rel.reltype, rel._target)
|
||||
rId_mapping[rel_id] = new_rId
|
||||
|
||||
# Copy all shape elements
|
||||
r_embed = f"{{{R_NS}}}embed"
|
||||
r_id = f"{{{R_NS}}}id"
|
||||
r_link = f"{{{R_NS}}}link"
|
||||
|
||||
for shape in src_slide.shapes:
|
||||
new_el = deepcopy(shape.element)
|
||||
new_slide.shapes._spTree.insert_element_before(new_el, "p:extLst")
|
||||
|
||||
# Remap ALL relationship references (images, charts, hyperlinks, video, etc.)
|
||||
for el in new_el.iter():
|
||||
for attr in (r_embed, r_id, r_link):
|
||||
old_rId = el.get(attr)
|
||||
if old_rId and old_rId in rId_mapping:
|
||||
el.set(attr, rId_mapping[old_rId])
|
||||
|
||||
# Copy slide-level background if defined.
|
||||
# p:bg lives inside p:cSld, not directly under p:sld.
|
||||
src_cSld = src_slide.element.find(qn("p:cSld"))
|
||||
dst_cSld = new_slide.element.find(qn("p:cSld"))
|
||||
if src_cSld is not None and dst_cSld is not None:
|
||||
src_bg = src_cSld.find(qn("p:bg"))
|
||||
if src_bg is not None:
|
||||
existing_bg = dst_cSld.find(qn("p:bg"))
|
||||
if existing_bg is not None:
|
||||
dst_cSld.remove(existing_bg)
|
||||
dst_cSld.insert(0, deepcopy(src_bg))
|
||||
|
||||
|
||||
def rearrange_presentation(
|
||||
template_path: Path, output_path: Path, slide_sequence: list[int]
|
||||
) -> None:
|
||||
src_prs = Presentation(template_path)
|
||||
total = len(src_prs.slides)
|
||||
|
||||
for idx in slide_sequence:
|
||||
if idx < 0 or idx >= total:
|
||||
raise ValueError(f"Slide index {idx} out of range (0–{total - 1})")
|
||||
|
||||
# Build a fresh presentation with the same dimensions
|
||||
dst_prs = Presentation(template_path)
|
||||
|
||||
# Remove all existing slides from dst_prs
|
||||
sldIdLst = dst_prs.slides._sldIdLst
|
||||
for sldId in list(sldIdLst):
|
||||
rId = sldId.get(qn("r:id")) # must use full namespace via qn(), not bare "r:id"
|
||||
if rId:
|
||||
dst_prs.part.drop_rel(rId)
|
||||
sldIdLst.remove(sldId)
|
||||
|
||||
# Search all slide masters for layout matching (templates may have multiple masters)
|
||||
all_layouts = {
|
||||
layout.name: layout
|
||||
for master in dst_prs.slide_masters
|
||||
for layout in master.slide_layouts
|
||||
}
|
||||
|
||||
# Append slides in requested order (duplicates included)
|
||||
for idx in slide_sequence:
|
||||
copy_slide(src_prs, dst_prs, idx, all_layouts)
|
||||
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
dst_prs.save(output_path)
|
||||
print(f"Saved {len(slide_sequence)} slides → {output_path}")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Rearrange PowerPoint slides.",
|
||||
epilog="Example: python rearrange.py template.pptx output.pptx 0,34,34,50,52",
|
||||
)
|
||||
parser.add_argument("template", help="Path to template PPTX")
|
||||
parser.add_argument("output", help="Path for output PPTX")
|
||||
parser.add_argument("sequence", help="Comma-separated 0-based slide indices")
|
||||
args = parser.parse_args()
|
||||
|
||||
template_path = Path(args.template)
|
||||
if not template_path.exists():
|
||||
print(f"Error: Template not found: {args.template}")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
slide_sequence = [int(x.strip()) for x in args.sequence.split(",")]
|
||||
except ValueError:
|
||||
print("Error: sequence must be comma-separated integers (e.g. 0,34,34,50,52)")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
rearrange_presentation(template_path, Path(args.output), slide_sequence)
|
||||
except ValueError as e:
|
||||
print(f"Error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
231
skills/ppt/scripts/replace.py
Executable file
231
skills/ppt/scripts/replace.py
Executable file
@@ -0,0 +1,231 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Apply text replacements to PowerPoint presentation.
|
||||
|
||||
Usage:
|
||||
python replace.py <input.pptx> <replacements.json> <output.pptx>
|
||||
|
||||
The replacements JSON should have the structure output by inventory.py.
|
||||
ALL text shapes identified by inventory.py will have their text cleared
|
||||
unless "paragraphs" is specified in the replacements for that shape.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from inventory import InventoryData, extract_text_inventory
|
||||
from pptx import Presentation
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.dml import MSO_THEME_COLOR
|
||||
from pptx.enum.text import PP_ALIGN
|
||||
from pptx.oxml.xmlchemy import OxmlElement
|
||||
from pptx.util import Pt
|
||||
|
||||
_ALIGN_MAP = {
|
||||
"LEFT": PP_ALIGN.LEFT,
|
||||
"CENTER": PP_ALIGN.CENTER,
|
||||
"RIGHT": PP_ALIGN.RIGHT,
|
||||
"JUSTIFY": PP_ALIGN.JUSTIFY,
|
||||
}
|
||||
|
||||
# Bullet indentation constants
|
||||
# marL = font_size × (1 + level) × 1.6 pts, converted to EMUs (1 pt = 12700 EMU)
|
||||
_INDENT_FACTOR = 1.6
|
||||
_EMU_PER_PT = 12700
|
||||
|
||||
|
||||
def _clear_paragraph_bullets(paragraph):
|
||||
"""Remove all bullet XML elements from a paragraph's pPr."""
|
||||
pPr = paragraph._element.get_or_add_pPr()
|
||||
for child in list(pPr):
|
||||
if any(child.tag.endswith(t) for t in ("buChar", "buNone", "buAutoNum", "buFont")):
|
||||
pPr.remove(child)
|
||||
return pPr
|
||||
|
||||
|
||||
def _apply_paragraph_properties(paragraph, para_data: Dict[str, Any]):
|
||||
text = para_data.get("text", "")
|
||||
pPr = _clear_paragraph_bullets(paragraph)
|
||||
|
||||
if para_data.get("bullet", False):
|
||||
level = para_data.get("level", 0)
|
||||
paragraph.level = level
|
||||
font_size = para_data.get("font_size", 18.0)
|
||||
pPr.attrib["marL"] = str(int(font_size * _INDENT_FACTOR * (1 + level) * _EMU_PER_PT))
|
||||
pPr.attrib["indent"] = str(int(-font_size * 0.8 * _EMU_PER_PT))
|
||||
buChar = OxmlElement("a:buChar")
|
||||
buChar.set("char", "•")
|
||||
pPr.append(buChar)
|
||||
if "alignment" not in para_data:
|
||||
paragraph.alignment = PP_ALIGN.LEFT
|
||||
else:
|
||||
pPr.attrib["marL"] = "0"
|
||||
pPr.attrib["indent"] = "0"
|
||||
pPr.insert(0, OxmlElement("a:buNone"))
|
||||
|
||||
if para_data.get("alignment") in _ALIGN_MAP:
|
||||
paragraph.alignment = _ALIGN_MAP[para_data["alignment"]]
|
||||
if "space_before" in para_data:
|
||||
paragraph.space_before = Pt(para_data["space_before"])
|
||||
if "space_after" in para_data:
|
||||
paragraph.space_after = Pt(para_data["space_after"])
|
||||
if "line_spacing" in para_data:
|
||||
paragraph.line_spacing = Pt(para_data["line_spacing"])
|
||||
|
||||
run = paragraph.runs[0] if paragraph.runs else paragraph.add_run()
|
||||
run.text = text
|
||||
_apply_font_properties(run, para_data)
|
||||
|
||||
|
||||
def _apply_font_properties(run, para_data: Dict[str, Any]):
|
||||
for attr in ("bold", "italic", "underline"):
|
||||
if attr in para_data:
|
||||
setattr(run.font, attr, para_data[attr])
|
||||
if "font_size" in para_data:
|
||||
run.font.size = Pt(para_data["font_size"])
|
||||
if "font_name" in para_data:
|
||||
run.font.name = para_data["font_name"]
|
||||
if "color" in para_data:
|
||||
h = para_data["color"].lstrip("#")
|
||||
if len(h) == 6:
|
||||
run.font.color.rgb = RGBColor(int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16))
|
||||
elif "theme_color" in para_data:
|
||||
try:
|
||||
run.font.color.theme_color = getattr(MSO_THEME_COLOR, para_data["theme_color"])
|
||||
except AttributeError:
|
||||
print(f" WARNING: Unknown theme color '{para_data['theme_color']}'")
|
||||
|
||||
|
||||
def _check_duplicate_keys(pairs):
|
||||
result = {}
|
||||
for key, value in pairs:
|
||||
if key in result:
|
||||
raise ValueError(f"Duplicate key in JSON: '{key}'")
|
||||
result[key] = value
|
||||
return result
|
||||
|
||||
|
||||
def _validate_replacements(inventory: InventoryData, replacements: Dict) -> List[str]:
|
||||
errors = []
|
||||
for slide_key, shapes_data in replacements.items():
|
||||
if not slide_key.startswith("slide-"):
|
||||
continue
|
||||
if slide_key not in inventory:
|
||||
errors.append(f"Slide '{slide_key}' not found in inventory")
|
||||
continue
|
||||
for shape_key in shapes_data:
|
||||
if shape_key not in inventory[slide_key]:
|
||||
available = sorted(inventory[slide_key].keys())
|
||||
errors.append(
|
||||
f"Shape '{shape_key}' not found on '{slide_key}'. "
|
||||
f"Available: {', '.join(available)}"
|
||||
)
|
||||
return errors
|
||||
|
||||
|
||||
def apply_replacements(pptx_file: str, json_file: str, output_file: str):
|
||||
prs = Presentation(pptx_file)
|
||||
inventory = extract_text_inventory(Path(pptx_file), prs)
|
||||
|
||||
# Snapshot original overflow so we can detect if replacements make it worse
|
||||
original_overflow: Dict[str, Dict[str, float]] = {
|
||||
slide_key: {
|
||||
shape_key: sd.frame_overflow_bottom
|
||||
for shape_key, sd in shapes.items()
|
||||
if sd.frame_overflow_bottom is not None
|
||||
}
|
||||
for slide_key, shapes in inventory.items()
|
||||
}
|
||||
|
||||
with open(json_file) as f:
|
||||
replacements = json.load(f, object_pairs_hook=_check_duplicate_keys)
|
||||
|
||||
errors = _validate_replacements(inventory, replacements)
|
||||
if errors:
|
||||
print("ERROR: Invalid shapes in replacement JSON:")
|
||||
for e in errors:
|
||||
print(f" - {e}")
|
||||
raise ValueError(f"Found {len(errors)} validation error(s)")
|
||||
|
||||
shapes_cleared = shapes_replaced = 0
|
||||
|
||||
for slide_key, shapes_dict in inventory.items():
|
||||
if not slide_key.startswith("slide-"):
|
||||
continue
|
||||
for shape_key, shape_data in shapes_dict.items():
|
||||
if not shape_data.shape:
|
||||
continue
|
||||
tf = shape_data.shape.text_frame # type: ignore
|
||||
tf.clear()
|
||||
shapes_cleared += 1
|
||||
|
||||
para_list = replacements.get(slide_key, {}).get(shape_key, {}).get("paragraphs")
|
||||
if not para_list:
|
||||
continue
|
||||
shapes_replaced += 1
|
||||
# Inherit original font_size if not specified in replacement
|
||||
orig_paras = shape_data.paragraphs or []
|
||||
orig_font_size = orig_paras[0].get("font_size") if orig_paras else None
|
||||
for i, para_data in enumerate(para_list):
|
||||
p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
|
||||
if orig_font_size is not None and "font_size" not in para_data:
|
||||
para_data = {**para_data, "font_size": orig_font_size}
|
||||
_apply_paragraph_properties(p, para_data)
|
||||
|
||||
# Re-check overflow on the updated in-memory presentation.
|
||||
# Note: extract_text_inventory may add benign empty <a:solidFill/> elements
|
||||
# while reading font colors — these are harmless and ignored by PowerPoint.
|
||||
updated_inventory = extract_text_inventory(Path(pptx_file), prs)
|
||||
|
||||
overflow_errors: List[str] = []
|
||||
warnings: List[str] = []
|
||||
for slide_key, shapes_dict in updated_inventory.items():
|
||||
for shape_key, sd in shapes_dict.items():
|
||||
for w in sd.warnings:
|
||||
warnings.append(f"{slide_key}/{shape_key}: {w}")
|
||||
new_ov = sd.frame_overflow_bottom
|
||||
if new_ov is not None:
|
||||
old_ov = original_overflow.get(slide_key, {}).get(shape_key, 0.0)
|
||||
if new_ov > old_ov + 0.01:
|
||||
overflow_errors.append(
|
||||
f'{slide_key}/{shape_key}: overflow increased by {new_ov - old_ov:.2f}" '
|
||||
f'(was {old_ov:.2f}", now {new_ov:.2f}")'
|
||||
)
|
||||
|
||||
if overflow_errors or warnings:
|
||||
print("\nWARNING: Issues in replacement output:")
|
||||
for e in overflow_errors:
|
||||
print(f" overflow - {e}")
|
||||
for w in warnings:
|
||||
print(f" warning - {w}")
|
||||
|
||||
prs.save(output_file)
|
||||
print(f"Saved: {output_file}")
|
||||
print(f" Shapes cleared: {shapes_cleared}, replaced: {shapes_replaced}")
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 4:
|
||||
print(__doc__)
|
||||
sys.exit(1)
|
||||
|
||||
input_pptx, replacements_json, output_pptx = (
|
||||
Path(sys.argv[1]), Path(sys.argv[2]), Path(sys.argv[3])
|
||||
)
|
||||
for p in (input_pptx, replacements_json):
|
||||
if not p.exists():
|
||||
print(f"Error: File not found: {p}")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
apply_replacements(str(input_pptx), str(replacements_json), str(output_pptx))
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"Error: {e}")
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
BIN
skills/ppt/scripts/tectonic
Executable file
BIN
skills/ppt/scripts/tectonic
Executable file
Binary file not shown.
352
skills/ppt/scripts/thumbnail.py
Executable file
352
skills/ppt/scripts/thumbnail.py
Executable file
@@ -0,0 +1,352 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Create thumbnail grids from PowerPoint presentation slides.
|
||||
|
||||
Creates a grid layout of slide thumbnails with configurable columns (max 6).
|
||||
Each grid contains up to cols×(cols+1) images. For presentations with more
|
||||
slides, multiple numbered grid files are created automatically.
|
||||
|
||||
The program outputs the names of all files created.
|
||||
|
||||
Output:
|
||||
- Single grid: {prefix}.jpg (if slides fit in one grid)
|
||||
- Multiple grids: {prefix}-1.jpg, {prefix}-2.jpg, etc.
|
||||
|
||||
Grid limits by column count:
|
||||
- 3 cols: max 12 slides per grid (3×4)
|
||||
- 4 cols: max 20 slides per grid (4×5)
|
||||
- 5 cols: max 30 slides per grid (5×6) [default]
|
||||
- 6 cols: max 42 slides per grid (6×7)
|
||||
|
||||
Usage:
|
||||
python thumbnail.py input.pptx [output_prefix] [--cols N] [--outline-placeholders]
|
||||
|
||||
Examples:
|
||||
python thumbnail.py presentation.pptx
|
||||
# Creates: thumbnails.jpg (using default prefix)
|
||||
# Outputs:
|
||||
# Created 1 grid(s):
|
||||
# - thumbnails.jpg
|
||||
|
||||
python thumbnail.py large-deck.pptx grid --cols 4
|
||||
# Creates: grid-1.jpg, grid-2.jpg, grid-3.jpg
|
||||
# Outputs:
|
||||
# Created 3 grid(s):
|
||||
# - grid-1.jpg
|
||||
# - grid-2.jpg
|
||||
# - grid-3.jpg
|
||||
|
||||
python thumbnail.py template.pptx analysis --outline-placeholders
|
||||
# Creates thumbnail grids with red outlines around text placeholders
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
from inventory import extract_text_inventory
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from pptx import Presentation
|
||||
|
||||
# Constants
|
||||
THUMBNAIL_WIDTH = 300 # Fixed thumbnail width in pixels
|
||||
CONVERSION_DPI = 100 # DPI for PDF to image conversion
|
||||
MAX_COLS = 6 # Maximum number of columns
|
||||
DEFAULT_COLS = 5 # Default number of columns
|
||||
JPEG_QUALITY = 95 # JPEG compression quality
|
||||
|
||||
# Grid layout constants
|
||||
GRID_PADDING = 20 # Padding between thumbnails
|
||||
BORDER_WIDTH = 2 # Border width around thumbnails
|
||||
FONT_SIZE_RATIO = 0.12 # Font size as fraction of thumbnail width
|
||||
LABEL_PADDING_RATIO = 0.4 # Label padding as fraction of font size
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Create thumbnail grids from PowerPoint slides."
|
||||
)
|
||||
parser.add_argument("input", help="Input PowerPoint file (.pptx)")
|
||||
parser.add_argument(
|
||||
"output_prefix",
|
||||
nargs="?",
|
||||
default="thumbnails",
|
||||
help="Output prefix for image files (default: thumbnails, will create prefix.jpg or prefix-N.jpg)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--cols",
|
||||
type=int,
|
||||
default=DEFAULT_COLS,
|
||||
help=f"Number of columns (default: {DEFAULT_COLS}, max: {MAX_COLS})",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--outline-placeholders",
|
||||
action="store_true",
|
||||
help="Outline text placeholders with a colored border",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
cols = min(args.cols, MAX_COLS)
|
||||
if args.cols > MAX_COLS:
|
||||
print(f"Warning: Columns limited to {MAX_COLS} (requested {args.cols})")
|
||||
|
||||
input_path = Path(args.input)
|
||||
if not input_path.is_file() or input_path.suffix.lower() != ".pptx":
|
||||
sys.exit(f"Error: Invalid PowerPoint file: {args.input}")
|
||||
|
||||
output_path = Path(f"{args.output_prefix}.jpg")
|
||||
print(f"Processing: {args.input}")
|
||||
|
||||
try:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
|
||||
placeholder_regions = None
|
||||
slide_dimensions = None
|
||||
if args.outline_placeholders:
|
||||
print("Extracting placeholder regions...")
|
||||
placeholder_regions, slide_dimensions = get_placeholder_regions(input_path)
|
||||
if placeholder_regions:
|
||||
print(f"Found placeholders on {len(placeholder_regions)} slides")
|
||||
|
||||
prs = Presentation(str(input_path))
|
||||
total_slides = len(prs.slides)
|
||||
hidden_slides = {
|
||||
idx + 1
|
||||
for idx, slide in enumerate(prs.slides)
|
||||
if slide.element.get("show") == "0"
|
||||
}
|
||||
|
||||
hidden_info = f" ({len(hidden_slides)} hidden)" if hidden_slides else ""
|
||||
print(f"Found {total_slides} slides{hidden_info}")
|
||||
|
||||
slide_images = convert_to_images(input_path, temp_path, CONVERSION_DPI, total_slides, hidden_slides)
|
||||
if not slide_images:
|
||||
sys.exit("Error: No slides found")
|
||||
|
||||
grid_files = create_grids(
|
||||
slide_images, cols, THUMBNAIL_WIDTH, output_path,
|
||||
placeholder_regions, slide_dimensions,
|
||||
)
|
||||
|
||||
print(f"Created {len(grid_files)} grid(s):")
|
||||
for grid_file in grid_files:
|
||||
print(f" - {grid_file}")
|
||||
|
||||
except RuntimeError as e:
|
||||
sys.exit(f"Error: {e}")
|
||||
|
||||
|
||||
def create_hidden_slide_placeholder(size):
|
||||
"""Create placeholder image for hidden slides."""
|
||||
img = Image.new("RGB", size, color="#F0F0F0")
|
||||
draw = ImageDraw.Draw(img)
|
||||
line_width = max(5, min(size) // 100)
|
||||
draw.line([(0, 0), size], fill="#CCCCCC", width=line_width)
|
||||
draw.line([(size[0], 0), (0, size[1])], fill="#CCCCCC", width=line_width)
|
||||
return img
|
||||
|
||||
|
||||
def get_placeholder_regions(pptx_path):
|
||||
"""Extract ALL text regions from the presentation.
|
||||
|
||||
Returns a tuple of (placeholder_regions, slide_dimensions).
|
||||
text_regions is a dict mapping slide indices to lists of text regions.
|
||||
Each region is a dict with 'left', 'top', 'width', 'height' in inches.
|
||||
slide_dimensions is a tuple of (width_inches, height_inches).
|
||||
"""
|
||||
prs = Presentation(str(pptx_path))
|
||||
inventory = extract_text_inventory(pptx_path, prs)
|
||||
placeholder_regions = {}
|
||||
|
||||
slide_width_inches = (prs.slide_width or 9144000) / 914400.0
|
||||
slide_height_inches = (prs.slide_height or 5143500) / 914400.0
|
||||
|
||||
for slide_key, shapes in inventory.items():
|
||||
slide_idx = int(slide_key.split("-")[1])
|
||||
regions = [
|
||||
{"left": s.left, "top": s.top, "width": s.width, "height": s.height}
|
||||
for s in shapes.values()
|
||||
]
|
||||
if regions:
|
||||
placeholder_regions[slide_idx] = regions
|
||||
|
||||
return placeholder_regions, (slide_width_inches, slide_height_inches)
|
||||
|
||||
|
||||
def _pptx_to_pdf(pptx_path, temp_dir):
|
||||
"""Convert PPTX to PDF via LibreOffice. Returns path to the PDF file."""
|
||||
pdf_path = temp_dir / f"{pptx_path.stem}.pdf"
|
||||
result = subprocess.run(
|
||||
["soffice", "--headless", "--convert-to", "pdf", "--outdir", str(temp_dir), str(pptx_path)],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if result.returncode != 0 or not pdf_path.exists():
|
||||
raise RuntimeError("PDF conversion failed")
|
||||
return pdf_path
|
||||
|
||||
|
||||
def _pdf_to_images(pdf_path, temp_dir, dpi):
|
||||
"""Convert PDF pages to JPEG images via pdftoppm. Returns sorted image paths."""
|
||||
result = subprocess.run(
|
||||
["pdftoppm", "-jpeg", "-r", str(dpi), str(pdf_path), str(temp_dir / "slide")],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError("Image conversion failed")
|
||||
return sorted(temp_dir.glob("slide-*.jpg"))
|
||||
|
||||
|
||||
def convert_to_images(pptx_path, temp_dir, dpi, total_slides, hidden_slides):
|
||||
"""Convert PowerPoint to images via PDF, inserting placeholders for hidden slides."""
|
||||
pdf_path = _pptx_to_pdf(pptx_path, temp_dir)
|
||||
visible_images = _pdf_to_images(pdf_path, temp_dir, dpi)
|
||||
|
||||
if not visible_images:
|
||||
return []
|
||||
|
||||
with Image.open(visible_images[0]) as img:
|
||||
placeholder_size = img.size
|
||||
|
||||
all_images = []
|
||||
visible_idx = 0
|
||||
for slide_num in range(1, total_slides + 1):
|
||||
if slide_num in hidden_slides:
|
||||
placeholder_path = temp_dir / f"hidden-{slide_num:03d}.jpg"
|
||||
create_hidden_slide_placeholder(placeholder_size).save(placeholder_path, "JPEG")
|
||||
all_images.append(placeholder_path)
|
||||
else:
|
||||
if visible_idx < len(visible_images):
|
||||
all_images.append(visible_images[visible_idx])
|
||||
visible_idx += 1
|
||||
|
||||
return all_images
|
||||
|
||||
|
||||
def create_grids(
|
||||
image_paths,
|
||||
cols,
|
||||
width,
|
||||
output_path,
|
||||
placeholder_regions=None,
|
||||
slide_dimensions=None,
|
||||
):
|
||||
"""Create multiple thumbnail grids from slide images, max cols×(cols+1) images per grid."""
|
||||
max_images_per_grid = cols * (cols + 1)
|
||||
grid_files = []
|
||||
total_images = len(image_paths)
|
||||
|
||||
for chunk_idx, start_idx in enumerate(range(0, total_images, max_images_per_grid)):
|
||||
chunk_images = image_paths[start_idx: start_idx + max_images_per_grid]
|
||||
|
||||
grid = create_grid(chunk_images, cols, width, start_idx, placeholder_regions, slide_dimensions)
|
||||
|
||||
if total_images <= max_images_per_grid:
|
||||
grid_filename = output_path
|
||||
else:
|
||||
grid_filename = output_path.parent / f"{output_path.stem}-{chunk_idx + 1}{output_path.suffix}"
|
||||
|
||||
grid_filename.parent.mkdir(parents=True, exist_ok=True)
|
||||
grid.save(str(grid_filename), quality=JPEG_QUALITY)
|
||||
grid_files.append(str(grid_filename))
|
||||
|
||||
return grid_files
|
||||
|
||||
|
||||
def create_grid(
|
||||
image_paths,
|
||||
cols,
|
||||
width,
|
||||
start_slide_num=0,
|
||||
placeholder_regions=None,
|
||||
slide_dimensions=None,
|
||||
):
|
||||
"""Create thumbnail grid from slide images with optional placeholder outlining."""
|
||||
font_size = int(width * FONT_SIZE_RATIO)
|
||||
label_padding = int(font_size * LABEL_PADDING_RATIO)
|
||||
|
||||
with Image.open(image_paths[0]) as img:
|
||||
aspect = img.height / img.width
|
||||
height = int(width * aspect)
|
||||
|
||||
rows = (len(image_paths) + cols - 1) // cols
|
||||
grid_w = cols * width + (cols + 1) * GRID_PADDING
|
||||
grid_h = rows * (height + font_size + label_padding * 2) + (rows + 1) * GRID_PADDING
|
||||
|
||||
grid = Image.new("RGB", (grid_w, grid_h), "white")
|
||||
draw = ImageDraw.Draw(grid)
|
||||
|
||||
try:
|
||||
font = ImageFont.load_default(size=font_size)
|
||||
except Exception:
|
||||
font = ImageFont.load_default()
|
||||
|
||||
for i, img_path in enumerate(image_paths):
|
||||
row, col = i // cols, i % cols
|
||||
x = col * width + (col + 1) * GRID_PADDING
|
||||
y_base = row * (height + font_size + label_padding * 2) + (row + 1) * GRID_PADDING
|
||||
|
||||
label = f"{start_slide_num + i}"
|
||||
bbox = draw.textbbox((0, 0), label, font=font)
|
||||
text_w = bbox[2] - bbox[0]
|
||||
draw.text((x + (width - text_w) // 2, y_base + label_padding), label, fill="black", font=font)
|
||||
|
||||
y_thumbnail = y_base + label_padding + font_size + label_padding
|
||||
|
||||
with Image.open(img_path) as img:
|
||||
orig_w, orig_h = img.size
|
||||
|
||||
if placeholder_regions and (start_slide_num + i) in placeholder_regions:
|
||||
if img.mode != "RGBA":
|
||||
img = img.convert("RGBA")
|
||||
|
||||
regions = placeholder_regions[start_slide_num + i]
|
||||
if slide_dimensions:
|
||||
slide_w_in, slide_h_in = slide_dimensions
|
||||
else:
|
||||
slide_w_in = orig_w / CONVERSION_DPI
|
||||
slide_h_in = orig_h / CONVERSION_DPI
|
||||
|
||||
x_scale = orig_w / slide_w_in
|
||||
y_scale = orig_h / slide_h_in
|
||||
|
||||
overlay = Image.new("RGBA", img.size, (255, 255, 255, 0))
|
||||
overlay_draw = ImageDraw.Draw(overlay)
|
||||
stroke_width = max(5, min(orig_w, orig_h) // 150)
|
||||
|
||||
for region in regions:
|
||||
px_left = int(region["left"] * x_scale)
|
||||
px_top = int(region["top"] * y_scale)
|
||||
px_right = px_left + int(region["width"] * x_scale)
|
||||
px_bottom = px_top + int(region["height"] * y_scale)
|
||||
overlay_draw.rectangle(
|
||||
[(px_left, px_top), (px_right, px_bottom)],
|
||||
outline=(255, 0, 0, 255),
|
||||
width=stroke_width,
|
||||
)
|
||||
|
||||
img = Image.alpha_composite(img, overlay).convert("RGB")
|
||||
|
||||
img.thumbnail((width, height), Image.Resampling.LANCZOS)
|
||||
w, h = img.size
|
||||
tx = x + (width - w) // 2
|
||||
ty = y_thumbnail + (height - h) // 2
|
||||
grid.paste(img, (tx, ty))
|
||||
|
||||
if BORDER_WIDTH > 0:
|
||||
draw.rectangle(
|
||||
[(tx - BORDER_WIDTH, ty - BORDER_WIDTH), (tx + w + BORDER_WIDTH - 1, ty + h + BORDER_WIDTH - 1)],
|
||||
outline="gray",
|
||||
width=BORDER_WIDTH,
|
||||
)
|
||||
|
||||
return grid
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
197
skills/ppt/setup.sh
Executable file
197
skills/ppt/setup.sh
Executable file
@@ -0,0 +1,197 @@
|
||||
#!/usr/bin/env bash
|
||||
# ---
|
||||
# name: ppt-setup
|
||||
# author: Z.AI
|
||||
# version: "1.0"
|
||||
# description: Environment setup for the PPT skill. Checks and installs all required dependencies.
|
||||
# ---
|
||||
#
|
||||
# Installs only dependencies required by the PPT skill.
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
|
||||
ok() { echo -e " ${GREEN}✓${NC} $1"; }
|
||||
fail() { echo -e " ${RED}✗${NC} $1"; }
|
||||
warn() { echo -e " ${YELLOW}○${NC} $1"; }
|
||||
info() { echo -e " ${BLUE}→${NC} $1"; }
|
||||
|
||||
echo "============================================"
|
||||
echo " PPT Skill — Environment Setup"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
|
||||
OS="$(uname -s)"
|
||||
ARCH="$(uname -m)"
|
||||
echo "Platform: $OS $ARCH"
|
||||
echo ""
|
||||
|
||||
# ── 0. macOS: Homebrew ──
|
||||
if [ "$OS" = "Darwin" ]; then
|
||||
echo "--- Homebrew (macOS package manager) ---"
|
||||
if command -v brew &>/dev/null; then
|
||||
BREW_VER=$(brew --version 2>/dev/null | head -1)
|
||||
ok "brew ($BREW_VER)"
|
||||
else
|
||||
fail "brew not found — Node.js install needs Homebrew on macOS"
|
||||
info "Install: /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# ── 1. Node.js (PptxGenJS runs on Node) ──
|
||||
echo "--- Node.js ---"
|
||||
if command -v node &>/dev/null; then
|
||||
NODE_VER=$(node --version)
|
||||
ok "node ($NODE_VER)"
|
||||
else
|
||||
fail "node not found (required — PPTX generation uses PptxGenJS on Node)"
|
||||
case "$OS" in
|
||||
Darwin) info "Install: brew install node" ;;
|
||||
Linux) info "Install: curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -"
|
||||
info " sudo apt install -y nodejs" ;;
|
||||
*) info "Install: https://nodejs.org/" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# ── 2. npm ──
|
||||
echo ""
|
||||
echo "--- npm ---"
|
||||
if command -v npm &>/dev/null; then
|
||||
NPM_VER=$(npm --version 2>/dev/null)
|
||||
ok "npm ($NPM_VER)"
|
||||
else
|
||||
fail "npm not found"
|
||||
case "$OS" in
|
||||
Darwin) info "Install: brew install node (includes npm)" ;;
|
||||
Linux) info "Install: comes with nodejs" ;;
|
||||
*) info "Install: https://nodejs.org/" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# ── 3. npm package: pptxgenjs ──
|
||||
echo ""
|
||||
echo "--- npm Packages ---"
|
||||
if node -e "require('pptxgenjs')" 2>/dev/null || npm list -g pptxgenjs &>/dev/null; then
|
||||
PPTX_VER=$(node -e "try{console.log(require('pptxgenjs/package.json').version)}catch(e){console.log('installed')}" 2>/dev/null)
|
||||
ok "pptxgenjs ($PPTX_VER)"
|
||||
else
|
||||
fail "pptxgenjs not installed"
|
||||
info "Install: npm install -g pptxgenjs"
|
||||
echo ""
|
||||
if [ -t 0 ]; then
|
||||
read -p " Install now? [Y/n] " -n 1 -r REPLY
|
||||
echo ""
|
||||
REPLY=${REPLY:-Y}
|
||||
else
|
||||
warn "Non-interactive mode — skipping auto-install."
|
||||
REPLY=N
|
||||
fi
|
||||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||||
npm install -g pptxgenjs 2>/dev/null && ok "Installed: pptxgenjs" || fail "npm install failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── 4. Python 3 (OOXML validation scripts) ──
|
||||
echo ""
|
||||
echo "--- Python (OOXML validation) ---"
|
||||
if command -v python3 &>/dev/null; then
|
||||
PY_VER=$(python3 --version 2>&1)
|
||||
ok "python3 ($PY_VER)"
|
||||
if [ "$OS" = "Darwin" ]; then
|
||||
PY_PATH=$(which python3 2>/dev/null)
|
||||
if [[ "$PY_PATH" == "/usr/bin/python3" ]]; then
|
||||
warn "Using macOS system Python (limited). Recommend: brew install python3"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
fail "python3 not found"
|
||||
case "$OS" in
|
||||
Darwin) info "Install: brew install python3" ;;
|
||||
Linux) info "Install: sudo apt install python3 python3-pip (Debian/Ubuntu)"
|
||||
info " sudo dnf install python3 python3-pip (Fedora/RHEL)" ;;
|
||||
*) info "Install: https://www.python.org/downloads/" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# ── 5. pip ──
|
||||
echo ""
|
||||
echo "--- pip ---"
|
||||
if python3 -m pip --version &>/dev/null 2>&1; then
|
||||
PIP_VER=$(python3 -m pip --version 2>/dev/null | head -1)
|
||||
ok "pip ($PIP_VER)"
|
||||
else
|
||||
fail "pip not found"
|
||||
case "$OS" in
|
||||
Darwin) info "Install: python3 -m ensurepip --upgrade"
|
||||
info " or: brew install python3 (includes pip)" ;;
|
||||
Linux) info "Install: sudo apt install python3-pip (Debian/Ubuntu)" ;;
|
||||
*) info "Install: python3 -m ensurepip --upgrade" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# ── 6. Python packages ──
|
||||
echo ""
|
||||
echo "--- Python Packages ---"
|
||||
PY_PKGS=(
|
||||
"lxml:lxml"
|
||||
"defusedxml:defusedxml"
|
||||
)
|
||||
|
||||
MISSING_PY=()
|
||||
for entry in "${PY_PKGS[@]}"; do
|
||||
mod="${entry%%:*}"
|
||||
pkg="${entry##*:}"
|
||||
if python3 -c "import $mod" 2>/dev/null; then
|
||||
ver=$(python3 -c "import $mod; print(getattr($mod, '__version__', 'installed'))" 2>/dev/null)
|
||||
ok "$pkg ($ver)"
|
||||
else
|
||||
fail "$pkg not installed"
|
||||
MISSING_PY+=("$pkg")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#MISSING_PY[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
if [ -t 0 ]; then
|
||||
read -p " Install missing Python packages? [Y/n] " -n 1 -r REPLY
|
||||
echo ""
|
||||
REPLY=${REPLY:-Y}
|
||||
else
|
||||
warn "Non-interactive mode — skipping auto-install. Run interactively or install manually."
|
||||
REPLY=N
|
||||
fi
|
||||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||||
python3 -m pip install -q "${MISSING_PY[@]}" 2>/dev/null \
|
||||
|| python3 -m pip install -q --user "${MISSING_PY[@]}" 2>/dev/null \
|
||||
|| python3 -m pip install -q --break-system-packages "${MISSING_PY[@]}" 2>/dev/null \
|
||||
|| { fail "pip install failed. Try manually: pip install ${MISSING_PY[*]}"; }
|
||||
ok "Installed: ${MISSING_PY[*]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── 7. Tectonic (optional, for Beamer/LaTeX slides) ──
|
||||
echo ""
|
||||
echo "--- Tectonic (optional, Beamer slides only) ---"
|
||||
if command -v tectonic &>/dev/null; then
|
||||
TEC_VER=$(tectonic --version 2>&1 | head -1)
|
||||
ok "tectonic ($TEC_VER)"
|
||||
elif [ -x "$HOME/tectonic" ]; then
|
||||
ok "tectonic (~/tectonic)"
|
||||
else
|
||||
warn "tectonic not installed (needed only for Beamer/LaTeX slide PDFs)"
|
||||
case "$OS" in
|
||||
Darwin) info "Install: brew install tectonic" ;;
|
||||
Linux) info "Install: conda install -c conda-forge tectonic"
|
||||
info " or: curl -fsSL https://drop-sh.fullyjustified.net | sh" ;;
|
||||
MINGW*|MSYS*|CYGWIN*) info "Install: scoop install tectonic" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# ── Summary ──
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " Setup complete."
|
||||
echo " Core: Node.js + pptxgenjs"
|
||||
echo " Validation: Python + lxml + defusedxml"
|
||||
echo " Beamer slides: tectonic (optional)"
|
||||
echo "============================================"
|
||||
581
skills/ppt/themes.md
Executable file
581
skills/ppt/themes.md
Executable file
@@ -0,0 +1,581 @@
|
||||
# Themes — Preset Theme Configuration
|
||||
|
||||
Each theme = a set of colors + a set of fonts + mood tags. Once a theme is selected, all colors are automatically derived according to the color scale rules in `design-system.md`.
|
||||
|
||||
---
|
||||
|
||||
## Theme Selection Rules
|
||||
|
||||
1. AI selects the theme based on scene classification and content tone
|
||||
2. Each PPT deck uses only one theme, **no switching throughout**
|
||||
3. If the user specifies a color or style preference, select the closest theme or customize accordingly (still must follow color scale rules)
|
||||
|
||||
---
|
||||
|
||||
## Preset Themes
|
||||
|
||||
### 1. Ocean (Deep Sea Blue)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Professional, trustworthy |
|
||||
| **Suitable for** | Work reports, business proposals, company introductions |
|
||||
| **Primary** | `#1B2A4A` |
|
||||
| **Accent (A — default)** | `#2A9D8F` (teal) |
|
||||
| **Accent B** | `#D7A460` (warm gold) |
|
||||
| **Accent C** | `#6C92E0` (bright blue) |
|
||||
| **CJK Title Font** | Microsoft YaHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Gill Sans MT Bold |
|
||||
| **Latin Body Font** | Gill Sans MT |
|
||||
| **Image Keywords** | ocean, deep blue, corporate, skyline, technology, water, aerial city |
|
||||
| **Mask Color** | `rgba(18,32,64,0.75)` (primary-90 based) |
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value | Usage Example |
|
||||
|------|------|---------|
|
||||
| primary-100 | `#0D1525` | Dark mode background |
|
||||
| primary-90 | `#122040` | Title bar background |
|
||||
| primary-80 | `#1B2A4A` | Title text |
|
||||
| primary-60 | `#3D5A80` | Subtitle / icons |
|
||||
| primary-40 | `#6B8AB0` | Secondary text |
|
||||
| primary-20 | `#B0C4DE` | Light decoration |
|
||||
| primary-10 | `#DFE8F2` | Card background / border |
|
||||
| primary-5 | `#F0F4F8` | Surface base color |
|
||||
|
||||
---
|
||||
|
||||
### 2. Graphite (Graphite Gray)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Modern, restrained, clean and sharp |
|
||||
| **Suitable for** | Tech products, weekly/monthly reports, technical sharing |
|
||||
| **Primary** | `#2D3436` |
|
||||
| **Accent (A — default)** | `#D77860` (coral red) |
|
||||
| **Accent B** | `#6BCB77` (emerald green) |
|
||||
| **Accent C** | `#9B8EC4` (light purple) |
|
||||
| **CJK Title Font** | SimHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Century Gothic Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | architecture, minimal, concrete, technology, geometric, monochrome, server room |
|
||||
| **Mask Color** | `rgba(34,40,41,0.75)` (primary-90 based) |
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value |
|
||||
|------|------|
|
||||
| primary-100 | `#161A1B` |
|
||||
| primary-90 | `#222829` |
|
||||
| primary-80 | `#2D3436` |
|
||||
| primary-60 | `#576163` |
|
||||
| primary-40 | `#8D9496` |
|
||||
| primary-20 | `#C3C8CA` |
|
||||
| primary-10 | `#E4E7E8` |
|
||||
| primary-5 | `#F3F4F5` |
|
||||
|
||||
---
|
||||
|
||||
### 3. Forest (Forest Green)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Natural, serene, organic and gentle |
|
||||
| **Suitable for** | Educational courseware, humanities/liberal arts academic, ESG/sustainability |
|
||||
| **Primary** | `#1B4332` |
|
||||
| **Accent (A — default)** | `#DCBD74` (golden) |
|
||||
| **Accent B** | `#E18C70` (coral) |
|
||||
| **Accent C** | `#7EC8B0` (mint) |
|
||||
| **CJK Title Font** | SimSun Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Palatino Linotype Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | forest, nature, leaves, green, organic, sustainability, botanical, meadow |
|
||||
| **Mask Color** | `rgba(18,45,31,0.75)` (primary-90 based) |
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value |
|
||||
|------|------|
|
||||
| primary-100 | `#0B1E14` |
|
||||
| primary-90 | `#122D1F` |
|
||||
| primary-80 | `#1B4332` |
|
||||
| primary-60 | `#2E6B4F` |
|
||||
| primary-40 | `#60A882` |
|
||||
| primary-20 | `#A8D4BC` |
|
||||
| primary-10 | `#D8EEE2` |
|
||||
| primary-5 | `#EEF7F1` |
|
||||
|
||||
---
|
||||
|
||||
### 4. Twilight (Dark Night Purple)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Creative, unique, personality-driven |
|
||||
| **Suitable for** | Creative proposals, brand planning, design sharing |
|
||||
| **Primary** | `#2D2B55` |
|
||||
| **Accent (A — default)** | `#9B50F5` (electric purple) |
|
||||
| **Accent B** | `#E3B27D` (warm orange) |
|
||||
| **Accent C** | `#5EC4D4` (sky blue) |
|
||||
| **CJK Title Font** | Microsoft YaHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Candara Bold |
|
||||
| **Latin Body Font** | Candara |
|
||||
| **Image Keywords** | galaxy, night sky, aurora, creative, neon, abstract art, purple gradient |
|
||||
| **Mask Color** | `rgba(33,31,64,0.75)` (primary-90 based) |
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value |
|
||||
|------|------|
|
||||
| primary-100 | `#15142A` |
|
||||
| primary-90 | `#211F40` |
|
||||
| primary-80 | `#2D2B55` |
|
||||
| primary-60 | `#555380` |
|
||||
| primary-40 | `#8886AB` |
|
||||
| primary-20 | `#BFBED6` |
|
||||
| primary-10 | `#E2E1ED` |
|
||||
| primary-5 | `#F2F2F7` |
|
||||
|
||||
---
|
||||
|
||||
### 5. Sandstone (Warm Sand)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Premium, warm, composed and grand |
|
||||
| **Suitable for** | Investment roadshows, real estate, luxury goods, finance |
|
||||
| **Primary** | `#3C2415` |
|
||||
| **Accent (A — default)** | `#C09E30` (gold) |
|
||||
| **Accent B** | `#D4766A` (ochre red) |
|
||||
| **Accent C** | `#8BB174` (olive) |
|
||||
| **CJK Title Font** | SimSun Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Palatino Linotype Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | luxury, gold, marble, architecture, warm light, classical, elegant interior |
|
||||
| **Mask Color** | `rgba(45,27,16,0.75)` (primary-90 based) |
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value |
|
||||
|------|------|
|
||||
| primary-100 | `#1E120A` |
|
||||
| primary-90 | `#2D1B10` |
|
||||
| primary-80 | `#3C2415` |
|
||||
| primary-60 | `#6B5443` |
|
||||
| primary-40 | `#9E8A7A` |
|
||||
| primary-20 | `#CEBFB5` |
|
||||
| primary-10 | `#E9E2DC` |
|
||||
| primary-5 | `#F5F2F0` |
|
||||
|
||||
---
|
||||
|
||||
### 6. Mono (Minimalist Black)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Sharp, minimalist, visual impact |
|
||||
| **Suitable for** | Product launches, minimalist style, photography showcases |
|
||||
| **Primary** | `#1A1A1A` |
|
||||
| **Accent (A — default)** | `#E6754C` (burnt orange) |
|
||||
| **Accent B** | `#4ECDC4` (cyan) |
|
||||
| **Accent C** | `#C44569` (rose) |
|
||||
| **CJK Title Font** | Microsoft YaHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Arial Bold |
|
||||
| **Latin Body Font** | Arial |
|
||||
| **Image Keywords** | minimal, black white, contrast, product, clean, abstract, studio lighting |
|
||||
| **Mask Color** | `rgba(20,20,20,0.75)` (primary-90 based) |
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value |
|
||||
|------|------|
|
||||
| primary-100 | `#0A0A0A` |
|
||||
| primary-90 | `#141414` |
|
||||
| primary-80 | `#1A1A1A` |
|
||||
| primary-60 | `#4A4A4A` |
|
||||
| primary-40 | `#808080` |
|
||||
| primary-20 | `#B8B8B8` |
|
||||
| primary-10 | `#E0E0E0` |
|
||||
| primary-5 | `#F2F2F2` |
|
||||
|
||||
---
|
||||
|
||||
### 7. Deep Mineral (Dark Night Blue)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | High-end, immersive, cinematic depth |
|
||||
| **Suitable for** | Tech launches, keynotes, data dashboards, night-mode presentations |
|
||||
| **Primary** | `#FFFFFF` |
|
||||
| **Accent (A — default)** | `#44D1E4` (electric cyan) |
|
||||
| **Accent B** | `#EDCD82` (warm yellow) |
|
||||
| **Accent C** | `#E65174` (rose) |
|
||||
| **Background Override** | `#162235` (replaces default `#FFFFFF`) |
|
||||
| **CJK Title Font** | Microsoft YaHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Trebuchet MS Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | dark blue, night city, deep ocean, space, data visualization, neon glow |
|
||||
| **Mask Color** | `rgba(16,26,40,0.70)` (primary-100 based) |
|
||||
|
||||
**Dark theme notes**: This is a dark-background theme — the color logic is inverted:
|
||||
- `background` = `#162235` (dark), `surface` = `#1E2D45` (slightly lighter), `surface-card` = `#243550` (card layer)
|
||||
- `text-primary` = `#FFFFFF`, `text-secondary` = `rgba(255,255,255,0.75)`, `text-muted` = `rgba(255,255,255,0.45)`
|
||||
- Cards use `surface-card` with no shadow (shadows invisible on dark backgrounds)
|
||||
- Accent (`#44D1E4`) is used for highlights, KPI numbers, accent bars, and emphasis elements
|
||||
|
||||
Color Scale (inverted — lighter values are "darker" in visual weight):
|
||||
|
||||
| Scale | Color Value | Usage |
|
||||
|------|------|---------|
|
||||
| primary-100 | `#0D1525` | Deepest background |
|
||||
| primary-90 | `#122040` | Title bar background |
|
||||
| primary-80 | `#FFFFFF` | Title text / primary elements |
|
||||
| primary-60 | `rgba(255,255,255,0.75)` | Subtitle / secondary text |
|
||||
| primary-40 | `rgba(255,255,255,0.45)` | Muted text / annotations |
|
||||
| primary-20 | `#2A3F5F` | Card borders / subtle decorations |
|
||||
| primary-10 | `#1E2D45` | Surface / content area base |
|
||||
| primary-5 | `#162235` | Page background |
|
||||
|
||||
---
|
||||
|
||||
### 8. Warm Retro (Vintage Warmth)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Vintage, cultured, warm and grounded |
|
||||
| **Suitable for** | Cultural events, humanities, food/lifestyle, brand storytelling |
|
||||
| **Primary** | `#2A4A3A` |
|
||||
| **Accent (A — default)** | `#C89F62` (antique gold) |
|
||||
| **Accent B** | `#C06C58` (copper red) |
|
||||
| **Accent C** | `#7BA68C` (moss green) |
|
||||
| **Background Override** | `#F4F1E9` (warm off-white, replaces default `#FFFFFF`) |
|
||||
| **CJK Title Font** | SimSun Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Palatino Linotype Bold |
|
||||
| **Latin Body Font** | Garamond |
|
||||
| **Image Keywords** | vintage, warm light, craft, leather, coffee, botanical, old book, linen texture |
|
||||
| **Mask Color** | `rgba(30,40,34,0.75)` (primary-90 based) |
|
||||
|
||||
**Warm background notes**: This theme uses a warm off-white (`#F4F1E9`) instead of pure white:
|
||||
- `background` = `#F4F1E9`, `surface` = `#EDE9DF` (slightly darker warm), `surface-card` = `#FEFDFB` (near-white card)
|
||||
- The warm base gives a cozy, analog feel — avoid pure white elements that would look jarring
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value | Usage |
|
||||
|------|------|---------|
|
||||
| primary-100 | `#0F1C15` | Darkest (rarely used) |
|
||||
| primary-90 | `#1E2822` | Title bar background |
|
||||
| primary-80 | `#2A4A3A` | Title text / primary elements |
|
||||
| primary-60 | `#4A7A62` | Subtitle / icons |
|
||||
| primary-40 | `#7AAA90` | Secondary text |
|
||||
| primary-20 | `#B5D4C2` | Light decoration |
|
||||
| primary-10 | `#DCE9E0` | Card background / border |
|
||||
| primary-5 | `#F0F5F1` | Surface base (use `#EDE9DF` for warm surface) |
|
||||
|
||||
---
|
||||
|
||||
### 9. Deep Forest (Dark Green)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Calm, grounded, nature-tech fusion |
|
||||
| **Suitable for** | ESG reports, sustainability, ecology, green tech |
|
||||
| **Primary** | `#FFFFFF` |
|
||||
| **Accent (A — default)** | `#D7D968` (electric lime) |
|
||||
| **Accent B** | `#E18C70` (coral orange) |
|
||||
| **Accent C** | `#85C5E0` (sky blue) |
|
||||
| **Background Override** | `#193328` (deep forest green, replaces default `#FFFFFF`) |
|
||||
| **CJK Title Font** | Microsoft YaHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Gill Sans MT Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | dark forest, moss, fern, green nature, sustainability, eco technology, rain forest |
|
||||
| **Mask Color** | `rgba(18,38,30,0.70)` (primary-100 based) |
|
||||
|
||||
**Dark theme notes**: Same inverted logic as Deep Mineral — see its notes above.
|
||||
- `background` = `#193328`, `surface` = `#1F3F32`, `surface-card` = `#264A3C`
|
||||
- `text-primary` = `#FFFFFF`, `text-secondary` = `rgba(255,255,255,0.75)`, `text-muted` = `rgba(255,255,255,0.45)`
|
||||
|
||||
Color Scale (inverted):
|
||||
|
||||
| Scale | Color Value | Usage |
|
||||
|------|------|---------|
|
||||
| primary-100 | `#0D1A14` | Deepest background |
|
||||
| primary-90 | `#12261E` | Title bar background |
|
||||
| primary-80 | `#FFFFFF` | Title text / primary elements |
|
||||
| primary-60 | `rgba(255,255,255,0.75)` | Subtitle / secondary text |
|
||||
| primary-40 | `rgba(255,255,255,0.45)` | Muted text / annotations |
|
||||
| primary-20 | `#2A5040` | Card borders / subtle decorations |
|
||||
| primary-10 | `#1F3F32` | Surface / content area base |
|
||||
| primary-5 | `#193328` | Page background |
|
||||
|
||||
---
|
||||
|
||||
### 10. Coral (Coral Pink)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Warm, vibrant, youthful |
|
||||
| **Suitable for** | Brand marketing, consumer products, lifestyle, female-audience presentations |
|
||||
| **Primary** | `#8B3A4A` |
|
||||
| **Accent (A — default)** | `#E2A574` (warm peach) |
|
||||
| **Accent B** | `#DC755B` (burnt sienna) |
|
||||
| **Accent C** | `#6BC5B8` (mint contrast) |
|
||||
| **CJK Title Font** | Microsoft YaHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Candara Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | pink, flowers, beauty, lifestyle, warm light, cafe, fashion, soft texture |
|
||||
| **Mask Color** | `rgba(100,42,54,0.75)` (primary-90 based) |
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value | Usage |
|
||||
|------|------|---------|
|
||||
| primary-100 | `#3D1A22` | Deepest background |
|
||||
| primary-90 | `#642A36` | Title bar background |
|
||||
| primary-80 | `#8B3A4A` | Title text / primary elements |
|
||||
| primary-60 | `#B06070` | Subtitle / icons |
|
||||
| primary-40 | `#D08A96` | Secondary text |
|
||||
| primary-20 | `#E8BAC2` | Light decoration |
|
||||
| primary-10 | `#F3DDE1` | Card background / border |
|
||||
| primary-5 | `#FAF0F2` | Surface base color |
|
||||
|
||||
---
|
||||
|
||||
### 11. Mint (Mint Green)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Fresh, clean, health-oriented |
|
||||
| **Suitable for** | Healthcare, wellness, eco-friendly, food & beverage |
|
||||
| **Primary** | `#1A6B5A` |
|
||||
| **Accent (A — default)** | `#E3987D` (warm coral) |
|
||||
| **Accent B** | `#DEC363` (golden yellow) |
|
||||
| **Accent C** | `#8574E2` (medium slate blue) |
|
||||
| **CJK Title Font** | Microsoft YaHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Gill Sans MT Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | mint, fresh, health, botanical, clean, green smoothie, spa, herbal |
|
||||
| **Mask Color** | `rgba(18,78,64,0.75)` (primary-90 based) |
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value | Usage |
|
||||
|------|------|---------|
|
||||
| primary-100 | `#0A3028` | Deepest background |
|
||||
| primary-90 | `#124E40` | Title bar background |
|
||||
| primary-80 | `#1A6B5A` | Title text / primary elements |
|
||||
| primary-60 | `#3D9B86` | Subtitle / icons |
|
||||
| primary-40 | `#6DBFAB` | Secondary text |
|
||||
| primary-20 | `#A8DACE` | Light decoration |
|
||||
| primary-10 | `#D6EDE7` | Card background / border |
|
||||
| primary-5 | `#EFF8F5` | Surface base color |
|
||||
|
||||
---
|
||||
|
||||
### 12. Azure (Sky Blue)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Open, lightweight, approachable technology |
|
||||
| **Suitable for** | SaaS products, AI/tech, onboarding, training materials |
|
||||
| **Primary** | `#1E5F8C` |
|
||||
| **Accent (A — default)** | `#FF6B2B` (electric orange) |
|
||||
| **Accent B** | `#DD5F5F` (red) |
|
||||
| **Accent C** | `#9270E1` (violet) |
|
||||
| **CJK Title Font** | Microsoft YaHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Trebuchet MS Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | sky, cloud, technology, light blue, software, digital, clean interface |
|
||||
| **Mask Color** | `rgba(20,68,104,0.75)` (primary-90 based) |
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value | Usage |
|
||||
|------|------|---------|
|
||||
| primary-100 | `#0C2A40` | Deepest background |
|
||||
| primary-90 | `#144468` | Title bar background |
|
||||
| primary-80 | `#1E5F8C` | Title text / primary elements |
|
||||
| primary-60 | `#4085B0` | Subtitle / icons |
|
||||
| primary-40 | `#70AAD0` | Secondary text |
|
||||
| primary-20 | `#A8CEE5` | Light decoration |
|
||||
| primary-10 | `#D8E9F3` | Card background / border |
|
||||
| primary-5 | `#F0F6FA` | Surface base color |
|
||||
|
||||
---
|
||||
|
||||
### 13. Ember (Amber Red)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Bold, energetic, high-impact |
|
||||
| **Suitable for** | Annual events, product launches, sales campaigns, motivational presentations |
|
||||
| **Primary** | `#8B2500` |
|
||||
| **Accent (A — default)** | `#F04828` (fire orange) |
|
||||
| **Accent B** | `#2EC4B6` (teal contrast) |
|
||||
| **Accent C** | `#EC7979` (coral red) |
|
||||
| **CJK Title Font** | SimHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Arial Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | fire, red, energy, stage light, celebration, bold, dynamic, explosion |
|
||||
| **Mask Color** | `rgba(100,26,0,0.75)` (primary-90 based) |
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value | Usage |
|
||||
|------|------|---------|
|
||||
| primary-100 | `#3E1000` | Deepest background |
|
||||
| primary-90 | `#641A00` | Title bar background |
|
||||
| primary-80 | `#8B2500` | Title text / primary elements |
|
||||
| primary-60 | `#B85030` | Subtitle / icons |
|
||||
| primary-40 | `#D88060` | Secondary text |
|
||||
| primary-20 | `#EBB8A0` | Light decoration |
|
||||
| primary-10 | `#F5DCD0` | Card background / border |
|
||||
| primary-5 | `#FBF0EB` | Surface base color |
|
||||
|
||||
---
|
||||
|
||||
### 14. Volt (Electric / Startup Dark)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Electric, aggressive, high-energy |
|
||||
| **Suitable for** | AI/tech product launches, startup pitches, youth tech brands, digital innovation |
|
||||
| **Primary** | `#FFFFFF` |
|
||||
| **Accent (A — default)** | `#00F5A0` (electric mint-green) |
|
||||
| **Accent B** | `#FF5E3A` (electric orange) |
|
||||
| **Accent C** | `#A855F7` (electric purple) |
|
||||
| **Background Override** | `#080B14` (near-black with blue tint, replaces default `#FFFFFF`) |
|
||||
| **CJK Title Font** | Microsoft YaHei Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Trebuchet MS Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | neon, circuit board, futuristic, dark ui, electric glow, startup, code, data stream |
|
||||
| **Mask Color** | `rgba(5,7,16,0.70)` (primary-100 based) |
|
||||
|
||||
**Dark theme notes**: Same inverted logic as Deep Mineral — see its notes above.
|
||||
- `background` = `#080B14`, `surface` = `#0F1424`, `surface-card` = `#162033`
|
||||
- `text-primary` = `#FFFFFF`, `text-secondary` = `rgba(255,255,255,0.75)`, `text-muted` = `rgba(255,255,255,0.45)`
|
||||
- Accents are extremely vivid by design — use sparingly (bars, numbers, key labels only)
|
||||
|
||||
Color Scale (inverted):
|
||||
|
||||
| Scale | Color Value | Usage |
|
||||
|------|------|---------|
|
||||
| primary-100 | `#050710` | Deepest background |
|
||||
| primary-90 | `#0D1320` | Title bar background |
|
||||
| primary-80 | `#FFFFFF` | Title text / primary elements |
|
||||
| primary-60 | `rgba(255,255,255,0.75)` | Subtitle / secondary text |
|
||||
| primary-40 | `rgba(255,255,255,0.45)` | Muted text / annotations |
|
||||
| primary-20 | `#1E2E48` | Card borders / subtle decorations |
|
||||
| primary-10 | `#0F1424` | Surface / content area base |
|
||||
| primary-5 | `#080B14` | Page background |
|
||||
|
||||
---
|
||||
|
||||
### 15. Vermillion (Chinese Red)
|
||||
|
||||
| Property | Value |
|
||||
|------|-----|
|
||||
| **Mood** | Ceremonial, festive, culturally resonant |
|
||||
| **Suitable for** | Chinese cultural events, Spring Festival, traditional ceremonies, brand storytelling with Chinese aesthetics |
|
||||
| **Primary** | `#8B1A1A` |
|
||||
| **Accent (A — default)** | `#D4AF37` (Chinese gold) |
|
||||
| **Accent B** | `#C4762A` (copper bronze) |
|
||||
| **Accent C** | `#2D6B8A` (cool blue contrast) |
|
||||
| **Background Override** | `#FDF8F2` (warm rice-paper white, replaces default `#FFFFFF`) |
|
||||
| **CJK Title Font** | SimSun Bold |
|
||||
| **CJK Body Font** | Microsoft YaHei |
|
||||
| **Latin Title Font** | Palatino Linotype Bold |
|
||||
| **Latin Body Font** | Corbel |
|
||||
| **Image Keywords** | red lantern, Chinese architecture, traditional culture, festival, gold ornament, calligraphy, temple, Spring Festival |
|
||||
| **Mask Color** | `rgba(107,20,20,0.75)` (primary-90 based) |
|
||||
|
||||
**Warm background notes**: Uses warm rice-paper white `#FDF8F2` instead of pure white:
|
||||
- `background` = `#FDF8F2`, `surface` = `#F5EDE0` (warm tint), `surface-card` = `#FEFDFB` (near-white card)
|
||||
- Avoid pure white elements that would look jarring against the warm base
|
||||
|
||||
Color Scale:
|
||||
|
||||
| Scale | Color Value | Usage |
|
||||
|------|------|---------|
|
||||
| primary-100 | `#450D0D` | Deepest background / dramatic pages |
|
||||
| primary-90 | `#6B1414` | Title bar background |
|
||||
| primary-80 | `#8B1A1A` | Title text / primary elements |
|
||||
| primary-60 | `#B84040` | Subtitle / icons |
|
||||
| primary-40 | `#D57070` | Secondary text |
|
||||
| primary-20 | `#EDB0B0` | Light decoration |
|
||||
| primary-10 | `#F8E0E0` | Card background / border |
|
||||
| primary-5 | `#FDF4F4` | Surface base color |
|
||||
|
||||
---
|
||||
|
||||
## Custom Themes
|
||||
|
||||
If the user specifies a particular color, create a custom theme following these steps:
|
||||
|
||||
1. Use the user-specified color as `primary-80`
|
||||
2. Derive the full 8-level color scale according to the color scale generation rules in section 3.1 of `design-system.md`
|
||||
3. Select an Accent color with a hue difference of ≥ 30° from the Primary (to ensure visual distinction). Recommended range: 60°–180°. Provide 3 accent variants (A/B/C) for variety.
|
||||
4. Choose the most suitable font pairing from the presets, or use the user-specified fonts
|
||||
5. Record the complete configuration in comments within the generated code to ensure consistency across the entire PPT deck
|
||||
|
||||
## Font Pairing Notes
|
||||
|
||||
Each theme has **4 font roles**:
|
||||
|
||||
| Role | HTML font-family Syntax | Usage |
|
||||
|------|----------------------|------|
|
||||
| CJK Title | Write PPT font name directly: `font-family:'SimHei','Microsoft YaHei',sans-serif` | h1, h2, cover title |
|
||||
| CJK Body | Write PPT font name directly: `font-family:'Microsoft YaHei',sans-serif` | body, lists, annotations |
|
||||
| Latin Title | Write PPT font name directly: `font-family:'Century Gothic','Corbel',sans-serif` | Pure Latin character titles |
|
||||
| Latin Body | Write PPT font name directly: `font-family:'Corbel',sans-serif` | Pure Latin character body text |
|
||||
|
||||
**v3 Smart Font Mapping**: html2pptx.js automatically handles fonts:
|
||||
- **PPT-safe fonts** (SimHei, Corbel, Palatino Linotype, etc. 40+) → Passed through directly, preserved as-is
|
||||
- **macOS-exclusive fonts** (PingFang, Hiragino) → Automatically mapped to cross-platform equivalent fonts
|
||||
- **Web fonts** (Roboto, Montserrat, Inter, etc.) → Automatically mapped to the visually closest PPT-safe font
|
||||
- **fontConfig still available**: Serves as the final fallback default for CJK/Latin
|
||||
|
||||
**fontConfig can be passed when calling html2pptx()** (optional, used to override default fallback):
|
||||
```javascript
|
||||
const fontConfig = { cjk: 'SimHei', latin: 'Corbel' };
|
||||
```
|
||||
|
||||
**Recommended practice**: Write the target PPT font name directly in HTML; do not rely on fontConfig for switching.
|
||||
|
||||
**PPT-safe Chinese fonts**: Microsoft YaHei / SimHei / SimSun / KaiTi / FangSong / DengXian
|
||||
**PPT-safe English fonts**: Corbel / Arial / Times New Roman / Palatino Linotype / Gill Sans MT / Century Gothic / Garamond / Rockwell / Candara / Constantia / Cambria / Trebuchet MS
|
||||
|
||||
---
|
||||
|
||||
## Dark Mode Semantic Color Mapping
|
||||
|
||||
For themes that need a full dark-mode deck (not just individual dark slides), use these semantic overrides:
|
||||
|
||||
| Semantic Token | Light Mode Value | Dark Mode Value |
|
||||
|---------------|-----------------|-----------------|
|
||||
| `background` | `#FFFFFF` | `primary-100` |
|
||||
| `surface` | `primary-5` | `primary-90` |
|
||||
| `surface-card` | `#FFFFFF` | `primary-80` |
|
||||
| `text-primary` | `primary-80` | `#FFFFFF` |
|
||||
| `text-secondary` | `primary-60` | `rgba(255,255,255,0.75)` |
|
||||
| `text-muted` | `primary-40` | `rgba(255,255,255,0.45)` |
|
||||
| `border` | `primary-10` | `primary-60` |
|
||||
| `on-dark` | `#FFFFFF` | `#FFFFFF` (unchanged) |
|
||||
|
||||
Deep Mineral and Deep Forest themes already use dark mode by default. For any other theme, apply this mapping to create a dark variant.
|
||||
|
||||
Cards in dark mode use `surface-card` background with **no shadow** (shadows invisible on dark backgrounds). Use subtle `border: 1pt solid primary-60` instead for card definition.
|
||||
Reference in New Issue
Block a user