html files are now templates
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
package pdfrender
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseTemplateMetadata extracts block metadata from HTML comments in template content
|
||||
// Format: <!-- BLOCK: name, TYPE: type, MAX: number, FILTER: filter -->
|
||||
func ParseTemplateMetadata(templateContent string) []BlockMetadata {
|
||||
blocks := []BlockMetadata{}
|
||||
|
||||
// Regex to match: <!-- BLOCK: name, TYPE: type, MAX: number, FILTER: filter -->
|
||||
re := regexp.MustCompile(`<!--\s*BLOCK:\s*([^,]+),\s*TYPE:\s*([^,]+),\s*MAX:\s*(\d+)(?:,\s*FILTER:\s*([^-]+))?\s*-->`)
|
||||
|
||||
matches := re.FindAllStringSubmatch(templateContent, -1)
|
||||
for _, match := range matches {
|
||||
if len(match) < 4 {
|
||||
continue
|
||||
}
|
||||
|
||||
name := strings.TrimSpace(match[1])
|
||||
listType := strings.TrimSpace(match[2])
|
||||
maxItems, _ := strconv.Atoi(strings.TrimSpace(match[3]))
|
||||
|
||||
filter := ""
|
||||
if len(match) > 4 && match[4] != "" {
|
||||
filter = strings.TrimSpace(match[4])
|
||||
}
|
||||
|
||||
blocks = append(blocks, BlockMetadata{
|
||||
Name: name,
|
||||
ListType: listType,
|
||||
MaxItems: maxItems,
|
||||
Filter: filter,
|
||||
})
|
||||
}
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
// GetBlockByName returns the block metadata for a specific block name
|
||||
func GetBlockByName(blocks []BlockMetadata, name string) *BlockMetadata {
|
||||
for i := range blocks {
|
||||
if blocks[i].Name == name {
|
||||
return &blocks[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBlocksByType returns all blocks of a specific list type
|
||||
func GetBlocksByType(blocks []BlockMetadata, listType string) []BlockMetadata {
|
||||
result := []BlockMetadata{}
|
||||
for _, block := range blocks {
|
||||
if block.ListType == listType {
|
||||
result = append(result, block)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package pdfrender
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParseTemplateMetadata(t *testing.T) {
|
||||
// Arrange
|
||||
templateContent := `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<!-- BLOCK: spells_left, TYPE: spells, MAX: 12 -->
|
||||
<table>
|
||||
{{range .Spells}}
|
||||
{{end}}
|
||||
</table>
|
||||
|
||||
<!-- BLOCK: spells_right, TYPE: spells, MAX: 10 -->
|
||||
<table>
|
||||
{{range .Spells}}
|
||||
{{end}}
|
||||
</table>
|
||||
|
||||
<!-- BLOCK: magic_items, TYPE: magicItems, MAX: 5 -->
|
||||
<table>
|
||||
{{range .MagicItems}}
|
||||
{{end}}
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
// Act
|
||||
blocks := ParseTemplateMetadata(templateContent)
|
||||
|
||||
// Assert
|
||||
if len(blocks) != 3 {
|
||||
t.Fatalf("Expected 3 blocks, got %d", len(blocks))
|
||||
}
|
||||
|
||||
// Check first block
|
||||
if blocks[0].Name != "spells_left" {
|
||||
t.Errorf("Expected name 'spells_left', got '%s'", blocks[0].Name)
|
||||
}
|
||||
if blocks[0].ListType != "spells" {
|
||||
t.Errorf("Expected type 'spells', got '%s'", blocks[0].ListType)
|
||||
}
|
||||
if blocks[0].MaxItems != 12 {
|
||||
t.Errorf("Expected max 12, got %d", blocks[0].MaxItems)
|
||||
}
|
||||
|
||||
// Check second block
|
||||
if blocks[1].Name != "spells_right" {
|
||||
t.Errorf("Expected name 'spells_right', got '%s'", blocks[1].Name)
|
||||
}
|
||||
if blocks[1].MaxItems != 10 {
|
||||
t.Errorf("Expected max 10, got %d", blocks[1].MaxItems)
|
||||
}
|
||||
|
||||
// Check third block
|
||||
if blocks[2].Name != "magic_items" {
|
||||
t.Errorf("Expected name 'magic_items', got '%s'", blocks[2].Name)
|
||||
}
|
||||
if blocks[2].ListType != "magicItems" {
|
||||
t.Errorf("Expected type 'magicItems', got '%s'", blocks[2].ListType)
|
||||
}
|
||||
if blocks[2].MaxItems != 5 {
|
||||
t.Errorf("Expected max 5, got %d", blocks[2].MaxItems)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseTemplateMetadata_WithFilter(t *testing.T) {
|
||||
// Arrange
|
||||
templateContent := `
|
||||
<!-- BLOCK: skills_learned, TYPE: skills, MAX: 24, FILTER: learned -->
|
||||
<table>{{range .Skills}}{{end}}</table>
|
||||
`
|
||||
|
||||
// Act
|
||||
blocks := ParseTemplateMetadata(templateContent)
|
||||
|
||||
// Assert
|
||||
if len(blocks) != 1 {
|
||||
t.Fatalf("Expected 1 block, got %d", len(blocks))
|
||||
}
|
||||
|
||||
if blocks[0].Name != "skills_learned" {
|
||||
t.Errorf("Expected name 'skills_learned', got '%s'", blocks[0].Name)
|
||||
}
|
||||
if blocks[0].Filter != "learned" {
|
||||
t.Errorf("Expected filter 'learned', got '%s'", blocks[0].Filter)
|
||||
}
|
||||
if blocks[0].MaxItems != 24 {
|
||||
t.Errorf("Expected max 24, got %d", blocks[0].MaxItems)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBlockByName(t *testing.T) {
|
||||
// Arrange
|
||||
blocks := []BlockMetadata{
|
||||
{Name: "skills_left", ListType: "skills", MaxItems: 32},
|
||||
{Name: "skills_right", ListType: "skills", MaxItems: 32},
|
||||
{Name: "weapons_main", ListType: "weapons", MaxItems: 30},
|
||||
}
|
||||
|
||||
// Act
|
||||
block := GetBlockByName(blocks, "weapons_main")
|
||||
|
||||
// Assert
|
||||
if block == nil {
|
||||
t.Fatal("Expected block, got nil")
|
||||
}
|
||||
if block.Name != "weapons_main" {
|
||||
t.Errorf("Expected 'weapons_main', got '%s'", block.Name)
|
||||
}
|
||||
if block.MaxItems != 30 {
|
||||
t.Errorf("Expected max 30, got %d", block.MaxItems)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBlocksByType(t *testing.T) {
|
||||
// Arrange
|
||||
blocks := []BlockMetadata{
|
||||
{Name: "skills_left", ListType: "skills", MaxItems: 32},
|
||||
{Name: "skills_right", ListType: "skills", MaxItems: 32},
|
||||
{Name: "weapons_main", ListType: "weapons", MaxItems: 30},
|
||||
}
|
||||
|
||||
// Act
|
||||
skillBlocks := GetBlocksByType(blocks, "skills")
|
||||
|
||||
// Assert
|
||||
if len(skillBlocks) != 2 {
|
||||
t.Fatalf("Expected 2 skill blocks, got %d", len(skillBlocks))
|
||||
}
|
||||
if skillBlocks[0].ListType != "skills" {
|
||||
t.Errorf("Expected type 'skills', got '%s'", skillBlocks[0].ListType)
|
||||
}
|
||||
if skillBlocks[1].ListType != "skills" {
|
||||
t.Errorf("Expected type 'skills', got '%s'", skillBlocks[1].ListType)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Figurenblatt - {{.Character.Name}}</title>
|
||||
<link rel="stylesheet" href="export_format_a4_quer.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<span class="header-left">Figurenblatt</span>
|
||||
<span class="header-right">Datum: {{.Meta.Date}}</span>
|
||||
</div>
|
||||
|
||||
<div class="title-row">
|
||||
<img src="headerimg.png" alt="Schmuckgrafik" class="header-decoration">
|
||||
<div class="info-box">
|
||||
<div><strong>Figur</strong> {{.Character.Name}}</div>
|
||||
<hr>
|
||||
<div><strong>Spieler</strong> {{.Character.Player}}</div>
|
||||
</div>
|
||||
<img src="headerimg.png" alt="Schmuckgrafik" class="header-decoration">
|
||||
</div>
|
||||
|
||||
<div class="flex main-content">
|
||||
<div class="left-section">
|
||||
<div class="col">
|
||||
<!-- left column block Chartype -->
|
||||
<div class="margin-bottom-3">
|
||||
<div><strong>Typ</strong> {{.Character.Type}} <strong>Grad</strong> {{.Character.Grade}}</div>
|
||||
<div><strong>Spezialisierung</strong> _______________________</div>
|
||||
</div>
|
||||
<!-- left column block stats1 -->
|
||||
<div class="margin-bottom-3">
|
||||
<div class="attr-box"><div class="attr-label">St</div><div class="attr-value">{{.Attributes.St}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">Gs</div><div class="attr-value">{{.Attributes.Gs}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">Gw</div><div class="attr-value">{{.Attributes.Gw}}</div></div>
|
||||
</div>
|
||||
<!-- left column block stats2 -->
|
||||
<div class="margin-bottom-3">
|
||||
<div class="attr-box"><div class="attr-label">Ko</div><div class="attr-value">{{.Attributes.Ko}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">In</div><div class="attr-value">{{.Attributes.In}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">Zt</div><div class="attr-value">{{.Attributes.Zt}}</div></div>
|
||||
</div>
|
||||
<!-- left column block stats3 -->
|
||||
<div class="margin-bottom-3">
|
||||
<div class="attr-box"><div class="attr-label">Au</div><div class="attr-value">{{.Attributes.Au}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">pA</div><div class="attr-value">{{.Attributes.PA}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">Wk</div><div class="attr-value">{{.Attributes.Wk}}</div></div>
|
||||
</div>
|
||||
<!-- left column block stats4 -->
|
||||
<div class="margin-bottom-3">
|
||||
<div class="attr-box attr-box-80"><div class="attr-label">B</div><div class="attr-value">{{.Attributes.B}}</div></div>
|
||||
<div class="attr-box attr-box-100"><div class="attr-label">Raufen</div><div class="attr-value">+ 5</div></div>
|
||||
</div>
|
||||
<!-- left column block boni -->
|
||||
<div class="margin-top-5">
|
||||
<div><strong>persönlicher Bonus für:</strong></div>
|
||||
<div class="margin-top-2">
|
||||
<div class="bonus-row"><span>Ausdauer <u>{{.DerivedValues.AusdauerBonus}}</u></span><span>Schaden <u>{{.DerivedValues.SchadenBonus}}</u></span><span>Angriff <u>{{.DerivedValues.AngriffBonus}}</u></span></div>
|
||||
<div class="bonus-row"><span>Abwehr <u>{{.DerivedValues.Abwehr}}</u></span><span>Resistenz <u>{{.DerivedValues.ResistenzGift}}/{{.DerivedValues.ResistenzGeist}}</u></span><span>Zaubern <u>{{.DerivedValues.Zaubern}}</u></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- center column block Charinfo -->
|
||||
<div class="col">
|
||||
<table class="charinfo">
|
||||
<tr>
|
||||
<td><strong>Geburtsdatum</strong></td>
|
||||
<td>{{.Character.Birthdate}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Alter</strong></td>
|
||||
<td><u>{{.Character.Age}}</u> rechts. händig</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Größe</strong></td>
|
||||
<td>{{.Character.Height}} cm</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Gestalt</strong></td>
|
||||
<td>mittel, normal Gewicht {{.Character.Weight}} kg</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Stand</strong></td>
|
||||
<td>{{.Character.Stand}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Heimat</strong></td>
|
||||
<td>{{.Character.Homeland}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Glaube</strong></td>
|
||||
<td>{{.Character.Religion}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><strong>Besondere Merkmale:</strong><br/><br/><br/><br/><br/><br/><br/><br/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- left column block LPAP -->
|
||||
<div class="margin-top-5">
|
||||
<div class="attr-box attr-box-100"><div class="attr-label">LP-Max.</div><div class="attr-value">{{.DerivedValues.LPMax}}</div></div>
|
||||
<div class="attr-box attr-box-100"><div class="attr-label">AP-Max.</div><div class="attr-value">{{.DerivedValues.APMax}}</div></div>
|
||||
<div class="attr-box attr-box-80"><div class="attr-label">GG</div><div class="attr-value">{{.DerivedValues.GG}}</div></div>
|
||||
<div class="attr-box attr-box-80"><div class="attr-label">SG</div><div class="attr-value">{{.DerivedValues.SG}}</div></div>
|
||||
</div>
|
||||
<!-- left column block History -->
|
||||
<div class="margin-top-5">
|
||||
<table class="history-table">
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
{{range .GameResults}}<th>{{.Date.Format "02.01.2006"}}</th>{{end}}
|
||||
{{range $i := iterate 6}}{{if lt $i (len $.GameResults)}}<th> </th>{{end}}{{end}}
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ES</td>
|
||||
{{range .GameResults}}<td>{{.EP}}</td>{{end}}
|
||||
{{range $i := iterate 6}}{{if lt $i (len $.GameResults)}}<td></td>{{end}}{{end}}
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EP</td>
|
||||
{{range .GameResults}}<td>{{.EP}}</td>{{end}}
|
||||
{{range $i := iterate 6}}{{if lt $i (len $.GameResults)}}<td></td>{{end}}{{end}}
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Geld</td>
|
||||
{{range .GameResults}}<td>{{.Gold}}</td>{{end}}
|
||||
{{range $i := iterate 6}}{{if lt $i (len $.GameResults)}}<td></td>{{end}}{{end}}
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b><center>Datum</center></b></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ES</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EP</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Geld</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- right1 column block Fertigkeiten -->
|
||||
<div class="right-section">
|
||||
<div class="skills-content">
|
||||
<div class="skills-title">Liste der gelernten und angeborenen Fertigkeiten</div>
|
||||
<div class="skills-container">
|
||||
<!-- BLOCK: skills_column1, TYPE: skills, MAX: 32 -->
|
||||
<table class="skills-table">
|
||||
<tr>
|
||||
<th>Fertigkeit</th>
|
||||
<th>EW</th>
|
||||
<th>PP</th>
|
||||
</tr>
|
||||
{{range .Skills}}
|
||||
<tr><td>{{.Name}}</td><td>+ {{.Value}}</td><td>{{if .PracticePoints}}{{.PracticePoints}}{{end}}</td></tr>
|
||||
{{end}}
|
||||
</table>
|
||||
<!-- BLOCK: skills_column2, TYPE: skills, MAX: 32 -->
|
||||
<table class="skills-table">
|
||||
<tr>
|
||||
<th>Fertigkeit</th>
|
||||
<th>EW</th>
|
||||
<th>PP</th>
|
||||
</tr>
|
||||
{{range $i := iterate 32}}
|
||||
<tr><td> </td><td></td><td></td></tr>
|
||||
{{end}}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="senses-row"> <span><b>Sehen</b> +{{.DerivedValues.Sehen}}</span><span><b>Nachtsicht</b> +{{.DerivedValues.Sehen}}</span><span><b>Hören</b> +{{.DerivedValues.Horen}}</span><span><b>Riechen/Schmecken</b> +{{.DerivedValues.Riechen}} <b>Sechster Sinn</b> +{{.DerivedValues.Sechster}}</span> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,205 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Abenteuerblatt - {{.Character.Name}}</title>
|
||||
<link rel="stylesheet" href="export_format_a4_quer.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<span class="header-left">Abenteuerblatt</span>
|
||||
<span class="header-right">Datum: {{.Meta.Date}}</span>
|
||||
</div>
|
||||
|
||||
<div class="title-row">
|
||||
<img src="headerimg.png" alt="Schmuckgrafik" class="header-decoration">
|
||||
<div class="info-box">
|
||||
<div><strong>Figur</strong> {{.Character.Name}} <strong>Grad</strong> {{.Character.Grade}}</div>
|
||||
<hr>
|
||||
<div><strong>Typ</strong> {{.Character.Type}} <strong>GG</strong> {{.DerivedValues.GG}} <strong>SG</strong> {{.DerivedValues.SG}}</div>
|
||||
</div>
|
||||
<img src="headerimg.png" alt="Schmuckgrafik" class="header-decoration">
|
||||
</div>
|
||||
|
||||
<div class="flex main-content">
|
||||
<!-- Left section -->
|
||||
<div class="left-section">
|
||||
<!-- Stats boxes top -->
|
||||
<div class="stats-row">
|
||||
<div class="attr-box"><div class="attr-label">St</div><div class="attr-value">{{.Attributes.St}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">Gs</div><div class="attr-value">{{.Attributes.Gs}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">Gw</div><div class="attr-value">{{.Attributes.Gw}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">Ko</div><div class="attr-value">{{.Attributes.Ko}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">In</div><div class="attr-value">{{.Attributes.In}}</div></div>
|
||||
</div>
|
||||
<div class="stats-row">
|
||||
<div class="attr-box"><div class="attr-label">Zt</div><div class="attr-value">{{.Attributes.Zt}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">Au</div><div class="attr-value">{{.Attributes.Au}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">pA</div><div class="attr-value">{{.Attributes.PA}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">Wk</div><div class="attr-value">{{.Attributes.Wk}}</div></div>
|
||||
<div class="attr-box"><div class="attr-label">B</div><div class="attr-value">{{.Attributes.B}}</div></div>
|
||||
</div>
|
||||
|
||||
<!-- Combat stats -->
|
||||
<div class="combat-stats">
|
||||
<div><strong>Abwehr + {{.DerivedValues.Abwehr}}</strong></div>
|
||||
<div><strong>+</strong> <span class="combat-stats-small">mit Vert.<br>waffe</span></div>
|
||||
<div><strong>Resistenz + {{.DerivedValues.ResistenzGift}}/{{.DerivedValues.ResistenzGeist}}</strong></div>
|
||||
<div><strong>Zaubern + {{.DerivedValues.Zaubern}}</strong></div>
|
||||
</div>
|
||||
|
||||
<!-- Skills tables -->
|
||||
<div class="skills-row">
|
||||
<!-- BLOCK: skills_learned, TYPE: skills, MAX: 24, FILTER: learned -->
|
||||
<table class="skills-table">
|
||||
<tr>
|
||||
<th>Fertigkeit</th>
|
||||
<th>EW</th>
|
||||
<th>PP</th>
|
||||
</tr>
|
||||
{{range .Skills}}
|
||||
<tr><td>{{.Name}}</td><td>+ {{.Value}}</td><td>{{if .PracticePoints}}{{.PracticePoints}}{{end}}</td></tr>
|
||||
{{end}}
|
||||
</table>
|
||||
<div class="skills-stack">
|
||||
<!-- BLOCK: skills_unlearned, TYPE: skills, MAX: 15, FILTER: unlearned -->
|
||||
<table class="skills-col-table">
|
||||
<tr>
|
||||
<th colspan="2"><em>ungelernte Fertigkeiten</em></th>
|
||||
</tr>
|
||||
<tr><td colspan="2" class="unlearned-small">alle wenigstens +(0) außer Musizieren, Schreiben, Sprache, Lesen von Zauberschrift</td></tr>
|
||||
<tr><td>Akrobatik+(6)</td><td>Tauchen~(6)</td></tr>
|
||||
<tr><td>Athletik+(6)</td><td>Trinken+(3)</td></tr>
|
||||
<tr><td>Balancieren+(6)</td><td>Überreden+(6)</td></tr>
|
||||
<tr><td>Betäubungsgriff+(6)</td><td>Verführen+(3)</td></tr>
|
||||
<tr><td>Bootfahren+(3)</td><td>Verfroren+(3)</td></tr>
|
||||
<tr><td>Einschüchtern+(3)</td><td>Verstecken+(3)</td></tr>
|
||||
<tr><td>Klettern+(6)</td><td>Wahrnehmung+(6)</td></tr>
|
||||
<tr><td>Menschenkenntnis+(3)</td><td></td></tr>
|
||||
<tr><td>Reiten+(6)</td><td></td></tr>
|
||||
<tr><td>Schwimmen+(3)</td><td></td></tr>
|
||||
<tr><td>Seilkunst+(3)</td><td></td></tr>
|
||||
<tr><td>Stehlen+(3)</td><td></td></tr>
|
||||
<tr><td>Tanzen+(6)</td><td></td></tr>
|
||||
<tr><td>Tarnen+(3)</td><td></td></tr>
|
||||
</table>
|
||||
<!-- BLOCK: skills_languages, TYPE: skills, MAX: 11, FILTER: language -->
|
||||
<table class="skills-table" style="width: 100%; height: unset;">
|
||||
<tr>
|
||||
<th>Fertigkeit</th>
|
||||
<th>EW</th>
|
||||
<th>PP</th>
|
||||
</tr>
|
||||
{{range .Skills}}
|
||||
{{if eq .Category "Sprache"}}
|
||||
<tr><td>{{.Name}}</td><td>+ {{.Value}}</td><td>{{if .PracticePoints}}{{.PracticePoints}}{{end}}</td></tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right section -->
|
||||
<div class="right-section">
|
||||
<div>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>LP {{.DerivedValues.LPMax}}</td>
|
||||
{{range $i := iterate 13}}<td> </td>{{end}}
|
||||
</tr><tr>
|
||||
<td>AP {{.DerivedValues.APMax}}</td>
|
||||
{{range $i := iterate 13}}<td> </td>{{end}}
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Bonus table -->
|
||||
<div class="margin-bottom-3">
|
||||
<table class="bonus-table">
|
||||
<tr>
|
||||
<th>pers.</th>
|
||||
<th colspan="2">Ausdauer</th>
|
||||
<th colspan="2">Angriff</th>
|
||||
<th colspan="2">Abwehr</th>
|
||||
<th colspan="2">Schaden</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bonus</td>
|
||||
<td>{{.DerivedValues.AusdauerBonus}}</td>
|
||||
<td></td>
|
||||
<td>{{.DerivedValues.AngriffBonus}}</td>
|
||||
<td></td>
|
||||
<td>{{.DerivedValues.Abwehr}}</td>
|
||||
<td></td>
|
||||
<td>{{.DerivedValues.SchadenBonus}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Situativ</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Summe</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Weapons table -->
|
||||
<div class="margin-bottom-3">
|
||||
<!-- BLOCK: weapons_main, TYPE: weapons, MAX: 30 -->
|
||||
<table class="weapons-table">
|
||||
<tr>
|
||||
<th>Waffe</th>
|
||||
<th>EW +/-</th>
|
||||
<th>GG</th>
|
||||
<th>+/-</th>
|
||||
<th>Schaden</th>
|
||||
<th>+/-</th>
|
||||
<th>Abwehr</th>
|
||||
<th>+/-</th>
|
||||
</tr>
|
||||
{{range .Weapons}}
|
||||
<tr>
|
||||
<td>{{.Name}}</td>
|
||||
<td>{{.Value}}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>{{.Damage}}</td>
|
||||
<td></td>
|
||||
<td>{{.ParryValue}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Senses row at bottom -->
|
||||
<div class="senses-row">
|
||||
<span>Sehen+{{.DerivedValues.Sehen}}</span>
|
||||
<span>Nachtsicht+{{.DerivedValues.Sehen}}</span>
|
||||
<span>Hören+{{.DerivedValues.Horen}}</span>
|
||||
<span>Riechen/Schmecken+{{.DerivedValues.Riechen}}</span>
|
||||
<span>Sechster Sinn+{{.DerivedValues.Sechster}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,99 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Zauberblatt - {{.Character.Name}}</title>
|
||||
<link rel="stylesheet" href="export_format_a4_quer.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<span class="header-left">Zauberblatt</span>
|
||||
<span class="header-right">Datum: {{.Meta.Date}}</span>
|
||||
</div>
|
||||
|
||||
<div class="title-row">
|
||||
<img src="headerimg.png" alt="Schmuckgrafik" class="header-decoration">
|
||||
<div class="info-box">
|
||||
<div><strong>Figur</strong> {{.Character.Name}} <strong>Grad</strong> {{.Character.Grade}}</div>
|
||||
<hr>
|
||||
<div><strong>Typ</strong> {{.Character.Type}} <strong>Zaubern</strong> + {{.DerivedValues.Zaubern}}</div>
|
||||
</div>
|
||||
<img src="headerimg.png" alt="Schmuckgrafik" class="header-decoration">
|
||||
</div>
|
||||
|
||||
<div class="flex main-content">
|
||||
<!-- Left spell table -->
|
||||
<div class="left-section">
|
||||
<!-- BLOCK: spells_left, TYPE: spells, MAX: 12 -->
|
||||
<table class="spells-table">
|
||||
<tr>
|
||||
<th>AP<hr>Prozess *</th>
|
||||
<th>Zauber</th>
|
||||
<th>Zauberdauer<hr>Reichweite</th>
|
||||
<th>Wirkungsbereich<hr>Wirkungsdauer</th>
|
||||
<th>Wirkung</th>
|
||||
<th>Wirk.ziel<hr>Art</th>
|
||||
</tr>
|
||||
{{range .Spells}}
|
||||
<tr>
|
||||
<td>{{.AP}}<hr>{{.Notes}}</td>
|
||||
<td>{{.Name}}</td>
|
||||
<td>{{.CastTime}}<hr>{{.Range}}</td>
|
||||
<td>{{.Scope}}<hr>{{.Duration}}</td>
|
||||
<td>{{.Notes}}</td>
|
||||
<td>{{.Objective}}<hr>{{.CastingType}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Right spell table -->
|
||||
<div class="right-section">
|
||||
<!-- BLOCK: spells_right, TYPE: spells, MAX: 10 -->
|
||||
<table class="spells-table">
|
||||
<tr>
|
||||
<th>AP<br>Prozess *</th>
|
||||
<th>Zauber</th>
|
||||
<th>Zauberdauer<br>Reichweite</th>
|
||||
<th>Wirkungsbereich<br>Wirkungsdauer</th>
|
||||
<th>Wirkung</th>
|
||||
<th>Wirk.ziel<br>Art</th>
|
||||
</tr>
|
||||
{{range .Spells}}
|
||||
<tr>
|
||||
<td>{{.AP}}<hr>{{.Notes}}</td>
|
||||
<td>{{.Name}}</td>
|
||||
<td>{{.CastTime}}<hr>{{.Range}}</td>
|
||||
<td>{{.Scope}}<hr>{{.Duration}}</td>
|
||||
<td>{{.Notes}}</td>
|
||||
<td>{{.Objective}}<hr>{{.CastingType}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
<div class="spell-footer">
|
||||
<p><em>wichtige magische Gegenstände, Tränke, Schriftrollen</em></p>
|
||||
<!-- BLOCK: magic_items, TYPE: magicItems, MAX: 5 -->
|
||||
<table class="items-table">
|
||||
<tr>
|
||||
<th>Gegenstand</th>
|
||||
<th>Beschreibung</th>
|
||||
</tr>
|
||||
{{range .MagicItems}}
|
||||
<tr>
|
||||
<td>{{.Name}}</td>
|
||||
<td>{{.Description}} {{if .Properties}}{{.Properties}}{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="spell-note">
|
||||
<strong>* +2 auf EW:Zaubern für Spezialisierung von Magiern</strong>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,122 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Ausrüstungsblatt - {{.Character.Name}}</title>
|
||||
<link rel="stylesheet" href="export_format_a4_quer.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<span class="header-left">Ausrüstungsblatt</span>
|
||||
<span class="header-right">Datum: {{.Meta.Date}}</span>
|
||||
</div>
|
||||
|
||||
<div class="title-row">
|
||||
<img src="headerimg.png" alt="Schmuckgrafik" class="header-decoration">
|
||||
<div class="info-box">
|
||||
<div><strong>Figur</strong> {{.Character.Name}} <strong>Grad</strong> {{.Character.Grade}}</div>
|
||||
<hr>
|
||||
<div><strong>Typ</strong> {{.Character.Type}} <strong>Zaubern</strong> + {{.DerivedValues.Zaubern}}</div>
|
||||
</div>
|
||||
<img src="headerimg.png" alt="Schmuckgrafik" class="header-decoration">
|
||||
</div>
|
||||
|
||||
<div class="flex main-content">
|
||||
<!-- Left section: Character icon, currency, and small containers -->
|
||||
<div class="equipment-left">
|
||||
<div class="char-icon-section">
|
||||
{{if .Character.IconBase64}}
|
||||
<img src="{{.Character.IconBase64}}" alt="Charakter" class="char-icon">
|
||||
{{end}}
|
||||
</div>
|
||||
<table class="currency-table">
|
||||
<tr>
|
||||
<td><strong>GS</strong></td>
|
||||
<td>0</td>
|
||||
{{range $i := iterate 9}}<td> </td>{{end}}
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>SS</strong></td>
|
||||
<td>0</td>
|
||||
{{range $i := iterate 9}}<td></td>{{end}}
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>KS</strong></td>
|
||||
<td>0</td>
|
||||
{{range $i := iterate 9}}<td></td>{{end}}
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Containers sections -->
|
||||
{{range .Equipment}}
|
||||
{{if .IsContainer}}
|
||||
<table class="equipment-section">
|
||||
<tr>
|
||||
<th colspan="2">{{.Name}}</th>
|
||||
</tr>
|
||||
{{range $.Equipment}}
|
||||
{{if and (not .IsContainer) (eq .Container $.Name)}}
|
||||
<tr>
|
||||
<td>{{.Name}}</td>
|
||||
<td>{{.Quantity}} x {{.Weight}} kg</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<tr>
|
||||
<td colspan="2" class="weight-total"><strong>Gewicht {{.Weight}} kg</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<!-- Right section: Equipment sections -->
|
||||
<div class="equipment-right">
|
||||
<!-- Section: Am Körper getragen -->
|
||||
<!-- BLOCK: equipment_worn, TYPE: equipment, MAX: 10, FILTER: worn -->
|
||||
<table class="equipment-section">
|
||||
<tr>
|
||||
<th colspan="2">Am Körper getragen</th>
|
||||
</tr>
|
||||
{{range .Equipment}}
|
||||
{{if .IsWorn}}
|
||||
<tr>
|
||||
<td>{{.Name}}</td>
|
||||
<td>{{.Quantity}} x {{.Weight}} kg - {{.Value}} GS{{if .Notes}}<br>{{.Notes}}{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<tr>
|
||||
<td colspan="2" class="weight-total"><strong>Gewicht ? kg</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Other equipment sections by container -->
|
||||
{{$containers := .Equipment}}
|
||||
{{range $container := $containers}}
|
||||
{{if and $container.IsContainer (ne $container.Name "Am Körper")}}
|
||||
<table class="equipment-section">
|
||||
<tr>
|
||||
<th colspan="2">{{$container.Name}}</th>
|
||||
</tr>
|
||||
{{range $item := $containers}}
|
||||
{{if and (not $item.IsContainer) (eq $item.Container $container.Name)}}
|
||||
<tr>
|
||||
<td>{{$item.Name}}</td>
|
||||
<td>{{$item.Quantity}} x {{$item.Weight}} kg - {{$item.Value}} GS</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<tr>
|
||||
<td colspan="2" class="weight-total"><strong>Gewicht {{$container.Weight}} kg</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user