mirror of
https://github.com/Theodor-Springmann-Stiftung/lenz-web.git
synced 2025-10-28 16:55:32 +00:00
Seitenumbrüche und Weißraum FIX
This commit is contained in:
@@ -2,9 +2,6 @@ package functions
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"strings"
|
||||
|
||||
xmlparsing "github.com/Theodor-Springmann-Stiftung/lenz-web/xml"
|
||||
)
|
||||
|
||||
func FirstLetter(s string) string {
|
||||
@@ -20,41 +17,3 @@ func Safe(s string) template.HTML {
|
||||
}
|
||||
return template.HTML(s)
|
||||
}
|
||||
|
||||
type LenzParseState struct{}
|
||||
|
||||
func ParseGeneric(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
builder := strings.Builder{}
|
||||
for elem, err := range xmlparsing.Iterate(s, LenzParseState{}) {
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
switch elem.Token.Type {
|
||||
case xmlparsing.StartElement:
|
||||
builder.WriteString("<div class=\"")
|
||||
builder.WriteString(elem.Token.Name)
|
||||
for key, value := range elem.Token.Attributes {
|
||||
builder.WriteString(" ")
|
||||
builder.WriteString(key)
|
||||
builder.WriteString("-")
|
||||
builder.WriteString(value)
|
||||
}
|
||||
|
||||
builder.WriteString("\">")
|
||||
}
|
||||
|
||||
if elem.Token.Type == xmlparsing.CharData {
|
||||
builder.WriteString(elem.Token.Data)
|
||||
}
|
||||
|
||||
if elem.Token.Type == xmlparsing.EndElement {
|
||||
builder.WriteString("</div>")
|
||||
}
|
||||
}
|
||||
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
155
helpers/functions/textparse.go
Normal file
155
helpers/functions/textparse.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package functions
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
xmlparsing "github.com/Theodor-Springmann-Stiftung/lenz-web/xml"
|
||||
)
|
||||
|
||||
type outType int
|
||||
|
||||
const (
|
||||
NA outType = iota
|
||||
Text
|
||||
Element
|
||||
EmptyElement
|
||||
EndElement
|
||||
)
|
||||
|
||||
type outToken struct {
|
||||
Type outType
|
||||
Name string
|
||||
Classes []string
|
||||
Id string
|
||||
Value string
|
||||
}
|
||||
|
||||
func (o *outToken) ClassesFromAttrs(attrs map[string]string) {
|
||||
if len(attrs) == 0 {
|
||||
return
|
||||
}
|
||||
for key, value := range attrs {
|
||||
o.Classes = append(o.Classes, key+"-"+value)
|
||||
}
|
||||
}
|
||||
|
||||
func Default(token xmlparsing.Token) outToken {
|
||||
o := outToken{}
|
||||
switch token.Type {
|
||||
case xmlparsing.StartElement:
|
||||
o.Name = "div"
|
||||
o.Type = Element
|
||||
o.Classes = []string{token.Name}
|
||||
o.ClassesFromAttrs(token.Attributes)
|
||||
case xmlparsing.EndElement:
|
||||
o.Type = EndElement
|
||||
case xmlparsing.CharData:
|
||||
o.Type = Text
|
||||
o.Value = token.Data
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
type LenzParseState struct {
|
||||
Out []outToken
|
||||
LC int
|
||||
PC string
|
||||
CloseElement bool
|
||||
}
|
||||
|
||||
func (s *LenzParseState) String() string {
|
||||
builder := strings.Builder{}
|
||||
for _, token := range s.Out {
|
||||
switch token.Type {
|
||||
case Text:
|
||||
builder.WriteString(token.Value)
|
||||
case Element:
|
||||
builder.WriteString("<")
|
||||
builder.WriteString(token.Name)
|
||||
if len(token.Classes) > 0 {
|
||||
builder.WriteString(" class=\"")
|
||||
builder.WriteString(strings.Join(token.Classes, " "))
|
||||
builder.WriteString("\"")
|
||||
}
|
||||
if len(token.Id) > 0 {
|
||||
builder.WriteString(" id=\"")
|
||||
builder.WriteString(token.Id)
|
||||
builder.WriteString("\"")
|
||||
}
|
||||
builder.WriteString(">")
|
||||
case EndElement:
|
||||
builder.WriteString("</div>")
|
||||
case EmptyElement:
|
||||
builder.WriteString("<")
|
||||
builder.WriteString(token.Name)
|
||||
if len(token.Classes) > 0 {
|
||||
builder.WriteString(" class=\"")
|
||||
builder.WriteString(strings.Join(token.Classes, " "))
|
||||
builder.WriteString("\"")
|
||||
}
|
||||
|
||||
if len(token.Id) > 0 {
|
||||
builder.WriteString(" id=\"")
|
||||
builder.WriteString(token.Id)
|
||||
builder.WriteString("\"")
|
||||
}
|
||||
builder.WriteString("/>")
|
||||
}
|
||||
}
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
func ParseGeneric(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
ps := LenzParseState{CloseElement: true}
|
||||
|
||||
for elem, err := range xmlparsing.Iterate(s, ps) {
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
if elem.Token.Type < 3 {
|
||||
if !ps.CloseElement && elem.Token.Type == xmlparsing.EndElement {
|
||||
ps.CloseElement = true
|
||||
continue
|
||||
} else if elem.Token.Type == xmlparsing.EndElement {
|
||||
ps.Out = append(ps.Out, Default(elem.Token))
|
||||
continue
|
||||
}
|
||||
|
||||
defaultToken := Default(elem.Token)
|
||||
switch elem.Token.Name {
|
||||
case "line":
|
||||
nt := outToken{
|
||||
Type: EmptyElement,
|
||||
Name: "br",
|
||||
}
|
||||
if val := elem.Token.Attributes["type"]; val != "empty" {
|
||||
ps.Out = append(ps.Out, nt)
|
||||
ps.LC += 1
|
||||
ps.Out = append(ps.Out, defaultToken)
|
||||
} else {
|
||||
nt.Classes = []string{"empty"}
|
||||
ps.Out = append(ps.Out, nt)
|
||||
ps.CloseElement = false
|
||||
}
|
||||
case "page":
|
||||
ps.LC = 0
|
||||
ps.PC = elem.Token.Attributes["index"]
|
||||
ps.Out = append(ps.Out, defaultToken)
|
||||
nt := outToken{
|
||||
Type: Text,
|
||||
Value: "[" + ps.PC + "]",
|
||||
}
|
||||
ps.Out = append(ps.Out, nt)
|
||||
default:
|
||||
ps.Out = append(ps.Out, defaultToken)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ps.String()
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -7,4 +7,7 @@
|
||||
<a href="/brief/{{ .next.Letter }}" class="stdlink">Nächster</a>
|
||||
{{ end }}
|
||||
|
||||
{{- Safe (ParseGeneric .text.Content) -}}
|
||||
|
||||
<div class="text">
|
||||
{{- Safe (ParseGeneric .text.Content) -}}
|
||||
</div>
|
||||
|
||||
@@ -25,24 +25,16 @@
|
||||
<div>{{- .year }}</div>
|
||||
<div>({{- len $letters }})</div>
|
||||
</div>
|
||||
{{ range $l := $letters -}}
|
||||
<a href="/brief/{{ $l.Letter }}" class="">
|
||||
{{- template "_letterhead" $l -}}
|
||||
</a>
|
||||
{{- end -}}
|
||||
{{ template "_letterlist" $letters -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if .all -}}
|
||||
{{- range $y := .years -}}
|
||||
<div>
|
||||
<div class="">
|
||||
{{- $y -}}
|
||||
{{- $letters := index $model.yearmap $y -}}
|
||||
{{- len $letters }}
|
||||
{{ range $l := $letters -}}
|
||||
<a href="/brief/{{ $l.Letter }}" class="">
|
||||
{{- template "_letterhead" $l -}}
|
||||
</a>
|
||||
{{- end -}}
|
||||
<div>({{- len $letters }})</div>
|
||||
{{ template "_letterlist" $letters -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -1,34 +1,40 @@
|
||||
{{ $model := . }}
|
||||
<div>{{ $model.Letter }}</div>
|
||||
<div>{{ $model.Earliest.Text -}}</div>
|
||||
{{- range $sr := $model.SendReceivedPairs -}}
|
||||
<div>
|
||||
<div>
|
||||
{{- range $i, $p := $sr.Sent.Persons -}}
|
||||
|
||||
|
||||
<div class="flex flex-row">
|
||||
<div class="mr-4 text-6xl">{{ $model.Letter }}</div>
|
||||
<div class="pt-0.5">
|
||||
<div>{{ $model.Earliest.Text -}}</div>
|
||||
{{- range $sr := $model.SendReceivedPairs -}}
|
||||
<div class="flex flex-row">
|
||||
<div>
|
||||
{{- if $i -}}
|
||||
,
|
||||
{{ end -}}
|
||||
{{- $person := Person $p.Reference -}}
|
||||
{{- $person.Name -}}
|
||||
{{- range $i, $p := $sr.Sent.Persons -}}
|
||||
<div class="inline-block">
|
||||
{{- if $i -}}
|
||||
,
|
||||
{{ end -}}
|
||||
{{- $person := Person $p.Reference -}}
|
||||
{{- $person.Name -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
<div>an</div>
|
||||
{{- if $sr.Received -}}
|
||||
<div>
|
||||
{{- range $i, $p := $sr.Received.Persons -}}
|
||||
<div class="mx-2"><i class="ri-arrow-right-long-line"></i></div>
|
||||
{{- if $sr.Received -}}
|
||||
<div>
|
||||
{{- if $i -}}
|
||||
,
|
||||
{{ end -}}
|
||||
{{- $person := Person $p.Reference -}}
|
||||
{{- $person.Name -}}
|
||||
{{- range $i, $p := $sr.Received.Persons -}}
|
||||
<div class="inline-block">
|
||||
{{- if $i -}}
|
||||
,
|
||||
{{ end -}}
|
||||
{{- $person := Person $p.Reference -}}
|
||||
{{- $person.Name -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- else -}}
|
||||
<div>Unbekannt</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- else -}}
|
||||
<div>Unbekannt</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
|
||||
7
views/routes/components/_letterlist.gohtml
Normal file
7
views/routes/components/_letterlist.gohtml
Normal file
@@ -0,0 +1,7 @@
|
||||
{{- $letters := . }}
|
||||
|
||||
{{ range $l := $letters -}}
|
||||
<a class="block mb-2" href="/brief/{{ $l.Letter }}">
|
||||
{{- template "_letterhead" $l -}}
|
||||
</a>
|
||||
{{- end -}}
|
||||
@@ -74,4 +74,106 @@
|
||||
nav a[aria-current="page"] {
|
||||
@apply font-bold text-red-500;
|
||||
}
|
||||
|
||||
.text {
|
||||
@apply font-serif max-w-[80ch] relative;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.text .page,
|
||||
.text .line,
|
||||
.text .aq,
|
||||
.text .ul,
|
||||
.text .dul,
|
||||
.text .it,
|
||||
.text .pe,
|
||||
.text .gr,
|
||||
.text .hb,
|
||||
.text .nr,
|
||||
.text .align,
|
||||
.text .insertion,
|
||||
.text .del,
|
||||
.text .fn,
|
||||
.text .anchor {
|
||||
@apply inline-block;
|
||||
}
|
||||
|
||||
.text .aq {
|
||||
@apply font-sans;
|
||||
}
|
||||
|
||||
.text .line {
|
||||
@apply w-0;
|
||||
font-size: 0 !important;
|
||||
}
|
||||
|
||||
.text .line.tab-1 {
|
||||
@apply w-4;
|
||||
}
|
||||
|
||||
.text br.index-1 {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
.text .page {
|
||||
@apply font-sans text-sm text-gray-500;
|
||||
}
|
||||
|
||||
.text .page.index-1 {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
.text .ul {
|
||||
@apply underline;
|
||||
}
|
||||
|
||||
.text .dul {
|
||||
@apply underline decoration-double;
|
||||
}
|
||||
|
||||
.text .it {
|
||||
@apply italic;
|
||||
}
|
||||
|
||||
.text .align.pos-right {
|
||||
@apply text-right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.text .align.pos-center {
|
||||
width: max-content;
|
||||
position: relative;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.text .insertion::before {
|
||||
content: "⌞";
|
||||
}
|
||||
|
||||
.text .insertion::after {
|
||||
content: "⌟";
|
||||
}
|
||||
|
||||
.text .nr::before {
|
||||
content: "⸰";
|
||||
}
|
||||
|
||||
.text .nr::after {
|
||||
content: "⸰";
|
||||
}
|
||||
|
||||
.text .pe {
|
||||
@apply text-stone-600;
|
||||
}
|
||||
|
||||
.text .del {
|
||||
@apply line-through;
|
||||
}
|
||||
|
||||
.text .del .del::before {
|
||||
content: "";
|
||||
@apply absolute inset-x-0 top-1/2 h-px bg-black;
|
||||
top: 55%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,18 +22,22 @@ func (d *Date) Sort() *xmlparsing.XSDDate {
|
||||
if d.NotBefore.Validate() {
|
||||
return &d.NotBefore
|
||||
}
|
||||
if d.From.Validate() {
|
||||
return &d.From
|
||||
}
|
||||
if d.When.Validate() {
|
||||
return &d.When
|
||||
}
|
||||
if d.To.Validate() {
|
||||
return &d.To
|
||||
}
|
||||
|
||||
if d.NotAfter.Validate() {
|
||||
return &d.NotAfter
|
||||
}
|
||||
|
||||
if d.To.Validate() {
|
||||
return &d.To
|
||||
}
|
||||
|
||||
if d.When.Validate() {
|
||||
return &d.When
|
||||
}
|
||||
|
||||
if d.From.Validate() {
|
||||
return &d.From
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user