Initial replacement of old repository.

This commit is contained in:
Simon Martens
2021-09-15 13:31:10 +02:00
commit 3125edf027
222 changed files with 582725 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "5.0.4",
"commands": [
"dotnet-ef"
]
}
}
}

35
HaLive/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,35 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/netcoreapp2.2/HaLive.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

42
HaLive/.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,42 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/HaLive.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/HaLive.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/HaLive.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace HaLive
{
public struct Attribute
{
public string Name;
public string Value;
}
public static class HTMLHelpers
{
public static string[] MonthNames = { "", "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" };
private static Dictionary<char, int> RomanMap = new Dictionary<char, int>()
{
{'I', 1},
{'V', 5},
{'X', 10},
{'L', 50},
{'C', 100},
{'D', 500},
{'M', 1000}
};
public static int RomanToInteger(string roman)
{
var ro = roman.ToUpper();
int number = 0;
for (int i = 0; i < roman.Length; i++)
{
if (RomanMap.ContainsKey(ro[i]) && (i + 1 >= ro.Length || RomanMap.ContainsKey(ro[i + 1])))
{
if (i + 1 < ro.Length && RomanMap[ro[i]] < RomanMap[ro[i + 1]])
{
number -= RomanMap[ro[i]];
}
else
{
number += RomanMap[ro[i]];
}
}
else return 0;
}
return number;
}
public static int RomanOrNumberToInt(string number)
{
var a = 0;
if (Int32.TryParse(number, out a)) return a;
else return RomanToInteger(number);
}
public static string ToRoman(int number)
{
if ((number < 0) || (number > 3999)) return string.Empty;
if (number < 1) return string.Empty;
if (number >= 1000) return "M" + ToRoman(number - 1000);
if (number >= 900) return "CM" + ToRoman(number - 900);
if (number >= 500) return "D" + ToRoman(number - 500);
if (number >= 400) return "CD" + ToRoman(number - 400);
if (number >= 100) return "C" + ToRoman(number - 100);
if (number >= 90) return "XC" + ToRoman(number - 90);
if (number >= 50) return "L" + ToRoman(number - 50);
if (number >= 40) return "XL" + ToRoman(number - 40);
if (number >= 10) return "X" + ToRoman(number - 10);
if (number >= 9) return "IX" + ToRoman(number - 9);
if (number >= 5) return "V" + ToRoman(number - 5);
if (number >= 4) return "IV" + ToRoman(number - 4);
if (number >= 1) return "I" + ToRoman(number - 1);
return string.Empty;
}
public static string CreateElement(string elementname, string classes = "", string ids = "")
{
string res = "<" + elementname;
if (!String.IsNullOrWhiteSpace(classes))
if (elementname == "button")
res += CreateAttribute(new HaLive.Attribute() { Name = "type", Value = classes });
else
res += CreateAttribute(new HaLive.Attribute() { Name = "class", Value = classes });
if (!String.IsNullOrWhiteSpace(ids))
if (elementname == "a")
res += CreateAttribute(new HaLive.Attribute() { Name = "href", Value = ids });
else
res += CreateAttribute(new HaLive.Attribute() { Name = "id", Value = ids });
return res + ">";
}
public static string CreateCustomElement(string elementname, params HaLive.Attribute[] attributes)
{
string res = "<" + elementname;
if (!(attributes.Length == 0))
{
foreach (var attrib in attributes)
{
res += CreateAttribute(attrib);
}
}
return res + ">";
}
public static string CreateEndElement(string elementname)
=> "</" + elementname + ">";
public static string CreateAttribute(HaLive.Attribute attr)
=> " " + attr.Name + "=\"" + attr.Value + "\" ";
public static string CreateEmptyElement(string elementname, string classes = "", string ids = "")
{
string res = "<" + elementname;
if (!String.IsNullOrWhiteSpace(classes))
res += CreateAttribute(new HaLive.Attribute() { Name = "class", Value = classes });
if (!String.IsNullOrWhiteSpace(ids))
res += CreateAttribute(new HaLive.Attribute() { Name = "id", Value = ids });
return res + "></" + elementname + ">";
}
public static string GetEnumerationString(List<string> strlist)
{
var res = "";
foreach (var str in strlist)
{
if (str != strlist.First())
if (str == strlist.Last())
res += " und " + str;
else
res += ", " + str;
else
res += str;
}
return res;
}
}
}

View File

@@ -0,0 +1,123 @@
using HaDocument.Interfaces;
using HaDocument.Models;
using System;
using System.Text;
using HaXMLReader.Interfaces;
using HaXMLReader.EvArgs;
using HaXMLReader;
using System.Collections.Generic;
namespace HaLive {
public class LinkBuilder {
private ILibrary _lib;
private IReader _reader;
private StringBuilder _sb;
private bool _followlinksinchildren;
private bool _followlinksinthis;
public LinkBuilder(ILibrary lib, IReader reader, StringBuilder stringBuilder, bool followlinksinchildren = true, bool followlinksinthis = true) {
if (lib == null || reader == null || stringBuilder == null) throw new ArgumentNullException();
_lib = lib;
_reader = reader;
_sb = stringBuilder;
_followlinksinchildren = followlinksinchildren;
_followlinksinthis = followlinksinthis;
reader.Tag += OnTag;
}
private void OnTag(object _, Tag tag) {
if (tag.Name == "wwwlink" || tag.Name == "intlink" || tag.Name == "link") {
if (tag.EndTag && _followlinksinthis) {
_sb.Append(HTMLHelpers.CreateEndElement("a"));
}
else {
if (tag.Name == "wwwlink" && tag.Values.ContainsKey("address") && _followlinksinthis)
_sb.Append(HTMLHelpers.CreateCustomElement("a",
new HaLive.Attribute() { Name = "class", Value = "hlink wwwlink invlink" },
new HaLive.Attribute() { Name = "href", Value = tag["address"]},
new HaLive.Attribute() { Name = "target", Value = "_blank"},
new HaLive.Attribute() { Name = "rel", Value = "noopener noreferrer"}));
if (tag.Name == "intlink" && tag.Values.ContainsKey("letter") && _lib.Metas.ContainsKey(tag["letter"])) {
var letter = _lib.Metas[tag["letter"]];
_sb.Append(HTMLHelpers.CreateElement("a", "hlink intlink invlink", "/Briefe/" + letter.Autopsic + "#" + tag["page"] + "-" + tag["line"]));
if (!tag.Values.ContainsKey("linktext") || tag.Values["linktext"] == "true") {
var linkstring = "";
var ZHstring = "";
var pglnstring= "";
linkstring += "HKB&nbsp;" + letter.Autopsic;
if (tag.Values.ContainsKey("page")) {
pglnstring += tag["page"];
if (tag.Values.ContainsKey("line")) {
pglnstring += "/" + tag["line"];
}
if (letter.ZH != null)
ZHstring += HTMLHelpers.ToRoman(Int32.Parse(letter.ZH.Volume)) + "&nbsp;";
linkstring += "&nbsp;(&#8239;";
linkstring += ZHstring;
linkstring += pglnstring;
linkstring += "&#8239;)";
}
_sb.Append(linkstring);
}
}
if (tag.Name == "link" && tag.Values != null) {
Comment comment = null;
if (tag.Values.ContainsKey("subref") && _lib.SubCommentsByID.ContainsKey(tag["subref"]))
comment = _lib.SubCommentsByID[tag["subref"]];
else if (tag.Values.ContainsKey("ref"))
if (_lib.Comments.ContainsKey(tag["ref"]))
comment = _lib.Comments[tag["ref"]];
else if (_lib.SubCommentsByID.ContainsKey(tag["ref"]))
comment = _lib.SubCommentsByID[tag["ref"]];
if (comment != null) {
var linkloc = String.IsNullOrWhiteSpace(comment.Parent) ? comment.Index : comment.Parent;
if (_followlinksinthis)
if (comment.Type == "neuzeit")
_sb.Append(HTMLHelpers.CreateElement("a", "hlink link invlink", "/Supplementa/Register/" + linkloc[0] + "#" + comment.Index));
else if (comment.Type == "bibel")
_sb.Append(HTMLHelpers.CreateElement("a", "hlink link invlink", "/Supplementa/Bibelstellen/" + linkloc[0] + linkloc[1] + "#" + comment.Index));
else if (comment.Type == "forschung")
_sb.Append(HTMLHelpers.CreateElement("a", "hlink link invlink", "/Supplementa/Forschung/" + linkloc[0] + "#" + comment.Index));
_sb.Append(GetLemmaString(tag, comment));
}
}
if (tag.IsEmpty && _followlinksinthis) _sb.Append(HTMLHelpers.CreateEndElement("a"));
}
}
}
private string GetLemmaString(Tag tag, Comment comment) {
if (!tag.Values.ContainsKey("linktext") || tag.Values["linktext"] == "true") {
var sb = new StringBuilder();
var subreader = new UTF8StringReader(comment.Lemma);
new LinkBuilder(_lib, subreader, sb, _followlinksinchildren, _followlinksinchildren);
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> OTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "lemma", (strbd, x) => strbd.Append(HTMLHelpers.CreateElement("div", "reference")) ),
( x => x.Name == "titel", (strbd, x) => strbd.Append(HTMLHelpers.CreateElement("span", "title")) )
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> CTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "lemma", (strbd, x) => strbd.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "titel", (strbd, x) => strbd.Append(HTMLHelpers.CreateEndElement("span")) )
};
List<(Func<Text, bool>, Action<StringBuilder, Text>)> Text_Funcs = new List<(Func<Text, bool>, Action<StringBuilder, Text>)>() {
( x => true, (strbd, txt) => strbd.Append(txt.Value))
};
new StandardSubscriber(subreader, sb, OTag_Funcs, null, CTag_Funcs, Text_Funcs, null);
subreader.Read();
return sb.ToString();
}
return "";
}
public void Dispose() {
if (_reader != null)
_reader.Tag -= OnTag;
}
~LinkBuilder() {
Dispose();
}
}
}

77
HaLive/Classes/Search.cs Normal file
View File

@@ -0,0 +1,77 @@
using HaDocument.Models;
using HaDocument.Interfaces;
using HaDocument.Comparers;
using HaXMLReader.Interfaces;
using HaLive.Models;
using HaXMLReader.EvArgs;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
using System.Linq;
using System;
namespace HaLive {
internal class DocumentSearch {
internal DocumentSearchResult _searchResult { get; }
private IReader _reader { get; }
private string _search { get; }
internal DocumentSearch(DocumentSearchResult res, IReader reader, string search) {
_searchResult = res;
_reader = reader;
_search = search;
_pg = "";
}
internal DocumentSearchResult Act() {
_reader.Text += OnText;
_reader.SingleTag += OnSTag;
_reader.Read();
return _searchResult;
}
internal void OnText(object _, Text text) {
if (text.Value.ToLower().Contains(_search.ToLower())) {
_searchResult.Results.Add(new DocumentResult(text.Value, _pg, _ln));
}
}
private string _pg;
private string _ln;
internal void OnSTag(object _, Tag tag) {
if (tag.Name == "page")
_pg = tag["index"];
else if (tag.Name == "line")
_ln = tag["index"];
}
}
internal class RegisterSearch {
internal Comment _searchResult { get; }
private IReader _reader { get; }
private string _search { get; }
private bool found;
internal RegisterSearch(Comment res, IReader reader, string search) {
_searchResult = res;
_reader = reader;
_search = search;
found = false;
}
internal bool Act() {
_reader.Text += OnText;
_reader.Read();
return found;
}
internal void OnText(object _, Text text) {
if (text.Value.ToLower().Contains(_search.ToLower())) {
found = true;
}
}
}
}

View File

@@ -0,0 +1,102 @@
using HaXMLReader.Interfaces;
using HaXMLReader.EvArgs;
using System.Text;
using System.Collections.Generic;
using System;
namespace HaLive {
public class StandardSubscriber {
private IReader _in;
private StringBuilder _target;
private List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> _OTag_Funcs;
private List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> _STag_Funcs;
private List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> _CTag_Funcs;
private List<(Func<Text, bool>, Action<StringBuilder, Text>)> _Text_Funcs;
private List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)> _WS_Funcs;
private bool _deleteLeadingWS;
private bool _deleteTrailingWS;
public StandardSubscriber(
IReader input,
StringBuilder target,
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> OTag_Funcs = null,
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> STag_Funcs = null,
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> CTag_Funcs = null,
List<(Func<Text, bool>, Action<StringBuilder, Text>)> Text_Funcs = null,
List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)> WS_Funcs = null,
bool deleteLeadingWS = false,
bool deleteTrailingWS = false
) {
if (input == null || target == null) throw new ArgumentNullException();
_in = input;
_target = target;
_deleteLeadingWS = deleteLeadingWS;
_deleteTrailingWS = deleteTrailingWS;
_OTag_Funcs = OTag_Funcs;
_STag_Funcs = STag_Funcs;
_CTag_Funcs = CTag_Funcs;
_Text_Funcs = Text_Funcs;
_WS_Funcs = WS_Funcs;
if (_OTag_Funcs != null)
_in.OpenTag += OnOTag;
if (_STag_Funcs != null)
_in.SingleTag += OnSTag;
if (_CTag_Funcs != null)
_in.CloseTag += OnCTag;
if (_Text_Funcs != null)
_in.Text += OnText;
if (_WS_Funcs != null)
_in.Whitespace += OnWS;
}
void OnOTag(object _, Tag tag) {
foreach(var entry in _OTag_Funcs)
if (entry.Item1(tag)) entry.Item2(_target, tag);
}
void OnText(object _, Text text) {
if (_deleteLeadingWS) text.Value = text.Value.TrimStart();
if (_deleteTrailingWS) text.Value = text.Value.TrimEnd();
foreach(var entry in _Text_Funcs)
if (entry.Item1(text)) entry.Item2(_target, text);
}
void OnSTag(object _, Tag tag) {
foreach(var entry in _STag_Funcs)
if (entry.Item1(tag)) entry.Item2(_target, tag);
}
void OnCTag (object _, Tag tag) {
foreach (var entry in _CTag_Funcs)
if (entry.Item1(tag)) entry.Item2(_target, tag);
}
void OnWS (object _, Whitespace ws) {
foreach (var entry in _WS_Funcs) {
if (entry.Item1(ws)) entry.Item2(_target, ws);
}
}
internal void Dispose() {
if (_in != null) {
if (_OTag_Funcs != null)
_in.OpenTag -= OnOTag;
if (_STag_Funcs != null)
_in.SingleTag -= OnSTag;
if (_CTag_Funcs != null)
_in.CloseTag -= OnCTag;
if (_Text_Funcs != null)
_in.Text -= OnText;
if (_WS_Funcs != null)
_in.Whitespace -= OnWS;
}
}
~StandardSubscriber() {
Dispose();
}
}
}

43
HaLive/HaLive.csproj Normal file
View File

@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<RazorCompileOnBuild>false</RazorCompileOnBuild>
<RazorCompileOnPublish>false</RazorCompileOnPublish>
<UserSecretsId>291b4748-5f17-4dbc-8b79-f8aba08bd32b</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<None Remove="Hamann.xml" />
</ItemGroup>
<ItemGroup>
<Content Include="Hamann.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<Folder Include="Interfaces\" />
</ItemGroup>
<ItemGroup>
<!-- extends watching group to include *.xml files -->
<Watch Include="**\*.xml" Exclude="obj\**\*;bin\**\*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\HaXMLReader\HaXMLReader.csproj" />
<ProjectReference Include="..\HaDocument\HaDocument.csproj" />
</ItemGroup>
</Project>

220893
HaLive/Hamann.xml Normal file

File diff suppressed because it is too large Load Diff

14
HaLive/Models/MenuItem.cs Normal file
View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace HaLive.Models
{
public abstract class MenuItem
{
public string FriendlyName { get; set; }
public string DefaultRoute { get; set; }
public bool Active { get; set; } = false;
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace HaLive.Models
{
public class MenuPageItem : MenuItem
{
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace HaLive.Models
{
public class MenuSubMenuItem : MenuItem
{
public List<MenuPageItem> menuPages { get; set; }
}
}

View File

@@ -0,0 +1,37 @@
using HaDocument.Models;
using HaDocument.Comparers;
using HaDocument.Interfaces;
using System.Collections.Generic;
namespace HaLive.Models {
public class DocumentSearchResult {
public Meta MetaData { get; }
public List<DocumentResult> Results { get; }
public DocumentSearchResult(Meta meta) {
MetaData = meta;
Results = new List<DocumentResult>(4);
}
}
public class DocumentResult {
public string PreviewString { get; }
public string Page { get; }
public string Line { get; }
public DocumentResult(string previewstring, string page, string line) {
PreviewString = previewstring;
Page = page;
Line = line;
}
}
public class LetterComparer : IComparer<DocumentSearchResult>
{
public int Compare(DocumentSearchResult first, DocumentSearchResult second)
{
var cmp = new DefaultComparer();
return cmp.Compare(first.MetaData, second.MetaData);
}
}
}

641
HaLive/Pages/Briefe.cshtml Normal file
View File

@@ -0,0 +1,641 @@
@page "{id?}"
@using System.Linq;
@using System.Threading.Tasks;
@using System.Collections.Generic;
@using System.Threading;
@using System.Linq:
@using System.Xml.Linq;
@model HaLive.Pages.BriefeModel
@inject IReaderService readerService
@inject ILibrary lib
@{
// Acquire data
ViewData["Title"] = "Brief";
var meta = lib.Metas.Where(x => x.Value.Autopsic == Model.id).First().Value;
var id = meta.Index;
var letter = lib.Letters[id];
var marginals = lib.MarginalsByLetter.Contains(id) ? lib.MarginalsByLetter[id] : null;
var tradition = lib.Traditions.ContainsKey(id) ? lib.Traditions[id] : null;
var editreasons = lib.EditreasonsByLetter.Contains(id) ? lib.EditreasonsByLetter[id].OrderBy(x => HTMLHelpers.RomanOrNumberToInt(x.StartPage)).ThenBy(x => HTMLHelpers.RomanOrNumberToInt(x.StartLine)) : null;
var senders = HTMLHelpers.GetEnumerationString(meta.Senders.Select(x => lib.Persons[x].Name).ToList());
var receivers = HTMLHelpers.GetEnumerationString(meta.Receivers.Select(x => lib.Persons[x].Name).ToList());
var next = meta == lib.MetasByDate.Last() ? null : lib.MetasByDate.ItemRef(lib.MetasByDate.IndexOf(meta) + 1);
var prev = meta == lib.MetasByDate.First() ? null : lib.MetasByDate.ItemRef(lib.MetasByDate.IndexOf(meta) - 1);
var hands = lib.Hands.ContainsKey(id) ? lib.Hands[id] : null;
var filename = "" + "_" + meta.Autopsic + "_HamannBriefe.pdf"; // TODO
// State
var currline = "-1";
var currpage = "";
var oldpage = "";
var commid = 1;
var firstedit = true;
var active_trad = false;
var skipwhitespace = true;
List<string> handstrings = new List<string>();
// Parsing-Combinations
var sb_lettertext = new StringBuilder(); // Hauptext
var sb_linecount = new StringBuilder(); // Linke Spalte (Zeilenzählung)
var sb_marginals = new StringBuilder(); // Rechte Spalte (Kommentare)
var sb_tradition = new StringBuilder(); // Überlieferung
var sb_trad_zhtext = new StringBuilder(); // Überlieferung, ZHText
var sb_trad_left = new StringBuilder(); // Überlieferung ZHText linke Spalte (zeilenzählung)
var sb_trad_right = new StringBuilder(); // Überlieferung ZHText rechte Spalte (Kommentare)
var sb_edits = new StringBuilder(); // Edits
var rd_lettertext = readerService.RequestStringReader(letter.Element); // Liest den Brieftext
var rd_tradition = tradition != null && !String.IsNullOrWhiteSpace(tradition.Element) ? readerService.RequestStringReader(tradition.Element) : null; // Liest die Überlieferung
// Initialize State
if (meta.ZH != null) {
currpage = meta.ZH.Page;
}
if (hands != null) {
foreach (var hand in hands.OrderBy(x => x.StartPage.Length).ThenBy(x => x.StartPage).ThenBy(x => x.StartLine.Length).ThenBy(x => x.StartLine)) {
var currstring = hand.StartPage + "/" + hand.StartLine;
if (hand.StartPage != hand.EndPage) {
currstring += "" + hand.EndPage + "/" + hand.EndLine;
}
else {
if (hand.StartLine != hand.EndLine) {
currstring += "" + hand.EndLine;
}
}
if (lib.HandPersons.Where(x => x.Key == hand.Person).Any()) {
currstring += " " + lib.HandPersons.Where(x => x.Key == hand.Person).FirstOrDefault().Value.Name;
handstrings.Add(currstring);
}
}
}
// Parsing Rules
// General rules (for the lettertext column, also for parsing the marginals, awa tradtions and editreasons)
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> OTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "align" && x["pos"] == "center", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "align center")) ),
( x => x.Name == "align" && x["pos"] == "right", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "align right")) ),
( x => x.Name == "added", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "added")) ),
( x => x.Name == "sal", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "sal")) ),
( x => x.Name == "aq", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "aq")) ),
( x => x.Name == "super", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "super")) ),
( x => x.Name == "del", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "del")) ),
( x => x.Name == "nr", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "nr")) ),
( x => x.Name == "note", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "note")) ),
( x => x.Name == "ul", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "ul")) ),
( x => x.Name == "anchor" && !String.IsNullOrWhiteSpace(x["ref"]), (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "anchor")) ),
( x => x.Name == "fn" && !String.IsNullOrWhiteSpace(x["index"]), (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "footnote")) ),
( x => x.Name == "dul", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "dul")) ),
( x => x.Name == "ful", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "ful")) ),
( x => x.Name == "up", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "up")) ),
( x => x.Name == "sub", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("sub")) ),
( x => x.Name == "tul", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "tul")) ),
( x => x.Name == "header", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "header")) ),
( x => x.Name == "lemma", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "lemma")) ),
( x => x.Name == "eintrag", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "entry")) ),
( x => x.Name == "titel", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "title")) ),
( x => x.Name == "bzg", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "bzg")) ),
( x => x.Name == "zh", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("span", "zh")) ),
( x => x.Name == "emph", (sb, tag) => { sb.Append(HTMLHelpers.CreateElement("em")); } ),
( x => x.Name == "app", (sb, tag) => { sb.Append(HTMLHelpers.CreateElement("span", "app")); } ),
( x => x.Name == "subsection", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "subcomment", tag["id"])) ),
( x => x.Name == "kommentar", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "comment", tag["id"])) ),
( x => x.Name == "editreason", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "editreason")) ),
( x => x.Name == "subsection", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "letter")) ),
( x => x.Name == "letterTradition", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "tradition")) ),
( x => x.Name == "marginal", (sb, tag) => {
sb.Append(HTMLHelpers.CreateElement("div", "marginal"));
skipwhitespace = !skipwhitespace;
}),
( x => x.Name == "hand", (sb, tag) => {
sb.Append(HTMLHelpers.CreateElement("span", "hand"));
} ),
( x => x.Name == "tabs", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "htable")) ),
( x => x.Name == "tab" && !String.IsNullOrWhiteSpace(x["value"]), (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "htab htab-" + tag["value"])))
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> CTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "align", (sb, tag) => {
sb.Append(HTMLHelpers.CreateEndElement("div"));
} ),
( x => x.Name == "added", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "sal", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "aq", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "super", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "del", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "nr", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "note", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "ul", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "anchor", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "fn", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "dul", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "up", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "ful", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "sub", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("sub")) ),
( x => x.Name == "tul", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "header", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "lemma", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "eintrag", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "titel", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "bzg", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "zh", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "emph", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("em")) ),
( x => x.Name == "app", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("span")) ),
( x => x.Name == "subsection", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "kommentar", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "editreason", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "subsection", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "letterTradition", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "marginal", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "tabs", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "tab", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")) ),
( x => x.Name == "hand", (sb, tag) => {
sb.Append(HTMLHelpers.CreateEndElement("span"));
} )
};
List<(Func<Text, bool>, Action<StringBuilder, Text>)> Text_Funcs = new List<(Func<Text, bool>, Action<StringBuilder, Text>)>() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
List<(Func<Text, bool>, Action<StringBuilder, Text>)> Text_Funcs_Tagging = new List<(Func<Text, bool>, Action<StringBuilder, Text>)>() {
( x => true, ( sb, txt ) => {
sb.Append(HTMLHelpers.CreateElement("span", "ntext"));
sb.Append(txt.Value);
sb.Append(HTMLHelpers.CreateEndElement("span"));
} )
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> STag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "line", (sb, tag) => {
if(currline != "-1") sb.Append(HTMLHelpers.CreateElement("br", "ZHBreak"));
if(tag["type"] == "line") sb.Append(HTMLHelpers.CreateElement("hr", "lineline"));
} ),
( x => x.Name == "line" && !String.IsNullOrWhiteSpace(x["tab"]), (sb, tag) => {
sb.Append(HTMLHelpers.CreateElement("span", "tab-" + tag["tab"]));
sb.Append(HTMLHelpers.CreateEndElement("span"));
} )
};
List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)> Whitespace_Funcs = new List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)>() {
( x => true, ( sb, txt ) => {
if (skipwhitespace)
sb.Append(txt.Value);
else
skipwhitespace = !skipwhitespace;
})
};
// Rules for the left sidebar
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> STag_Funcs_LEFT = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "line", (sb, tag) => {
if(currline != "-1") {
if (currpage == oldpage)
sb.Append(HTMLHelpers.CreateElement("br", "", currpage + "-" + currline));
else {
sb.Append(HTMLHelpers.CreateElement("br", "", oldpage + "-" + currline));
oldpage = currpage;
}
}
else {
sb.Append(HTMLHelpers.CreateElement("span", "zhpage firstpage", currpage + "-" + tag["index"]));
sb.Append("S." + "&nbsp;");
sb.Append(HTMLHelpers.CreateEndElement("span"));
if (tag["index"] != "1")
sb.Append(currpage + "&thinsp;/&thinsp;" + tag["index"]);
else
sb.Append(currpage);
oldpage = currpage;
}
}
),
( x => x.Name == "line", (sb, tag) => { if(currline != "-1" && Int32.TryParse(tag["index"], out var _) && Int32.Parse(tag["index"]) % 5 == 0) { sb.Append(tag["index"]); } } ),
( x => x.Name == "line" && x["index"] == "1" && currline != "-1", (sb, tag) => {
sb.Append(HTMLHelpers.CreateElement("span", "zhpage", ""));
sb.Append("S. " + currpage);
sb.Append(HTMLHelpers.CreateEndElement("span"));
}),
( x => x.Name == "line", (sb, tag) => { currline = tag["index"]; } ),
( x => x.Name == "page", (sb, tag) => { currpage = tag["index"]; } )
};
// Rules for the right sidebar
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> STag_Funcs_RIGHT = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "line", (sb, tag) => {
if(currline != "-1" && marginals != null) {
var margs = marginals.Where(x => x.Page == currpage && x.Line == currline);
if (margs != null && margs.Any())
{
margs = margs.OrderBy(x => Int32.Parse(x.Index));
sb.Append(HTMLHelpers.CreateElement("div", "commBox", commid.ToString()));
sb.Append(HTMLHelpers.CreateElement("div", "commselector"));
sb.Append(HTMLHelpers.CreateElement("button", "button"));
sb.Append(HTMLHelpers.CreateEndElement("button"));
sb.Append(HTMLHelpers.CreateEndElement("div"));
sb.Append(HTMLHelpers.CreateElement("div", "comment"));
foreach (var marginal in margs)
{
var rd = readerService.RequestStringReader(marginal.Element);
new StandardSubscriber(rd, sb, OTag_Funcs, null, CTag_Funcs, Text_Funcs_Tagging, Whitespace_Funcs);
new LinkBuilder(lib, rd, sb, false);
rd.Read();
}
sb.Append(HTMLHelpers.CreateEndElement("div"));
sb.Append(HTMLHelpers.CreateEndElement("div"));
sb.Append(HTMLHelpers.CreateElement("br"));
}
else
{
sb.Append(HTMLHelpers.CreateElement("br", "emptyline"));
}
}
commid++;
}
)};
// Rules for traditions
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> OTag_Funcs_Trad = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "app", (sb, tag) => { if (!firstedit) { sb.Append(HTMLHelpers.CreateElement("br")); } else { firstedit = false; } } ),
( x => x.Name == "ZHText", (sb, tag) => {
sb_tradition.Append(HTMLHelpers.CreateElement("div", "row zhtext"));
sb_tradition.Append(HTMLHelpers.CreateElement("div", "trad-text col order-2 letterbox"));
sb_trad_left = new StringBuilder();
sb_trad_right = new StringBuilder();
currline = "-1";
currpage = "";
active_trad = true;
sb_trad_left.Append(HTMLHelpers.CreateElement("div", "trad-linecount countbox nnumber d-none d-lg-block order-1"));
sb_trad_right.Append(HTMLHelpers.CreateElement("div", "commentColumn trad-comm col-4 d-none d-lg-block order-3"));
sb_trad_right.Append(HTMLHelpers.CreateElement("br", "emptyline"));
new StandardSubscriber(rd_tradition, sb_trad_left, null, STag_Funcs_LEFT);
new StandardSubscriber(rd_tradition, sb_trad_right, null, STag_Funcs_RIGHT);
} )
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> CTag_Funcs_Trad = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "ZHText", (sb, tag) => {
sb_tradition.Append(HTMLHelpers.CreateEndElement("div"));
sb_trad_left.Append(HTMLHelpers.CreateEndElement("div"));
sb_trad_right.Append(HTMLHelpers.CreateEndElement("div"));
sb_tradition.Append(sb_trad_left.ToString());
sb_tradition.Append(sb_trad_right.ToString());
sb_tradition.Append(HTMLHelpers.CreateEndElement("div"));
active_trad = false;
} )
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> STags_Funcs_TRAD = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "line", (sb, tag) => { if(currline != "-1" || !active_trad) sb.Append(HTMLHelpers.CreateElement("br", "ZHBreak")); } ),
( x => x.Name == "line" && !String.IsNullOrWhiteSpace(x["tab"]), (sb, tag) => {
sb.Append(HTMLHelpers.CreateElement("span", "tab-" + tag["tab"]));
sb.Append(HTMLHelpers.CreateEndElement("span"));
} )
};
// Rules for Edits:
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> STags_Funcs_EDIT = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "line", (sb, tag) => sb.Append("&emsp;") )
};
// Functionms for Parsing:
string HandleEdit(Editreason edit) {
sb_edits.Append(HTMLHelpers.CreateElement("div", "edit"));
sb_edits.Append(HTMLHelpers.CreateElement("span", "pageline"));
var currstring = edit.StartPage + "/" + edit.StartLine;
if (edit.StartPage != edit.EndPage) {
currstring += "" + edit.EndPage + "/" + edit.EndLine;
}
else {
if (edit.StartLine != edit.EndLine) {
currstring += "" + edit.EndLine;
}
}
sb_edits.Append(currstring + "&emsp;");
sb_edits.Append(HTMLHelpers.CreateEndElement("span"));
if (!String.IsNullOrWhiteSpace(edit.Reference)) {
var sb2 = new StringBuilder();
sb2.Append(HTMLHelpers.CreateElement("span", "reference"));
var rd = readerService.RequestStringReader(edit.Reference);
new StandardSubscriber(rd, sb2, OTag_Funcs, null, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
rd.Read();
sb2.Append(HTMLHelpers.CreateEndElement("span"));
if ((edit.StartPage != edit.EndPage || edit.StartLine != edit.EndLine) && XElement.Parse(sb2.ToString()).Value.ToString().Length >= 60)
{
var text = XElement.Parse(sb2.ToString()).Value.ToString();
text = text.ToString().Split(' ').Take(1).First() + " [&#x2026;] " + text.ToString().Split(' ').TakeLast(1).First();
sb_edits.Append(HTMLHelpers.CreateElement("span", "reference"));
sb_edits.Append(text);
sb_edits.Append(HTMLHelpers.CreateEndElement("span"));
}
else
sb_edits.Append(sb2);
@* MIT FORMATIERUNGEN: if (edit.StartPage != edit.EndPage || edit.StartLine != edit.EndLine)
{
var text1 = XElement.Parse(sb2.ToString());
var text2 = new XElement(text1);
if (!String.IsNullOrWhiteSpace(text1.Value)) {
text1.DescendantNodes().Where(x => x.NodeType == System.Xml.XmlNodeType.Text && !String.IsNullOrWhiteSpace(x.ToString())).Skip(1).Remove();
text2.DescendantNodes().Where(x => x.NodeType == System.Xml.XmlNodeType.Text && !String.IsNullOrWhiteSpace(x.ToString())).SkipLast(1).Remove();
var element1 = text1.DescendantNodes().Where(x => x.NodeType == System.Xml.XmlNodeType.Text && !String.IsNullOrWhiteSpace(x.ToString())).Any() ?
text1.DescendantNodes().Where(x => x.NodeType == System.Xml.XmlNodeType.Text && !String.IsNullOrWhiteSpace(x.ToString())).First().Parent :
null;
var element2 = text2.DescendantNodes().Where(x => x.NodeType == System.Xml.XmlNodeType.Text && !String.IsNullOrWhiteSpace(x.ToString())).Any() ?
text2.DescendantNodes().Where(x => x.NodeType == System.Xml.XmlNodeType.Text && !String.IsNullOrWhiteSpace(x.ToString())).Last().Parent :
null;
element1.Value = element1.Value.ToString().Split(' ').Take(1).First();
element2.Value = element2.Value.ToString().Split(' ').TakeLast(1).First();
text1.DescendantNodes().Where(x =>
(x.NodeType == System.Xml.XmlNodeType.Element && String.IsNullOrWhiteSpace(((XElement)x).Value.ToString())) ||
(x.NodeType == System.Xml.XmlNodeType.Text && String.IsNullOrWhiteSpace(x.ToString())) ||
(x.NodeType == System.Xml.XmlNodeType.Whitespace)
).Remove();
text2.DescendantNodes().Where(x =>
(x.NodeType == System.Xml.XmlNodeType.Element && String.IsNullOrWhiteSpace(((XElement)x).Value.ToString())) ||
(x.NodeType == System.Xml.XmlNodeType.Text && String.IsNullOrWhiteSpace(x.ToString())) ||
(x.NodeType == System.Xml.XmlNodeType.Whitespace)
).Remove();
sb_edits.Append(text1.ToString().Trim());
sb_edits.Append(" [&#x2026;] ");
sb_edits.Append(text2.ToString().Trim());
}
}
else
sb_edits.Append(sb2); *@
}
if (!String.IsNullOrWhiteSpace(edit.Element)) {
sb_edits.Append("&emsp;");
sb_edits.Append(HTMLHelpers.CreateElement("span", "corrections"));
var rd = readerService.RequestStringReader(edit.Element);
new StandardSubscriber(rd, sb_edits, OTag_Funcs, STags_Funcs_EDIT, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
rd.Read();
sb_edits.Append(HTMLHelpers.CreateEndElement("span"));
}
sb_edits.Append(HTMLHelpers.CreateEndElement("div"));
return sb_edits.ToString();
}
// Actual parsing
if (letter.Element != null && !String.IsNullOrWhiteSpace(letter.Element) && rd_lettertext != null) {
new StandardSubscriber(rd_lettertext, sb_lettertext, OTag_Funcs, STag_Funcs, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
new StandardSubscriber(rd_lettertext, sb_linecount, null, STag_Funcs_LEFT);
if (marginals != null && marginals.Any()) {
new StandardSubscriber(rd_lettertext, sb_marginals, null, STag_Funcs_RIGHT);
}
rd_lettertext.Read();
}
if (tradition != null && !String.IsNullOrWhiteSpace(tradition.Element) && rd_tradition != null) {
new StandardSubscriber(rd_tradition, sb_tradition, OTag_Funcs_Trad, null, CTag_Funcs_Trad, null, null);
new StandardSubscriber(rd_tradition, sb_tradition, OTag_Funcs, STags_Funcs_TRAD, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
new LinkBuilder(lib, rd_tradition, sb_tradition);
rd_tradition.Read();
}
if (editreasons != null && editreasons.Any()) {
foreach (var edit in editreasons) {
HandleEdit(edit);
}
}
}
<div class="mainhead no-gutters row"> <!-- + sticky-top if sticky -->
<div class="col">
<div class="widehead letterbar">
<div class="flexcol">
<div style="align-self: flex-end" class="printbutton">
<span class="label">
<a class="hlink" href="/pdf/@filename">
PDF&nbsp;<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="bi bi-arrow-down-circle" viewBox="0 0 14 18">
<path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/>
</svg>
</a>
</span>
</div>
<div class="lettercard flexrow">
<div class="nnumber letcount">
@meta.Autopsic
</div>
@if(!String.IsNullOrWhiteSpace(sb_lettertext.ToString()))
{
<div class="letdesc">
<span class="date">
@meta.Date
</span>&nbsp;
@if (meta.ZH != null) {
<span>
<span class="nnumber autopsic">&thinsp;
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" class="bi bi-book" viewBox="0 0 16 18">
<path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811V2.828zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783z"/>
</svg>
ZH @HTMLHelpers.ToRoman(Int32.Parse(meta.ZH.Volume)) @meta.ZH.Page
</span>&nbsp;
</span>
}
else
{
<span>
<span class="nnumber autopsic-new">
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="currentColor" class="bi bi-asterisk" viewBox="0 0 16 20">
<path d="M8 0a1 1 0 0 1 1 1v5.268l4.562-2.634a1 1 0 1 1 1 1.732L10 8l4.562 2.634a1 1 0 1 1-1 1.732L9 9.732V15a1 1 0 1 1-2 0V9.732l-4.562 2.634a1 1 0 1 1-1-1.732L6 8 1.438 5.366a1 1 0 0 1 1-1.732L7 6.268V1a1 1 0 0 1 1-1z"/>
</svg>
Neu
</span>&nbsp;
</span>
}
@if(meta.hasOriginal == OptionalBool.True)
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Original vorhanden">
&thinsp;Orig
</span>&nbsp;
</span>
}
else
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Original verschollen">
&thinsp;<span class="cross">Orig</span>
</span>&nbsp;
</span>
}
@if (meta.ZH != null && meta.ZH.dateChanged)
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Der Brief wurde gegenüber der Ausgabe ZH neu datiert">
&thinsp;neu datiert
</span>&nbsp;
</span>
}
@if(meta.isProofread == OptionalBool.True)
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Textkritisch geprüft">
&thinsp;geprüft
</span>&nbsp;
</span>
}
else
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Nicht textkritisch geprüft">
&thinsp;<span class="cross">geprüft</span>
</span>&nbsp;
</span>
}
@if (lib.MarginalsByLetter.Contains(meta.Index))
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Mit Stellenkommentar">
&thinsp;Komm
</span>&nbsp;
</span>
}
<br>
<span class="title">
@if (meta.Senders.Intersect(meta.Receivers).Any())
{
@for (int i = 0; i < meta.Senders.Count; i++)
{
@Html.Raw(lib.Persons[meta.Senders.ElementAt(i)].Name);
@if(meta.isDraft == OptionalBool.True)
{
<span data-bs-toggle="tooltip" data-bs-placement="bottom" title="Entwurf">&nbsp;&#8603;&nbsp;</span>
}
else
{
<span>&nbsp;&#8594;&nbsp;</span>
}
@Html.Raw(lib.Persons[meta.Receivers.ElementAt(i)].Name);
<br>
}
}
else
{
@HTMLHelpers.GetEnumerationString(meta.Senders.Select(x => lib.Persons[x].Name).ToList())
@if(meta.isDraft == OptionalBool.True)
{
<span data-bs-toggle="tooltip" data-bs-placement="bottom" title="Entwurf">&nbsp;&#8603;&nbsp;</span>
}
else
{
<span>&nbsp;&#8594;&nbsp;</span>
}
@HTMLHelpers.GetEnumerationString(meta.Receivers.Select(x => lib.Persons[x].Name).ToList())
}
</div>
}
else
{
<span>&nbsp;</span>
}
</span>
</div>
<div class="metas" style="align-self: flex-end">
@if(prev != null)
{
<a class="hlink invlink" href="/Briefe/@prev.Autopsic" >@prev.Autopsic &#x25C0;</a>
}
HKB
@if(next != null)
{
<a class="hlink invlink" href="/Briefe/@next.Autopsic">&#x25B6; @next.Autopsic</a>
}
</div>
</div>
</div>
</div>
</div>
@if(!String.IsNullOrWhiteSpace(sb_lettertext.ToString()))
{
<div class="row no-gutters">
<div class="col">
<div class="flexrow h-100">
<div class="countbox nnumber d-none d-lg-block">
@Html.Raw(sb_linecount.ToString())
<br>
</div>
<div class="letterbox">
@Html.Raw(sb_lettertext.ToString())
</div>
</div>
</div>
@if(marginals != null && marginals.Any())
{
<div class="col-4 d-none d-lg-block">
<div class="commentColumn">
@Html.Raw(sb_marginals.ToString())
</div>
</div>
} else
{
<div class="col-4 NoCommentColumn"></div>
}
</div>
}
@* <div class="row no-gutters dividerrow">
</div> *@
<div class="row no-gutters additions">
<div class="flexol additionbox">
@if(rd_tradition != null && !String.IsNullOrWhiteSpace(tradition.Element))
{
<div class="traditions">
@Html.Raw(sb_tradition.ToString())
</div>
}
@if (hands != null)
{
<div class="hands">
<br>
<span class="app">Zusätze fremder Hand:</span>
@foreach (var hand in handstrings)
{
<br>
@Html.Raw(hand)
}
</div>
}
@if (editreasons != null)
{
<div class="edits">
<br>
<span class="app">Textkritische Anmerkungen <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 20" data-bs-toggle="tooltip" data-bs-placement="right" title="Der Brieftext wurde anhand der überlieferten Quellen (vgl. Provenienz) kritisch geprüft. Notwendige Korrekturen gegenüber dem in ZH gedruckten Text wurden vorgenommen und sind vollständig annotiert. Die in den beiden Auflagen von ZH angehängten Korrekturvorschläge werden vollständig aufgelistet, werden aber nur dann im Text realisiert, sofern diese anhand überlieferter Quellen verifiziert werden konnten.">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
</svg> :</span>
@* <div class="disclaimer">Der Brieftext wurde anhand der überlieferten Quellen (vgl. Provenienz) kritisch geprüft. Notwendige Korrekturen gegenüber dem in ZH gedruckten Text wurden vorgenommen und sind vollständig annotiert. Die in den beiden Auflagen von ZH angehängten Korrekturvorschläge werden vollständig aufgelistet, werden aber nur dann im Text realisiert, sofern diese anhand überlieferter Quellen verifiziert werden konnten.</div> *@
@Html.Raw(sb_edits)
</div>
}
</div>
</div>
@section Scripts {
<script src="~/js/new.js" asp-append-version="true"></script>
<script>
function offsetAnchor() {
if (location.hash.length !== 0) {
window.scrollTo(window.scrollX, window.scrollY - 280);
}
}
$(document).on('click', 'a[href^="#"]', function(event) {
window.setTimeout(function() {
offsetAnchor();
}, 0);
});
window.setTimeout(offsetAnchor, 0);
$( "#" + window.location.hash.substr(1) ).before("<div class=\"selected\">☛</div>");
</script>
<script>
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
})
</script>
}

View File

@@ -0,0 +1,36 @@
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using HaDocument.Interfaces;
using HaDocument.Models;
using System;
namespace HaLive.Pages
{
public class BriefeModel : PageModel
{
internal ILibrary _lib;
[BindProperty(SupportsGet = true)]
public string id { get; set; }
public BriefeModel(ILibrary lib) {
_lib = lib;
}
public IActionResult OnGet()
{
if (String.IsNullOrWhiteSpace(id)) {
return RedirectPermanent("/Briefe/1");
}
var res = _lib.Metas.Where(x => x.Value.Autopsic == id);
if (!res.Any() || !_lib.Metas.ContainsKey(res.First().Key)) {
Response.StatusCode = 404;
return RedirectToPage("/Error");
}
_lib.Metas.Where(x => x.Value.Autopsic == id).First();
return Page();
}
}
}

View File

@@ -0,0 +1,139 @@
@page
@model HaLive.Pages.EditionsgeschichteModel
@{
ViewData["Title"] = "Editionsgeschichte";
}
<div class="mainhead row "> <!-- + sticky-top if sticky -->
<!--Sticky grey space on top of header -->
<div class="col">
<div class="widehead">
<div class="flexcol">
<div style="align-self: flex-end">
<br/>
</div>
<div class="flexrow" style="margin-bottom:-30px">
<div class="heading">
Editionsgeschichtliche Voraussetzungen
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row no-gutters">
<div class="col">
<div class="registerbox">
<div class="text editionstext">
<!-- Text -->
<p class="Text">Von 1899 bis zu seinem Tod 1929 sammelte Arthur Warda, Amtsrichter in Königsberg und Mitarbeiter an den ersten Briefbänden der Akademieausgabe von Kants Gesammelten Werken, alles in Bezug auf Hamann Erreichbare in Königsberg, um eine Gesamtausgabe der Werke und Briefe auf den Weg zu bringen.<a class="Fußnotenzeichen" name="FnZ-2" href="#FnA-2">2</a> Bei seinem Tod 1929 hatte er von Dreivierteln der fast 1.200 Briefe handschriftliche Abschriften in der Qualität von Satzvorlagen für den Druck angefertigt. In den Jahren 1905/06 schaffte er es, den Erwerb der drei wichtigsten Hamann-Nachlässe durch die Königsberger Staats- und Universitätsbibliothek zu vermitteln.<a class="Fußnotenzeichen" name="FnZ-3" href="#FnA-3">3</a></p>
<p class="Text">1904 wandte er sich mit dem Projekt einer Werk- und Briefausgabe an die Preußische Akademie der Wissenschaften zu Berlin (= PAW). Nach jahrelangen Verhandlungen begann die Unternehmung 1914 konkrete Züge anzunehmen, doch der Ausbruch des Ersten Weltkriegs erstickte diese Bestrebungen sogleich wieder im Keim. Erst 1927 betraute die Deutsche Kommission Julius Petersen (18781941) mit der Organisation einer Gesamtausgabe.<a class="Fußnotenzeichen" name="FnZ-4" href="#FnA-4">4</a> Als Bearbeiter der Brief-Bände wurde Arthur Warda benannt. Zeitgleich suchte die Preußische Akademie der Wissenschaften über Josef Nadler, zu dieser Zeit Professor für Neuere deutsche Literaturgeschichte in Königsberg, den Kontakt zur Königsberger Gelehrten Gesellschaft, um diese für eine gemeinsame Finanzierung der Ausgabe zu gewinnen. Josef Nadler bot sich als Bearbeiter der Werkbände an, im Juli 1928 übersandte er einen Ausgabenplan.</p>
<p class="Text">Als Arthur Warda 1929 starb, hinterließ er, neben zahlreichen Autographen und wertvollen Drucken, u.a. eine Kartei über sämtliche Briefe von und an Hamann, Abschriften von 857 Briefen in der Qualität von Satzvorlagen, ein durchkorrigiertes Exemplar von Gildemeisters Edition des Briefwechsels Hamanns mit Jacobi sowie reinschriftliche Abschriften in drei Foliobänden der übrigen Briefe.<a class="Fußnotenzeichen" name="FnZ-5" href="#FnA-5">5</a> Diese Materialien konnte Walther Ziesemer, der 1930 neu bestimmte Herausgeber der Briefe, übernehmen.</p>
<p>Wirksam zum 1. Januar 1930, wurde ein Vertrag zwischen der Preußischen Akademie der Wissenschaften sowie der Königsberger Gelehrten Gesellschaft mit dem Insel-Verlag, <span class="kursiv">in persona</span> dessen Leiter Anton Kippenberg, ausgehandelt. Jedes Jahr sollten parallel je ein Band der Werke und Briefe erscheinen.<a class="Fußnotenzeichen" name="FnZ-6" href="#FnA-6">6</a></p>
<p class="Text">Dank der Vorarbeiten von Warda konnte Ziesemer bereits im April 1932 die Satzvorlagen für den Druck von Band I des Briefwechsels an den Insel-Verlag schicken.<a class="Fußnotenzeichen" name="FnZ-7" href="#FnA-7">7</a> Mit der Drucklegung wollte der Verlag jedoch noch auf den ersten Werkband warten, damit eine einheitliche Druckgestaltung abgesprochen werden konnte. Obwohl jährlich angekündigt, konnte Nadler diese erst vier Jahre später Ende 1936 an den Verlag geben.<a class="Fußnotenzeichen" name="FnZ-8" href="#FnA-8">8</a></p>
<p class="Text">Nachdem Ende November 1936 sowohl die Satzvorlage für den Druck des ersten Bandes der Briefe, als auch jene der Werke beim Insel-Verlag vorlagen, begann die schwierige Phase der Drucklegung. Zunächst wurden vom Verlag Probeseiten für die Werkausgabe erstellt.<a class="Fußnotenzeichen" name="FnZ-9" href="#FnA-9">9</a> Petersen hatte den Verlagsleiter Kippenberg bereits im Dezember 1929 vor Vertragsabschluss auf Anraten Nadlers explizit darauf aufmerksam gemacht, »dass bei einzelnen Schriften Hamanns das Satzbild ein sehr kompliziertes ist und dass er selbst eine Buntheit von Typen im Wechsel von Sperrdruck, Fettdruck, antiqua, Fraktur, petit und fremden Alphabeten wie hebräisch und griechisch gewählt hat, um die man bei der Wiedergabe nicht herum kommt.«<a class="Fußnotenzeichen" name="FnZ-10" href="#FnA-10">10</a></p>
<p class="Text">Aus angeblich ästhetischen, aber wohl vornehmlich ökonomischen Gründen wollte der Verlag nun bei der Satzgestaltung auf fast sämtliche typographischen Auszeichnungen wie den mehrfachen Schriftwechsel und verschiedene Schriftgrößen wie sie in Hamanns Erstdrucken vorliegen, verzichten und einzig einzelne Wörter durch Sperrung hervorheben. Nadler fand die Entscheidung des Verlags, auf die spezifische typographische Gestaltung der Hamannschen Drucke zu verzichten, fatal.<a class="Fußnotenzeichen" name="FnZ-11" href="#FnA-11">11</a> Trotzdem begann die Drucklegung des je ersten Bands der Werke und Briefe im Juni 1937. Kurz darauf kollationierte Ziesemer bereits die Druckfahnen von Band I der Briefe noch einmal vollständig mit den Originalen in Königsberg,<a class="Fußnotenzeichen" name="FnZ-12" href="#FnA-12">12</a> und im Sitzungsbericht der PAW wird das Erscheinen der beiden Bände für Ostern 1938 angekündigt.<a class="Fußnotenzeichen" name="FnZ-13" href="#FnA-13">13</a></p>
<p class="Text">In den kommenden zweieinhalb Jahren vertröstete Nadler den Verlag und die Akademie immer wieder in Bezug auf die noch ausstehende Korrektur des Werkbandes. Während der erste Werkband unkorrigiert im Satz stand, wurden von 1937 bis 1939<a class="Fußnotenzeichen" name="FnZ-14" href="#FnA-14">14</a> die ersten beiden Bände der Briefe von Ziesemer vollständig korrigiert, in der vereinbarten Auflage von 1.200 Exemplaren ausgedruckt und vorerst eingelagert. Denn der Erscheinungstermin der Ausgabe wurde von Jahr zu Jahr verschoben. Die gescheiterte Wahl Nadlers zum korrespondierenden Mitglied der Preußischen Akademie der Wissenschaften im Frühjahr 1939 wurde dann zu einem Ränkespiel an Gesinnungsfronten, das bis 1943 andauerte und die Arbeit an der Werk-Ausgabe ausbremste.</p>
<p class="Text">Die Situation schien zwischen 19391942 so festgefahren, dass selbst Akademie und Königsberger Gelehrte Gesellschaft nicht mehr an die Korrektur der Druckfahnen durch Nadler glaubten und den Insel-Verlag, 1941/42 gerade mit der Drucklegung der Bände III und IV der Briefe beschäftigt,<a class="Fußnotenzeichen" name="FnZ-15" href="#FnA-15">15</a> um eine Entkoppelung des Erscheinens der Briefbände von den Werkbänden baten.<a class="Fußnotenzeichen" name="FnZ-16" href="#FnA-16">16</a> Kippenberg ging mit Verweis auf die vertraglichen Regelungen von 1930 jedoch nicht darauf ein<a class="Fußnotenzeichen" name="FnZ-17" href="#FnA-17">17</a> und druckte die Briefbände weiterhin für das Lager. Während der Satz des ersten Werkbandes trotz der zunehmenden Materialverknappung stehen blieb und auf Korrekturen und das Imprimatur Nadlers wartete, übersandte Ziesemer 1941 und Ende 1942 die restlichen Satzvorlagen für den Druck der Bände V, VI und VII an den Verlag.<a class="Fußnotenzeichen" name="FnZ-18" href="#FnA-18">18</a> Der Satz der letzten drei Bände wurde vom Verlag jedoch nicht mehr veranstaltet.</br></p>
<!-- Leerzeile -->
<p class="Text">In der Nacht vom 3. auf den 4. Dezember 1943 wurde das Verlagsgebäude des Insel-Verlags beim Luftangriff der Alliierten auf das Graphische Viertel Leipzigs vollständig zerstört. Im Januar 1944 schrieb Kippenberg an Ziesemer diesbezüglich: »Vom Insel-Verlag habe ich das Wesentlichste, vor allem alles Geschichtliche des Verlags rechtzeitig in Sicherheit gebracht, darunter auch die Manuskripte zu Band 5 bis 7 der Hamann-Briefe. Aber auch sonst hat über Hamann ein guter Stern gestanden insofern, als die Buchbinderei, in der die Vorräte der ersten Bände lagen, sich unter den wenigen befindet, die erhalten geblieben sind.«<a class="Fußnotenzeichen" name="FnZ-19" href="#FnA-19">19</a></p>
<p class="Text">Zwar wurden die eingelagerten Vorräte der ersten beiden Briefbände bei einem weiteren Luftangriff am 20. Februar 1944 doch noch zerstört, erhalten blieben jedoch einzelne Abzüge der Druckbogen der Briefbände I bis IV sowie die Satzvorlagen für die Bände V bis VII. Diese Materialien wurden nach Ziesemers Tod 1954 Arthur Henkel, dem mittlerweile dritten Herausgeber der Briefe Hamanns, übergeben.<a class="Fußnotenzeichen" name="FnZ-20" href="#FnA-20">20</a></p>
<p class="Text">Unschätzbare Bedeutung haben diese Materialien dadurch gewonnen, dass sämtliche Briefe Hamanns, die sich in Königsberg befanden, es handelt sich um insgesamt 658 Stück seit der Einnahme Königsbergs durch die Rote Armee Anfang 1945 ebenso wie der restliche Hamann-Nachlass als verschollen gelten. Nadlers Übersiedlung nach Wien, so negativ sie sich auch auf die Fertigstellung der Hamann-Ausgabe in den 1930/40er Jahren ausgewirkt hat, ist gleichzeitig nützlich gewesen, weil Reproduktionen angefertigt werden mussten. Anhand der Photographien, die Nadler veranlasste, lässt sich der Königsberger Nachlass, die Werke betreffend, heute recht gut rekonstruieren.<a class="Fußnotenzeichen" name="FnZ-21" href="#FnA-21">21</a></p>
<p class="Text">Da Ziesemer in Königsberg geblieben war, bestand für ihn nicht die Notwendigkeit, sich Reproduktionen der Briefe Hamanns anfertigen zu lassen, konnte er doch jederzeit an den Originalen arbeiten. So bleiben uns von jenen 658 Briefen, die in Königsberg waren, jeweils nur zweitbeste Quellen. Für die Jahre bis 1782, also die Bände I bis IV, haben wir als einzige Quelle der Königsberger-Briefe noch die Druckbogen aus den Jahren 1937 bis 1943. Für die Briefe aus den Jahren 1783 bis 1788 die Satzvorlagen für die Bände V bis VII, die Ziesemer 1941/42 an den Verlag geschickt hatte.</br></p>
<!-- Leerzeile -->
<p class="Text">Während Nadler nach dem zweiten Weltkrieg seine sechsbändige Werkausgabe Hamanns von 1949 bis 1957 wegen der Divergenzen mit dem Insel-Verlag und der Preußischen Akademie der Wissenschaften bei der Thomas-Morus-Presse im Herder-Verlag in Wien veröffentlichte,<a class="Fußnotenzeichen" name="FnZ-22" href="#FnA-22">22</a> ließ der Insel-Verlag von 1955 bis 1957, jetzt in Wiesbaden, unter Ziesemers und Henkels gemeinsamer Herausgeberschaft, die Bände I bis III der Briefausgabe seiten- und zeilenidentisch anhand der wenigen überlieferten Druckbogen neu setzen und diesmal auch ausliefern.<a class="Fußnotenzeichen" name="FnZ-23" href="#FnA-23">23</a> Band IV erschien als erster Band unter alleiniger Herausgeberschaft von Henkel 1959.<a class="Fußnotenzeichen" name="FnZ-24" href="#FnA-24">24</a> Im Gegensatz zu den vorherigen drei Bänden ist Band IV kein bloßer Nachdruck der Druckbogen Ziesemers aus den Jahren 194043. Zwar ist ein großer Teil der Briefe ebenfalls seiten- und zeilengetreu zur Vorlage, der Text wurde von Henkel aber nochmals »kritisch […] bearbeit[et]« und »eine genauere chronologische Ordnung der Briefe« hergestellt, wie er in seiner Einleitung schreibt.<a class="Fußnotenzeichen" name="FnZ-25" href="#FnA-25">25</a> Der Textbestand ist freilich identisch.</p>
<p class="Text">Insgesamt 499 der 681 Briefe aus den Hamann-Briefbänden I bis IV gelten seit 1945 als verschollen. Für diese 499 Briefe sind die Druckfahnen aus den 1930/40-Jahren die einzige erhaltene Quelle. Da Henkel in den Nachweisen aller sieben Briefbände jeweils noch die bei Ziesemer genannten, seinerzeit aber schon verschollenen Königsberger Quellen anführt, ist für den Leser leider zunächst nicht ersichtlich, dass für die Erstellung der Ausgabe von Henkel bereits nicht mehr die Originalbriefe verwendet werden konnten. Verstehbar wird diese Intransparenz der Quellen dadurch, dass Henkel nicht sicher wusste, ob die Originalbriefe tatsächlich zerstört wurden.</p>
<p class="Text">Die wenigen überlieferten Exemplare der ursprünglichen Druckfahnen der Bände I, II und IV befinden sich heute in der Deutschen Nationalbibliothek Leipzig, in der Präsenzbibliothek des Germanistischen Seminars der Universität Hamburg, in der Beinecke Library in Yale, im Herder-Institut in Marburg, in Privatbesitz sowie im Hamann-Nachlass Henkels in Heidelberg. Von Band III konnte ich bisher leider noch kein überliefertes Exemplar ausfindig machen,<a class="Fußnotenzeichen" name="FnZ-26" href="#FnA-26">26</a> 1957 hat es ein solches jedoch definitiv noch gegeben.</br></p>
<!-- Leerzeile -->
<p class="Text">Die letzten drei Bände der Briefausgabe erschienen, herausgegeben von Arthur Henkel: 1965, 1975 und 1979.<a class="Fußnotenzeichen" name="FnZ-27" href="#FnA-27">27</a> Henkel erstellte die Bände auf der Grundlage der Satzvorlagen der Bände V bis VII, die Ziesemer 1941/42 an den Verlag geschickt hatte und die Kippenberg kurz vor den Luftangriffen auf Leipzig noch aus dem Verlagsgebäude gerettet hatte. Kopien der durchnumerierten losen Abschriften in der Qualität von Satzvorlagen befinden sich heute im Nachlass Arthur Henkels: etwa ein Drittel als handschriftliche Abschriften Arthur Wardas von 19011929, die restlichen zwei Drittel als Typoskripte, die Ziesemer in den 1930er-Jahren angefertigt hat. Die Typoskripte sind bis auf wenige Ausnahmen Abschriften aus dem Briefwechsel Hamanns mit Jacobi, den Warda als einziges Großkonvolut vor seinem Tod nicht mehr abschreiben konnte. Glücklicherweise haben diese Briefe in der UB Nürnberg-Erlangen den Zweiten Weltkrieg überstanden, so dass die Typoskripte Ziesemers hauptsächlich editionsgeschichtliche, keine quellenmäßige Bedeutung haben.</p>
<p class="Text">Anders liegt die Sache bei den handschriftlichen Abschriften Wardas. Für mindestens 159 Briefe aus den Bänden V bis VII sind die handschriftlichen Abschriften Wardas die einzige überlieferte Quelle. Besser wäre es natürlich, hätten wir noch die Originalbriefe. Die Qualität und Genauigkeit der Transkription der Wardaschen Abschriften ist indes nicht zu verachten. Von Haus aus war Warda Jurist, nicht Philologe und so sind auch seine Abschriften von geradezu juristischer Genauigkeit: Unterschiedliche Schreiberhände sind mit verschiedenfarbiger Tinte kenntlich gemacht, Streichungen und Überschreibungen werden in Umschrift transkribiert, Geminationen wiedergegeben statt stillschweigend aufgelöst, die Anordnung der Textteile ist zum Teil präziser als in der gedruckten Ausgabe.</p>
<!-- Autorangabe -->
<div class="Unterschrift">Janina Reibold</div>
<p class="Text"><span class="kursiv">Eine ausführliche Version dieser editionsgeschichtlichen Untersuchung ist erschienen: <br/>Janina Reibold: Kurze Geschichte der langen Hamann-Edition. Ein Zwischenbericht. In: Johann Georg Hamann: Natur und Geschichte. Acta des Elften Internationalen Hamann-Kolloquiums an der Kirchlichen Hochschule Wuppertal/Bethel 2015. Hg. von Eric Achermann, Johann Kreuzer und Johannes von Lüpke. Göttingen 2020 (= Hamann-Studien, Bd. 4), S. 453&ndash;475.</span></p>
<!-- Fußnoten ab hier -->
<br/>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-1" href="#FnZ-1">1</a>Die im Folgenden genannten Informationen sind auf Dokumente gestützt in den Nachlässen Josef Nadlers in Wien (ÖNB), Julius Petersens in Marbach (DLA), Arthur Henkels in Heidelberg, dem Verlagsarchiv des Insel-Verlags in Weimar (GSA) sowie dem Archiv der Berlin-Brandenburgischen Akademie der Wissenschaften (ABBAW). Die Briefe zwischen Anton Kippenberg und Julius Petersen aus dem DLA und GSA wurden in Auswahl bereits von Thomas Neumann ediert: Anton Kippenberg. Der Briefwechsel mit Julius Petersen 1907 bis 1941. Hg. von Th. Neumann. Norderstedt 2000. Im Folgenden, falls vorhanden, zitiert als Neumann, Briefnummer. Die Briefe Arthur Wardas an Rudolf Unger aus der UB Göttingen wurden bereits von Renate Knoll ediert in: Johann Georg Hamann 17301788. Quellen und Forschungen. Hg. von R. Knoll. Bonn 1988, S. 209218. Im Folgenden zitiert als Knoll, Briefnummer [Seitennummer].</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-2" href="#FnZ-2">2</a>Vgl. hierzu und dem Folgenden ausführlich Josef Nadler: Die Hamannausgabe. Vermächtnis Bemühungen Vollzug. Halle an der Saale 1930 (= HA), S. 148166.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-3" href="#FnZ-3">3</a>Vgl. ebd., S. 150154.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-4" href="#FnZ-4">4</a>Vgl. Petersen an Kippenberg, 19.2.1927 (GSA 50/2606,2 | Neumann, Nr. 294) und Nadler, HA S. 163.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-5" href="#FnZ-4">5</a>Vgl. Nadler, HA S. 165f. sowie Ranke an Petersen, 23.11.1929 (DLA, A: Petersen, 73.494/7).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-6" href="#FnZ-6">6</a>Eine Kopie des endgültigen Vertrags findet sich sowohl als Beilage zum Brief Sthamers an Petersen, 15.4.1930 (DLA, A: Petersen, 73.495/2) als auch in den Unterlagen der ehemaligen Preußischen Akademie der Wissenschaften (ABBAW: ASt. Dt. Kommission, Nr. 19).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-7" href="#FnZ-7">7</a>Vgl. Ziesemer an Kippenberg, 23.4.1932 sowie Insel-Verlag an Ziesemer, 30.4.1932 (GSA 50/3859).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-8" href="#FnZ-8">8</a>Vgl. hierzu v.a. Nadler an Petersen, 31.12.1934 (DLA, A: Petersen, D62.348/2).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-9" href="#FnZ-9">9</a>Vgl. Insel-Verlag an Ziesemer, 23.1.1937 (GSA 50/3859).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-10" href="#FnZ-10">10</a>Petersen an Kippenberg, 21.12.1929 (DLA, A: Petersen, 73.480/1).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-11" href="#FnZ-11">11</a>Nadlers hier klar artikulierte Einsicht in die Notwendigkeit der Wiedergabe der spezifischen Druckbildlichkeit der Schriften Hamanns steht im diametralen Gegensatz zur tatsächlichen Praxis in den von ihm letztlich 194957 herausgegebenen <span class="kursiv">Sämtlichen Werken</span> beim Herder Verlag in Wien (vgl. Anm. 22). Stefan Willer hat auf diese Widersprüchlichkeit (in Bezug auf andere Äußerungen Nadlers) bereits hingewiesen in ders., <span class="kursiv">»Ein geschickter Gebrauch dieser masoretischen Zeichen«. Philologische Schriftbildlichkeit am Beispiel Johann Georg Hamanns.</span> In: Gernot Gruber, Werner Kogge u. Sybille Krämer (Hg.), Schrift. Kulturtechnik zwischen Auge, Hand und Maschine. München 2005, S. 357373: »Hinweise wie dieser, die die Buntheit und den Detailreichtum des Druckbildes betreffen, finden sich in Nadlers Kommentaren immer wieder. Umso auffälliger wird der Abstand zwischen der von Hamann veranstalteten Diversität der Erstdrucke und der Homogenität der Nadler-Ausgabe« (S. 363f.). Eine der wenigen Arbeiten, die sich mit der typographischen Gestaltung der Hamannschen Drucke auseinandersetzt, ist die (leider nur schwer zugängliche) Dissertation von Ilse Johanna Meyer, Provokationen im Druckbild Johann Georg Hamanns (17301788). Ohio State University 1978; Mikrofilm 1979. Ziesemer an Insel-Verlag, 22.7. und 27.9.1937 (GSA 50/3859).
</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-12" href="#FnZ-12">12</a>Ziesemer an Insel-Verlag, 22.7. und 27.9.1937 (GSA 50/3859).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-13" href="#FnZ-13">13</a>Sitzungsberichte der Preussischen Akademie der Wissenschaften, Philosophisch-Historische Klasse (1938), LXVIII.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-14" href="#FnZ-14">14</a>Das Druckmanuskript für Band II der Briefe wurde am 10. März 1938 von Ziesemer an den Insel-Verlag geschickt (GSA 50/3859).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-15" href="#FnZ-15">15</a>Die Satzvorlagen gingen für Band III vermutlich Ende 1939 und für Band IV 1940 an den Insel-Verlag, vgl. Ziesemer an Petersen, 20.3.1940 (DLA, A: Petersen, 73.497/8).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-16" href="#FnZ-16">16</a>Ernst Forsthoff (Königsberger Gelehrte Gesellschaft) an Kippenberg, 9.12.1940 (DLA, A: Petersen, 73.504).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-17" href="#FnZ-17">17</a>Forsthoff an Petersen, 22.12.1940 (DLA, A: Petersen, 73.486/1).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-18" href="#FnZ-18">18</a>Band V am 27.6.1941, Band VI am 1.12.1942 und Band VII am 4.12.1942, vgl. Ziesemer an Kippenberg, 21.1.1944. Entsprechende Briefe und Eingangsvermerke im Insel-Verlag fehlen, da die gesamten sich im Verlagsgebäude befindlichen Akten, v.a. die Korrespondenz zwischen Frühjahr 1939 und Ende 1943, bei der Zerstörung des Verlagsgebäudes in der Nacht vom 3. auf den 4. Dezember 1943 wohl verlorengegangen sind.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-19" href="#FnZ-19">19</a>Kippenberg an Ziesemer, 27.1.1944 (GSA 50/3859).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-20" href="#FnZ-20">20</a>Diese Angaben decken sich auch mit Nadlers »Abschlussbericht«: Ders.: Fliegender Brief. Rückblick und Abschied. In: Johann Georg Hamann: Sämtliche Werke. Historisch-kritische Ausgabe, Bd. VI (Wien 1952), S. 423431.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-21" href="#FnZ-21">21</a>Die ca. 6.000 Photographien befinden sich heute in der ULB Münster. Ein Findbuch zum Hamann-Nachlass in der ULB Münster ist dem Faksimiledruck von Nadler, HA durch Sabine Kinder, Bern/Frankfurt/Las Vegas 1978, beigegeben.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-22" href="#FnZ-22">22</a>Johann Georg Hamann: Sämtliche Werke. Historisch-kritische Ausgabe. 6 Bde. Hg. von Josef Nadler. Wien 19491957 [= N].</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-23" href="#FnZ-23">23</a>Johann Georg Hamann: Briefwechsel. Bde. IIII. Hg. von Walther Ziesemer und Arthur Henkel. Frankfurt a. M. 1955, 1956, 1957.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-24" href="#FnZ-24">24</a>Johann Georg Hamann: Briefwechsel. Bd. IV. Hg. von Arthur Henkel. Frankfurt a. M. 1959.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-25" href="#FnZ-25">25</a>Ebd., S. XXIII.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-26" href="#FnZ-26">26</a>Für Hinweise, die zum Auffinden eines Exemplars der Druckbogen von Bd. III dienen, bin ich sehr dankbar.</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-27" href="#FnZ-27">27</a>Johann Georg Hamann: Briefwechsel. Bde. VVII. Hg. von Arthur Henkel. Frankfurt a.M. 1965, 1975, 1979.</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace HaLive.Pages
{
public class EditionsgeschichteModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@@ -0,0 +1,68 @@
@page
@model HaLive.Pages.KontaktModel
@{
ViewData["Title"] = "Kontakt";
}
<div class="mainhead row"><!-- + sticky-top if sticky -->
<!--Sticky grey space on top of header -->
<div class="col">
<div class="widehead">
<div class="flexcol">
<div style="align-self: flex-end">
<br/>
</div>
<div class="flexrow" style="margin-bottom:-30px">
<div class="heading">
Kontakt
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row no-gutters">
<div class="col">
<div class="registerbox">
<div class="text editionstext">
<p class="Text_NI">Die Kommentierte Hamann-Ausgabe ist ein Projekt der Theodor Springmann Stiftung in Kooperation mit dem Germanistischen Seminar der Universität Heidelberg.</p>
<div class="Ueberschrift2">Kontakt</div>
<table>
<tr>
<td>Theodor Springmann Stiftung </br>
Dr. Janina Reibold </br>
Hirschgasse 2 </br>
69120 Heidelberg </br>
Telefon: 06221 7259277 </br>
E-Mail: <a class="Emailhref" href="mailto:post@hamann-ausgabe">post@hamann-ausgabe</a></td>
<td>Germanistisches Seminar der Universität Heidelberg </br>
Dr. Janina Reibold </br>
Hauptstraße 207209 </br>
69117 Heidelberg </br>
Telefon: 06221 543254 </br>
<a class="ExternerLink" href="https://www.gs.uni-heidelberg.de/personen/reibold.html" target="blank">www.gs.uni-heidelberg.de/personen/reibold.html</a></td>
</tr>
</table>
<div class="Ueberschrift2">Anmeldung zur regelmäßigen Mitteilung über den Stand der kommentierten Hamann-Ausgabe</div>
<p class="Text_NI">Wenn Sie über den Verlauf des Projekts informiert werden möchten, melden Sie sich bitte mit einer E-Mail an <a class="Emailhref" href="mailto:post@hamann-ausgabe.de">post@hamann-ausgabe.de</a> zu unserem Newsletter an. Sie erhalten dann Mitteilung über die Termine der online-Veröffentlichung der Briefe und des Kommentars sowie Hinweise zum Erscheinen der kommentierten Werkbände im Meiner Verlag.</p>
<div class="Ueberschrift2">Ihre Mitarbeit am Online-Kommentar</div>
<p class="Text_NI">Die Online-Publikation der Briefe und des Stellenkommentars ermöglicht eine ständige Revision desselben. Wir möchten Sie einladen, mit Ergänzungen, Korrekturen, Vorschlägen zu dessen Verbesserung beizutragen. Senden Sie uns diese bitte an <a class="Emailhref" href="mailto:post@hamann-ausgabe.de">post@hamann-ausgabe.de</a>. Nach unserer Prüfung fügen wir diese in den Online-Kommentar ein (auf Wunsch auch mit Namensnennung des Beiträgers).</p>
<div class="Ueberschrift2">Zitierempfehlung</div>
Johann Georg Hamann: <span class="kursiv">Kommentierte Briefausgabe.</span> Hg. von Leonard Keidel und Janina Reibold, auf Grundlage der Vorarbeiten Arthur Henkels, unter Mitarbeit von Gregor Babelotzky, Konrad Bucher, Christian Großmann, Carl Friedrich Haak, Luca Klopfer, Johannes Knüchel, Isabel Langkabel und Simon Martens (Heidelberg 2020&#x202f;ff.). URL: www.hamann-ausgabe.de [= HKB]<br/><br/>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace HaLive.Pages
{
public class KontaktModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@@ -0,0 +1,56 @@
@page
@model HaLive.Pages.MitwirkendeModel
@{
ViewData["Title"] = "Mitwirkende";
}
<div class="mainhead row"> <!-- + sticky-top if sticky -->
<!--Sticky grey space on top of header -->
<div class="col">
<div class="widehead">
<div class="flexcol">
<div style="align-self: flex-end">
<br/>
</div>
<div class="flexrow" style="margin-bottom:-30px">
<div class="heading">
Mitwirkende
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row no-gutters">
<div class="col">
<div class="registerbox">
<div class="text editionstext">
<div class="Ueberschrift2">Philologische Mitarbeit</div>
Dr. Gregor Babelotzky (seit 2019)<br/>
Konrad Bucher (seit 2019)<br/>
Christian Großmann (20182019)<br/>
Carl Friedrich Haak (20132018)<br/>
Leonard Keidel (seit 2018)<br/>
Luca Klopfer (seit 2016)<br/>
Johannes Knüchel (20162020)<br/>
Isabel Langkabel (20132019)<br/>
Simon Martens (20132018)<br/>
Dr. Janina Reibold (Leitung seit 2013)<br/>
<br/>
<div class="Ueberschrift2">Technische Umsetzung</div>
Carl Friedrich Haak (20182020)<br/>
Simon Martens (seit 2018)<br/><br/>
<div class="Ueberschrift2">Zitierempfehlung</div>
Johann Georg Hamann: <span class="kursiv">Kommentierte Briefausgabe.</span> Hg. von Leonard Keidel und Janina Reibold, auf Grundlage der Vorarbeiten Arthur Henkels, unter Mitarbeit von Gregor Babelotzky, Konrad Bucher, Christian Großmann, Carl Friedrich Haak, Luca Klopfer, Johannes Knüchel, Isabel Langkabel und Simon Martens (Heidelberg 2020&#x202f;ff.). URL: www.hamann-ausgabe.de [= HKB] <br/><br/>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace HaLive.Pages
{
public class MitwirkendeModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@@ -0,0 +1,113 @@
@page
@model HaLive.Pages.RichtlinienModel
@{
ViewData["Title"] = "Richtlinien";
}
<div class="mainhead row"> <!-- + sticky-top if sticky -->
<!--Sticky grey space on top of header -->
<div class="col">
<div class="widehead">
<div class="flexcol">
<div style="align-self: flex-end">
<br/>
</div>
<div class="flexrow" style="margin-bottom:-30px">
<div class="heading">
Editionsrichtlinien
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row no-gutters">
<div class="col">
<div class="registerbox">
<div class="text editionstext">
<p class="Text_NI">Die Online-Edition der Briefe Johann Georg Hamanns bietet dieselben als durchsuchbaren Volltext. Die Einteilung der Bände der gedruckten Briefausgabe ZH (J.G. Hamann, Briefwechsel. Hg. von Walther Ziesemer und Arthur Henkel. 7 Bde. [Frankfurt a. M. 19551979]) wird übernommen. Die derzeit hier veröffentlichten Briefe entsprechen im Umfang dem ersten Band von ZH und zusammen mit dem Stellenkommentar und den Registern unserem Editionsstand vom 13. Oktober 2020.</p>
<p class="Text_NI">Die in den Brief-Manuskripten enthaltenen Auszeichnungen werden, teilweise in veränderter Form gegenüber ZH, wiedergegeben:</p>
<!-- Tabelle -->
<table>
<tr>
<th class="TabellenUeberschrift">Handschrift/Abschrift</th>
<th class="TabellenUeberschrift">ZH</th>
<th class="TabellenUeberschrift">hier</th>
</tr>
<tr>
<td>Deutsche Kurrentschrift</td>
<td>Fraktur</td>
<td><span class="LinuxLibertine">Serifenschrift (Linux Libertine)</span></td>
</tr>
<tr>
<td>Lateinische Schreibschrift</td>
<td>Antiqua</td>
<td><span class="aq">serifenlose Schrift (Linux Biolinum)</span></td>
</tr>
<tr>
<td>Unterstreichung (einfache bis dreifache)</td>
<td>Sperrung/fette Sperrung</td>
<td><span class="ul">Unterstreichung</span> (einfache bis dreifache)</td>
</tr>
<tr>
<td>Durchstreichung</td>
<td>in spitzen Klammern ⟨...⟩</td>
<td><span class="del">Durchstreichung</span></td>
</tr>
<tr>
<td>Nicht entzifferbare Stelle / Unsichere Lesung</td>
<td>unterschiedlich gehandhabt</td>
<td>mit einem leeren Mittelpunkt markiert ◦ ◦</td>
</tr>
<tr>
<td>Brieftext fremder Hand</td>
<td>kleinere Schrift</td>
<td><span class="hand">klassizistische Antiqua (Playfair Display),</span> der Schreiber wird im Apparat angegeben</td>
</tr>
<tr>
<td>Ergänzung durch Hg.</td>
<td>in eckigen Klammern [...]</td>
<td><span class="added">grau hinterlegt</span></td>
</tr>
<tr>
<td>Herausgeberanmerkung</td>
<td>kleinere Schrift</td>
<td><span class="note">Kursive in grauer Farbe</span></td>
</table>
<p class="Text_NI">Die Briefnumerierung und Seiten- und Zeilenzählung wird von ZH übernommen, jedoch da, wo ZH fehlerhaft ist (bes. bei der Zeilenzählung), stillschweigend korrigiert. Auch bei der Datierung der Briefe wurden Korrekturen vorgenommen, die sich auf die Reihenfolge auswirken, aber die ZH-Numerierung wurde der wechselseitigen Benutzbarkeit von Buch- und Online-Edition wegen belassen. Die digitale Einrichtung der Edition (im XML-Format) bringt geringfügige Einschränkungen in der Textdarstellung mit sich: So stehen etwa Wörter, die in ZH am Zeilenende getrennt und umbrochen sind, hier nicht-getrennt in der je zweiten Zeile.</p>
<p class="Text_NI">Sofern die handschriftlichen Originale der Briefe, Abschriften oder Druckbogen von ZH (siehe dazu die <a href="/Edition/Editionsgeschichte">editionsgeschichtlichen Voraussetzungen</a>) vorliegen, wird der Brieftext an diesen geprüft und ggf. korrigiert. Text-Korrekturen, die mehrerlei Ursache haben (Lese- und Druckfehler oder Fehler nach Kollation mit ursprünglichen Druckbogen, Manuskripten oder Abschriften), werden in den Online-Brieftexten vorgenommen, der ursprüngliche Wortlaut in ZH sowie die Gründe für den Texteingriff sind jeweils in den textkritischen Anmerkungen unter dem Brieftext kenntlich gemacht. Soweit erstellbar, ist im Apparat für jeden Brief die Provenienz geliefert.</p>
<p class="Text_NI">Der Stellenkommentar in der Marginalspalte neben dem Brieftext und die Register stützen sich auf umfangreiche Vorarbeiten Arthur Henkels, der diese der Theodor Springmann Stiftung vor seinem Tod mit dem Auftrag übereignet hat, dass eine Online-Edition mit redigiertem und revidierbarem Kommentar erstellt und organisiert wird. Sybille Hubach, eine langjährige Mitarbeiterin Henkels, hat die Kommentierung des 2005 verstorbenen Germanisten auf www.hamann-briefwechsel.de als archivalisches Zeugnis publiziert und für die Bände VVII ergänzt, bspw. mit Informationen aus den kommentierten Briefausgaben von Johann Gottfried Herder und Friedrich Heinrich Jacobi. </p>
<p class="Text_NI">Der hier vorgelegte Stellenkommentar und die dazugehörigen Register beruhen auf neuen Recherchen bzgl. Personen, Quellen, Worten und historischen Begebenheiten und ergänzen, korrigieren oder bestätigen die bisherigen Informationen. Einen Schwerpunkt in Hamanns Korrespondenz bilden die Lektüren. Im Nachweis von Zitaten und benutzten Büchern besteht eine Hauptaufgabe des Kommentars. Auch die Verbindungen von Brief- und Werktexten (Stellenangaben nach den Erstdrucken und der Werkausgabe: <span class="kursiv">Sämtliche Werke,</span> hg. v. Josef Nadler. 6 Bde. [Wien 19491957, Reprint 1999] [=N], sowie bei den sog. Londoner Schriften: <span class="kursiv">Londoner Schriften,</span> hg. v. Oswald Bayer u. Bernd Weißenborn [München 1993] [=LS]) Hamanns werden nachgewiesen. </p>
<p class="Text_NI">Die Stellenkommentare sind mit einem Quellen-/Personen-, mit einem Bibelstellenregister und mit einer Forschungsbibliographie verlinkt. Das Quellen- und Personenregister ist alphabetisch nach Autoren sortiert; Zeitschriften mit mehreren Herausgebern sind nach dem Titel einsortiert. Die Nachweise der Bezugstexte Hamanns im Register verweisen auf die Erstdrucke und die von ihm konsultierten Ausgaben (sofern belegbar), sie verlinken außerdem auf Digitalisate dieser Ausgaben, wenn solche publiziert sind. Existiert eine moderne kritische Ausgabe des Bezugstextes, so wird diese angegeben. Außerdem ist der sog. »Biga«-Titeleintrag (Biga Bibliothecarum N V S. 15121) zitiert, ein 1776 gedruckter Versteigerungskatalog, in dem die Bibliotheken Hamanns und die seines Freundes Johann Gotthelf Lindner verzeichnet sind.</p>
<p class="Text_NI">Das Register enthält i.d.R. für die Personen Stellenverweise nur auf das im jeweiligen Brief erste Vorkommen. Orte werden im Stellenkommentar, wo möglich, mit der heutigen Bezeichnung und den Geo-Koordinaten versehen. Für heute ungebräuchliche Worte, regionale und dialektale Idiotismen werden Übersetzungen versucht. </p>
<p class="Text_NI">Die biographischen Angaben zu Personen im Register gehen über wenige Eckdaten (mit Verweis auf den Eintrag in einem biographischen Standard-Lexikon) nur dann hinaus, wenn Informationen, die in Verbindung mit Hamanns Leben und Lektüren stehen, geboten werden müssen. Das Register wird parallel zur Stellenkommentierung erarbeitet, ist also noch nicht abgeschlossen. </p>
<p class="Text_NI">Die Forschungsbibliographie enthält Titel zu Hamanns Leben und Werk und soll beständig aktualisiert werden. </p>
<p class="Text_NI">Im weiteren Verlauf der Edition werden außerdem erstellt: eine Verschlagwortung der Forschungsliteratur; eine Zeitleiste zum Leben Hamanns (welche die Zuordnung von Ereignissen und Aufenthaltsorten zu entsprechenden Briefen erleichtert). </p>
<p class="Text_NI">Die Online-Publikation der Briefe und des Stellenkommentars ermöglicht eine kontinuierte Revision desselben. Wir möchten Sie einladen, mit Ergänzungen, Korrekturen und Vorschlägen zu dessen Verbesserung beizutragen. Senden Sie uns diese an <a href="mailto:post@hamann-ausgabe.de">post@hamann-ausgabe.de</a>. Nach unserer Prüfung fügen wir diese in den Online-Kommentar ein (auf Wunsch auch mit Namensnennung des Beiträgers).</p>
<div class="Ueberschrift2">Zitierempfehlung</div>
Johann Georg Hamann: <span class="kursiv">Kommentierte Briefausgabe.</span> Hg. von Leonard Keidel und Janina Reibold, auf Grundlage der Vorarbeiten Arthur Henkels, unter Mitarbeit von Gregor Babelotzky, Konrad Bucher, Christian Großmann, Carl Friedrich Haak, Luca Klopfer, Johannes Knüchel, Isabel Langkabel und Simon Martens (Heidelberg 2020&#x202f;ff.). URL: www.hamann-ausgabe.de [= HKB]
<br/><br/>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace HaLive.Pages
{
public class RichtlinienModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@@ -0,0 +1,63 @@
@page
@model HaLive.Pages.WerkausgabeModel
@{
ViewData["Title"] = "Werkausgabe";
}
<div class="mainhead row"><!-- + sticky-top if sticky -->
<!--Sticky grey space on top of header -->
<div class="col">
<div class="widehead">
<div class="flexcol">
<div style="align-self: flex-end">
<br/>
</div>
<div class="flexrow" style="margin-bottom:-30px">
<div class="heading">
Werkausgabe
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row no-gutters">
<div class="col">
<div class="registerbox">
<div class="text editionstext">
<div class="Ueberschrift2">Kommentierte Neuedition ausgewählter Werke</div>
<p class="Text_NI nodist">Die Edition der Werke Hamanns durch Josef Nadler<a class="Fußnotenzeichen" name="FnZ-1" href="#FnA-1">1</a> ist problematisch und wird von der Hamann-Philologie bereits seit Erscheinen des ersten Bandes stark kritisiert.<a class="Fußnotenzeichen" name="FnZ-2" href="#FnA-2">2</a> Die Kritik betrifft einerseits die konzeptionelle Schwäche der Ausgabe, die Schriften nach Sach- anstelle von Zeitgruppen anzuordnen, andererseits und vor allem jedoch textkritische Probleme wie unzählige Fehllesungen, falsche Manuskriptanordnungen sowie Nadlers willkürlichen Umgang mit den handschriftlichen Annotationen Hamanns, die von ihm meist ohne Nachweis und Angabe von Gründen mit dem Drucktext vermischt wurden. Aus diesen Gründen wird im Rahmen der Kommentierten Hamann-Ausgabe die Neuedition ausgewählter Schriften Hamanns mit Kommentar erfolgen. Dabei werden
<ul class="Stichpunkte">
<li>sämtliche überlieferte Materialien im Zusammenhang mit dem jeweiligen Werk historisch-kritisch ediert</li>
<li>sämtliche überlieferte handschriftliche Annotationen Hamanns differenziert zum Drucktext vermerkt. Kontamination verschiedener Textträger sind methodisch ausgeschlossen.</li>
<li>Auszeichnungen sowie die typographische Eigentümlichkeit der Texte differenziert in eine moderne Typographie übersetzt</li>
<li>Texteingriffe, wo diese nötig sind, als solche gekennzeichnet.</li>
</ul>
</p>
<p class="Text_NI nodist">Der Kommentar wird sowohl als Stellen-, als auch als systematisch aufgebauter Kommentar erfolgen. Darüber hinaus wird jeder Band
<ul class="Stichpunkte">
<li>eine ausführliche Einleitung</li>
<li>Dokumente zur Entstehungsgeschichte</li>
<li>eine Bibliographie</li>
</ul>
enthalten.</p>
<div class="Ueberschrift2">Bereits erschienene Bände</div>
<p class="Text_NI">Johann Georg Hamann, Fliegender Brief. Historisch-kritische Ausgabe. Mit einer Einführung, Kommentar und Dokumenten zur Entstehungsgeschichte hg. von Janina Reibold, 2 Bde. [= Philosophische Bibliothek 707] (Hamburg: Meiner Verlag 2018) [<a class="ExternerLink" href="https://meiner.de/fliegender-brief.html">‣</a>]</p>
<div class="Ueberschrift2">Geplante Bände</div>
<ul class="Stichpunkte">
<li>Sokratische Denkwürdigkeiten / Wolken (vorauss. 2020)</li>
<li>Kreuzzüge des Philologen</li>
</ul>
<br/>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-1" href="#FnZ-1">1</a>Johann Georg Hamann, Sämtliche Werke. Historisch-kritische Ausgabe. Hg. v. Josef Nadler. 6 Bde. (Wien 194957).</div>
<div class="Fußnote"><a class="Fußnotenanker" name="FnA-2" href="#FnZ-2">2</a>Vgl. etwa Walter Boehlich, Forschungsbericht. Die historisch-kritische Hamann-Ausgabe, in: Euphorion 50 (1956), 341356.</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace HaLive.Pages
{
public class WerkausgabeModel : PageModel
{
public void OnGet()
{
}
}
}

22
HaLive/Pages/Error.cshtml Normal file
View File

@@ -0,0 +1,22 @@
@page
@model ErrorModel
@{
ViewData["Title"] = "Error";
}
<div class="mainhead row no-gutters">
<div class="col">
<div class="widehead">
<div class="flexcol">
<div class="flexrow" style="margin-bottom:-30px; align-items: last baseline;">
<div class="heading is-active">
Fehler
</div>
</div>
<div class="alphabet is-active">
Die angeforderte Seite konnte nicht gefunden werden.
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace HaLive.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}

351
HaLive/Pages/Index.cshtml Normal file
View File

@@ -0,0 +1,351 @@
@page
@inject ILibrary lib
@using System.Collections.Generic
@using System.Linq;
@using HaDocument.Comparers
@model IndexModel
@functions{
string setAct(string s) {
if (Model.person == s)
return "is-active";
else
return "";
}
string setActPg(string s) {
if (Model.selpage == s)
return "is-active";
else
return "";
}
string Position() {
string ret = "";
if (Model.cleanpage != 0)
ret += " hasAncestors";
if (Model.cleanpage == Model.Result.Count()-1)
ret += " isLast";
return ret;
}
string generateTTMsg(Meta m) {
if (m.isProofread == OptionalBool.False && m.hasOriginal == OptionalBool.False) {
return "Original verschollen. Der Brieftext wurde noch nicht textkritisch geprüft.";
}
if (m.isProofread == OptionalBool.False && m.hasOriginal != OptionalBool.False) {
return "Original vorhanden. Der Brieftext wurde noch nicht textkritisch geprüft.";
}
if (m.isProofread != OptionalBool.False && m.hasOriginal == OptionalBool.False ) {
return "Original verschollen. Der Brieftext wurde anhand der vorhandenen Quellen kritisch geprüft.";
}
return "Der Brieftext wurde anhand des Originals kritisch geprüft.";
}
}
@{
ViewData["Title"] = "Suche";
var pg = 0;
}
<div class="mainhead row no-gutters">
<div class="col">
<div class="widehead searchbar d-none d-lg-block">
<div class="alphabet">
<div class="row">
<div class="col-7">
<h1>
Volltextsuche
<span class="searchheading">
(Beta)
</span>
</h1>
<form>
<div class="form-inline hformbox">
<input type="search" class="form-control hform" asp-for="search" placeholder="Suchbegriff" />
<input type="submit" class="form-control hform" value="Suchen" />
</div>
</form>
</div>
@if (String.IsNullOrWhiteSpace(Model.search))
{
<div class="col-5 align-self-end">
<div class="zhselector">
<form style="margin-left: 105px;">
<div class="form-inline hformbox textform">
Briefnummer&nbsp;&nbsp;
<input type="search" class="form-control small-form hform" asp-for="fdletter" />
<input type="submit" class="form-control hform" value="Nachschlagen" />
</div>
</form>
<form>
<div class="form-inline hformbox textform">
<span class="autopsic">
<a class="hlink invlink autopsic" href="/Supplementa/Forschung/editionen/#1955" style="font-variant: small-caps;">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" class="bi bi-book" viewBox="0 0 16 20">
<path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811V2.828zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783z"/>
</svg> Z&VeryThinSpace;H
</a>
</span>&nbsp;&nbsp;
Band&nbsp;
&nbsp;
<select class="form-control hform" asp-for="havolume">
@foreach (var y in lib.Options.AvailableVolumes)
{
<option>@y</option>
}
</select>
&thinsp;,&nbsp;Seite&nbsp;&nbsp;
<input type="search" class="form-control small-form hform" value="1" asp-for="hapage" />
<input type="submit" class="form-control hform" value="Nachschlagen" />
</div>
</form>
</div>
</div>
}
</div>
</div>
</div></div></div>
<div class="row no-gutters mainhead sticky" style="top: 110px !important; z-index: 1000 !important;">
<div class="widehead yearsidebar">
@if (Model.State != IndexModel.IndexState.Initial)
{<div class="backbutton"><a class="hlink" href="/">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-arrow-left" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z"/>
</svg>&nbsp;alle Briefe anzeigen
</a></div>}
@if (Model.FailState == IndexModel.IndexFailState.LetterNotFound)
{<span class="searchwarning">Brief mit der Nummer @Model.fdletter nicht gefunden.</span>}
@if (Model.FailState == IndexModel.IndexFailState.SearchNoResult)
{<span class="searchwarning">Keine Briefe gefunden, die die &#x00BB;@Model.search&#x00AB; enthalten.</span>}
@if (Model.FailState == IndexModel.IndexFailState.SearchTooManyResults)
{<span class="searchwarning">Mehr als 1000 Treffer für &#x00BB;@Model.search&#x00AB;. Bitte grenzen Sie Ihre Suche ein.</span>}
@if (Model.FailState == IndexModel.IndexFailState.ZHNotFound)
{<span class="searchwarning">Keine Briefe auf <span class="letterselection aq nnumber"><a class="hlink invlink searchwarning" href="/Supplementa/Forschung/editionen/#1955" style="font-variant: small-caps;">
Z&VeryThinSpace;H
</a> @HTMLHelpers.ToRoman(Int32.Parse(Model.havolume)), @Model.hapage</span> gefunden.</span>}
@if (Model.FailState == IndexModel.IndexFailState.None)
{
<h1>Briefauswahl
@if (Model.State == IndexModel.IndexState.Initial)
{<span class="letterselection">alle Briefe; chronologische Anzeige.</span>}
@if (Model.State == IndexModel.IndexState.Search)
{<span class="letterselection">Briefe, die &#x00BB;@Model.search&#x00AB; enthalten.</span>}
@if (Model.State == IndexModel.IndexState.ZHLookup)
{<span class="letterselection aq nnumber">
Briefe auf
<a class="hlink invlink" href="/Supplementa/Forschung/editionen/#1955" style="font-variant: small-caps;">
Z&VeryThinSpace;H
</a> @HTMLHelpers.ToRoman(Int32.Parse(Model.havolume)), @Model.hapage</span>}
@if (Model.State == IndexModel.IndexState.PersonLookup)
{<span class="letterselection">Briefe von und an @lib.Persons[Model.person].Name.</span>}
</h1>
}
@if (Model.Result.Count() > 1 && Model.FailState == IndexModel.IndexFailState.None)
{
@foreach (var pag in Model.Result)
{
pg = Model.Result.IndexOf(pag)+1;
<span class="navigation-page">
<a class="invlink @setActPg(pg.ToString())" href="/?selpage=@pg&person=@Model.person&search=@Model.search">
@if (pag.First().First().MetaData.Sort.Year != pag.Last().Last().MetaData.Sort.Year)
{
<span>
@pag.First().First().MetaData.Sort.Year&ndash;@pag.Last().Last().MetaData.Sort.Year
</span>
}
@if (pag.First().First().MetaData.Sort.Year == pag.Last().Last().MetaData.Sort.Year)
{
<span>
@pag.First().First().MetaData.Sort.Year
</span>
}
</a> @if(pag != Model.Result.Last())
{
<span class="muted">&ThinSpace;</span>
}
</span>
}
}
</div>
</div>
@if (Model.FailState == IndexModel.IndexFailState.None)
{
<div class="row no-gutters">
<div class="col entriescolumn">
<div id="timeline">
<div class="@Position()">
@foreach (var l in Model.Result.ElementAt(Model.cleanpage))
{
<section>
<div class="year" style="top: 240px; z-index: 900;">
@l.Key <span class="printbutton">
<span class="label">
<a class="hlink" href="#">PDF
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="bi bi-arrow-down-circle" viewBox="0 0 14 18">
<path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/>
</svg>
</a>
</span>
</span>
<hr></div>
@foreach (var entry in l)
{
<section>
<div class="lettercard flexrow">
<a href="/Briefe/@entry.MetaData.Autopsic" class="hlink invlink">
<div class="nnumber letcount flexcol">@entry.MetaData.Autopsic</div>
<div class="letdesc flexcol">
@if(entry.MetaData.Senders.Any() || entry.MetaData.Receivers.Any())
{
<span class="date">
@entry.MetaData.Date</span><span>&nbsp;</span>
@if (entry.MetaData.ZH != null)
{
<span>
<span class="nnumber autopsic">&thinsp;
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" class="bi bi-book" viewBox="0 0 16 18">
<path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811V2.828zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783z"/>
</svg>
ZH @HTMLHelpers.ToRoman(Int32.Parse(entry.MetaData.ZH.Volume)) @entry.MetaData.ZH.Page
</span>&nbsp;
</span>
}
else
{
<span>
<span class="nnumber autopsic-new">
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="currentColor" class="bi bi-asterisk" viewBox="0 0 16 20">
<path d="M8 0a1 1 0 0 1 1 1v5.268l4.562-2.634a1 1 0 1 1 1 1.732L10 8l4.562 2.634a1 1 0 1 1-1 1.732L9 9.732V15a1 1 0 1 1-2 0V9.732l-4.562 2.634a1 1 0 1 1-1-1.732L6 8 1.438 5.366a1 1 0 0 1 1-1.732L7 6.268V1a1 1 0 0 1 1-1z"/>
</svg>
Neu
</span>&nbsp;
</span>
}
@if(entry.MetaData.hasOriginal == OptionalBool.True)
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Original vorhanden">
&thinsp;Orig
</span>&nbsp;
</span>
}
else
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Original verschollen">
&thinsp;<span class="cross">Orig</span>
</span>&nbsp;
</span>
}
@if (entry.MetaData.ZH != null && entry.MetaData.ZH.dateChanged)
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Der Brief wurde gegenüber der Ausgabe ZH neu datiert">
&thinsp;neu datiert
</span>&nbsp;
</span>
}
@if(entry.MetaData.isProofread == OptionalBool.True)
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Textkritisch geprüft">
&thinsp;geprüft
</span>&nbsp;
</span>
}
else
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Nicht textkritisch geprüft">
&thinsp;<span class="cross">geprüft</span>
</span>&nbsp;
</span>
}
@if (lib.MarginalsByLetter.Contains(entry.MetaData.Index))
{
<span>
<span class="nnumber autopsic hv" data-bs-toggle="tooltip" data-bs-placement="top" title="Mit Stellenkommentar">
&thinsp;Komm
</span>&nbsp;
</span>
}
<br>
<span class="title">
<span class="senders">
@HTMLHelpers.GetEnumerationString(entry.MetaData.Senders.Select(x => lib.Persons[x].Name).ToList())
</span>
<span class="arrow">
@if(entry.MetaData.isDraft == OptionalBool.True) {
<span data-bs-toggle="tooltip" data-bs-placement="bottom" title="Entwurf">&nbsp;&#8603;&nbsp;</span>
}
else
{
<span>&nbsp;&#8594;&nbsp;</span>
}
</span>
<span class="receivers">
@HTMLHelpers.GetEnumerationString(entry.MetaData.Receivers.Select(x => lib.Persons[x].Name).ToList())
</span>
</span>
}
else
{
<span>&nbsp;</span>
}
</a>
@if (entry.Results != null && entry.Results.Count() > 0)
{
<div class="sresults">
@foreach (var result in entry.Results)
{
<div class="sresult">
<a href="/Briefe/@entry.MetaData.Index#@result.Page-@result.Line" class="hlink invlink">
<span class="pgln">@result.Page/@result.Line:</span>&nbsp;<span class="sprev">@result.PreviewString</span>
</a>
</div>
}
</div>
}
</div>
</section>
}
</section>
}
</div>
</div>
</div>
@if(String.IsNullOrWhiteSpace(Model.search) &&
String.IsNullOrWhiteSpace(Model.hapage))
{
<div class="col-4 namesidebar d-none d-lg-block">
<h4>Korrespondenzpartner:innen</h4>
<a class="hlink person invlink @setAct("")" href="/">Alle</a>
@foreach (var p in Model.SelectedPersons.Where(x => x.Index != "1")) {
<a class="hlink invlink person @setAct(p.Index)" href="/?person=@p.Index">@p.Name</a>
}
</div>
<div>
</div>
}
</div>
}
@section Scripts {
<script>
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
})
</script>
}

View File

@@ -0,0 +1,222 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using HaDocument.Interfaces;
using System.Collections.Immutable;
using HaDocument.Models;
using HaDocument.Comparers;
using HaXMLReader.EvArgs;
using HaLive.Models;
using HaXMLReader.Interfaces;
using System.Collections.Concurrent;
namespace HaLive.Pages
{
public class IndexModel : PageModel
{
const int MAX_SRESULTS = 1000;
const int MINLETTPG = 90;
[BindProperty(SupportsGet = true)]
public string fdletter { get; set; }= "";
[BindProperty(SupportsGet = true)]
public string search { get; set; } = "";
[BindProperty(SupportsGet = true)]
public string person { get; set; } = "";
[BindProperty(SupportsGet = true)]
public string havolume { get; set; } = "";
[BindProperty(SupportsGet = true)]
public string hapage { get; set; } = "";
[BindProperty(SupportsGet = true)]
public string selpage { get; set; } = "";
public enum IndexState {
Initial,
Search,
ZHLookup,
PersonLookup
}
public enum IndexFailState {
None,
SearchTooManyResults,
SearchNoResult,
ZHNotFound,
LetterNotFound
}
public int cleanpage { get; set; } = 0;
public IndexState State { get; set; } = IndexState.Initial;
public IndexFailState FailState { get; set; } = IndexFailState.None;
public List<List<IGrouping<int, DocumentSearchResult>>> Result = null;
public ImmutableSortedSet<Person> SelectedPersons = null;
private ILibrary _lib;
private IReaderService _readerService;
public IndexModel(ILibrary lib, IReaderService readerservice) {
_lib = lib;
_readerService = readerservice;
PrepareData();
}
private void PrepareData() {
// Create a list of persons
var _SelectedPersons = new List<Person>(100);
foreach (var letter in _lib.MetasByDate) {
foreach (var sender in letter.Senders) {
var p = _lib.Persons[sender];
if (!_SelectedPersons.Contains(p)) {
_SelectedPersons.Add(p);
}
}
foreach (var receiver in letter.Receivers) {
var p = _lib.Persons[receiver];
if (!_SelectedPersons.Contains(p)) {
_SelectedPersons.Add(p);
}
}
}
SelectedPersons = _SelectedPersons.ToImmutableSortedSet(new PersonComparer());
}
public IActionResult OnGet() {
if (!String.IsNullOrWhiteSpace(fdletter)) {
if (_lib.Metas.Where(x => x.Value.Autopsic == fdletter).Any())
return Redirect("/Briefe/" + fdletter);
else
FailState = IndexFailState.LetterNotFound;
State = IndexState.Initial;
return Default();
}
// State detection and Execution
if (!String.IsNullOrWhiteSpace(search)) {
State = IndexState.Search;
return Search();
}
else if (!String.IsNullOrWhiteSpace(person)) {
State = IndexState.PersonLookup;
return PersonLookup();
}
else if (!String.IsNullOrWhiteSpace(havolume) ||
!String.IsNullOrWhiteSpace(hapage)) {
State = IndexState.ZHLookup;
return ZHLookup();
}
else {
State = IndexState.Initial;
return Default();
}
}
internal ActionResult Search() {
var ret = new ConcurrentBag<DocumentSearchResult>();
var searchin = _lib.MetasByDate.Select(x => new DocumentSearchResult(x)).ToImmutableSortedSet(new LetterComparer());
var cnt = 0; //TODO: Nicht in threads manipulieren
Parallel.ForEach (searchin, (letter, state) => {
if (cnt > 1000) {
FailState = IndexFailState.SearchTooManyResults;
state.Break();
}
var x = new DocumentSearch(letter, _readerService.RequestStringReader(_lib.Letters[letter.MetaData.Index].Element), search);
cnt = cnt + x.Act().Results.Count;
if (x._searchResult.Results.Count > 0 ) ret.Add(x._searchResult);
});
if (ret.Count() == 0) {
FailState = IndexFailState.SearchNoResult;
}
return Execute(ret);
}
internal ActionResult ZHLookup() {
var ret = ImmutableSortedSet.CreateBuilder(new LetterComparer());
ImmutableDictionary<string, ImmutableDictionary<string, string>> pagedic;
var selvolume = _lib.Structure.TryGetValue(havolume.Trim(), out pagedic);
if (selvolume) {
ImmutableDictionary<string, string> linedic;
var selpage = pagedic.TryGetValue(hapage.Trim(), out linedic);
if (selpage) {
foreach (var entry in linedic) {
ret.Add(_lib.MetasByDate.Where(x => x.Index == entry.Value).Select(x => new DocumentSearchResult(x)).First());
}
if (ret.Count == 1) {
return Redirect("/Briefe/" + ret.First().MetaData.Autopsic + "#" + hapage + "-1");
}
}
else {
FailState = IndexFailState.ZHNotFound;
return Execute(ret);
}
}
else {
return FatalError();
}
return Execute(ret);
}
internal ActionResult PersonLookup() {
return Execute(_lib.MetasByDate
.Where(x => x.Senders.Contains(person) || x.Receivers.Contains(person))
.Select(x => new DocumentSearchResult(x)));
}
internal ActionResult Default() {
return Execute(_lib.MetasByDate
.Select(x => new DocumentSearchResult(x)));
}
internal ActionResult Execute(IEnumerable<DocumentSearchResult> _result) {
if (_result == null) FatalError();
var res = _result.OrderBy(x => x, new LetterComparer()).ToLookup(x => x.MetaData.Sort.Year, x => x);
return Paginate(res);
}
internal ActionResult Paginate(ILookup<int, DocumentSearchResult> _result) {
if (_result == null) return Return();
var curr = new List<IGrouping<int, DocumentSearchResult>>();
Result = new List<List<IGrouping<int, DocumentSearchResult>>>();
foreach (var elem in _result) {
curr.Add(elem);
if (curr.SelectMany(x => x).Count() > MINLETTPG || elem == _result.Last()) {
Result.Add(new List<IGrouping<int, DocumentSearchResult>>(curr));
curr.Clear();
}
}
if (!String.IsNullOrWhiteSpace(selpage)) {
int no;
var isNo = Int32.TryParse(selpage, out no);
if (!isNo ||
Result.Count < no ||
no <= 0) {
return FatalError();
}
else {
cleanpage = no - 1;
}
}
else {
selpage = "1";
}
return Return();
}
internal ActionResult FatalError() {
Response.StatusCode = 404;
return RedirectToPage("/Error");
}
internal ActionResult Return() {
return Page();
}
}
}

382
HaLive/Pages/Privacy.cshtml Normal file
View File

@@ -0,0 +1,382 @@
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<div class="mainhead row no-gutters"><!-- + sticky-top if sticky -->
<!--Sticky grey space on top of header -->
<div class="col">
<div class="widehead flexcol">
<div class="flexrow" style="margin-bottom:-30px; align-items: last baseline;">
<div class="heading">
Impressum & Datenschutzerklärung
</div>
</div>
</div>
</div>
</div>
<div class="row no-gutters">
<div class="col entriescolumn">
<div class="registerbox">
<div class=WordSection1>
<div class="impress" style='mso-element:para-border-div;border:solid windowtext 1.0pt;
mso-border-alt:solid windowtext .5pt;padding:12.0pt 4.0pt 1.0pt 12.0pt'>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><b style='mso-bidi-font-weight:
normal'>Telemedienanbieter im Sinne des § 5 TMG<o:p></o:p></b></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'>Theodor Springmann
Stiftung<br>
Hirschgasse 2<br>
69120 Heidelberg</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'>Telefon +49 6221 436235<br>
Email info@theodor-springmann-stiftung.de</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><b>Rechtsform und Sitz<o:p></o:p></b></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'>Die Theodor Springmann
Stiftung ist eine rechtsfähige Stiftung bürgerlichen Rechts.<br>
Sitz der Stiftung ist Heidelberg.</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><b style='mso-bidi-font-weight:
normal'>Vorstand der Theodor Springmann Stiftung<o:p></o:p></b></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'>Dr. Randolf Straky
(Präsident)</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><b style='mso-bidi-font-weight:
normal'>Geschäftsführung<o:p></o:p></b></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'>Dr. Randolf Straky<br>
Theodor Springmann Stiftung<br>
Hirschgasse 2<br>
69120 Heidelberg</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><b style='mso-bidi-font-weight:
normal'>Zuständige Aufsichtsbehörde<o:p></o:p></b></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'>Regierungspräsidium
Karlsruhe<br>
Schlossplatz 13<br>
76131 Karlsruhe</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'>https://rp.baden-wuerttemberg.de/Themen/Stiftung/Seiten/Ansprechpartner.aspx</p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><b style='mso-bidi-font-weight:
normal'>Redaktionelle Verantwortung nach § 55 Abs. 2 RStV<o:p></o:p></b></p>
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .5pt;
padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'>Janina Reibold<br>
Theodor Springmann Stiftung<br>
Hirschgasse 2<br>
69120 Heidelberg</p>
</div>
<p class=MsoNormal><o:p>&nbsp;</o:p></p>
<h1>Datenschutzerklärung</h1>
<h2>Präambel</h2>
<p class=MsoNormal>Diese Datenschutzerklärung informiert Sie über die Art, den
Umfang und den Zweck der personenbezogenen Daten, die im Rahmen dieser
Onlinepräsenz von Ihnen erhoben und von uns verarbeitet werden, sowie die Ihnen
zustehenden Rechte.</p>
<p class=MsoNormal>Personenbezogene Daten sind alle Informationen, die sich auf
eine identifizierte oder identifizierbare natürliche Person beziehen. Als
identifizierbar wird eine natürliche Person angesehen, die direkt oder indirekt
identifiziert werden kann. Im Hinblick auf weitere verwendete Begrifflichkeiten
verweisen wir auf die Definitionen der Datenschutz-Grundverordnung (DSGVO),
Artikel 4.</p>
<p class=MsoNormal>Erfolgt die Verarbeitung personenbezogener Daten auf
Grundlage des Art. 6 Abs. 1 <span class=SpellE>lit</span>. f DSGVO, so besteht
unser berechtigtes Interesse in der Erfüllung unseres satzungsgemäßen
Stiftungszwecks. Zweck der Stiftung ist es, in gemeinnütziger Weise
Wissenschaft und Kunst, Völkerverständigung und Entwicklungshilfe zu fördern
und zum menschlichen Selbstverständnis sowie zum Erkennen und Lindern strukturell
bedingter Not und Bedürftigkeit von Menschen in aller Welt beizutragen.</p>
<h2>Verantwortlicher</h2>
<p class=MsoNormal>Verantwortlich im Sinne von Art. 4 Abs. 7 DSGVO für die
Verarbeitung personenbezogener Daten ist:</p>
<p class=MsoNormal>Theodor Springmann Stiftung<br>
Hirschgasse 2<br>
69120 Heidelberg</p>
<p class=MsoNormal>www.theodor-springmann-stiftung.de<br>
info@theodor-springmann-stiftung.de</p>
<h2>Automatisch bei Nutzung unserer Onlinepräsenz erfasste Daten</h2>
<p class=MsoNormal>Mit der Nutzung unserer Onlinepräsenz werden automatisch
personenbezogene und allgemeine Daten vom Nutzer übermittelt und von uns
erfasst und gespeichert. Die von uns erhobenen Daten umfassen:</p>
<p class=MsoListParagraphCxSpFirst style='text-indent:-18.0pt;mso-list:l2 level1 lfo1'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>1)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>die IP-Adresse des ans Internet angeschlossenen
Netzwerkgeräts (Computer oder Router des Nutzers),</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l2 level1 lfo1'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>2)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>den verwendeten Browsertyp und dessen Version,</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l2 level1 lfo1'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>3)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>das verwendete Betriebssystem und dessen
Version,</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l2 level1 lfo1'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>4)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>die Internetseite, die den Nutzer auf unsere
Onlinepräsenz verweist (<span class=SpellE>Referrer</span>),</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l2 level1 lfo1'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>5)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>die Unterwebseiten, die der Nutzer auf unserer
Onlinepräsenz aufruft,</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l2 level1 lfo1'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>6)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>das Datum und die Uhrzeit des Aufrufs,</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l2 level1 lfo1'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>7)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>den Internet-Service-Provider des Nutzers,</p>
<p class=MsoListParagraphCxSpLast style='text-indent:-18.0pt;mso-list:l2 level1 lfo1'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>8)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>sonstige ähnliche Daten.</p>
<p class=MsoNormal>Die Theodor Springmann Stiftung zieht aus diesen Daten keine
Rückschlüsse auf die betroffenen Nutzer. Diese Informationen werden benötigt,
um</p>
<p class=MsoListParagraphCxSpFirst style='text-indent:-18.0pt;mso-list:l4 level1 lfo2'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>1)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>die vom Nutzer angeforderten Inhalte korrekt
auszuliefern,</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l4 level1 lfo2'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>2)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>technische Probleme zu diagnostizieren, unsere
IT-Systeme vor Angriffen zu schützen und im Falle eines Angriffs den
zuständigen Behörden notwendige Informationen zur Strafverfolgung bereitstellen
zu können,</p>
<p class=MsoListParagraphCxSpLast style='text-indent:-18.0pt;mso-list:l4 level1 lfo2'><![if !supportLists]><span
style='mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin'><span
style='mso-list:Ignore'>3)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>die Inhalte und die Bedienung unserer
Onlinepräsenz zu optimieren.</p>
<p class=MsoNormal>Die oben genannten Verarbeitungszwecke werden von Subsystemen
erfüllt, die unabhängig von anderen Subsystemen ihre jeweils eigene Kopie der
vom Nutzer erhobenen Daten erhalten, verarbeiten und löschen. Dabei werden den
Subsystemen lediglich die zur Ausführung ihrer Aufgabe erforderlichen Daten übergeben.
Alle Subsysteme befinden sich auf Servern der Theodor Springmann Stiftung.</p>
<h3>Auslieferung der vom Nutzer angeforderten Inhalte</h3>
<p class=MsoNormal>Mit der Anforderung einer Seite dieser Onlinepräsenz
übermittelt der Browser des Nutzers automatisch die IP-Adresse seines ans
Internet angeschlossenen Netzwerkgeräts (Computer oder Router) und andere Daten.
Ohne diese IP-Adresse können die Inhalte dieser Online-Präsenz nicht an den
Nutzer zurückgesendet werden. Daher ist die Speicherung und Verarbeitung der
IP-Adresse für den Betrieb dieser Onlinepräsenz notwendig. Ebenfalls
übermittelte Daten über den verwendeten Browser usw. werden gegebenenfalls
verwendet, um die Anzeige der Webseite an das Anzeigegerät oder den Browser
anzupassen. Die zum Zwecke der Auslieferung von Inhalten gesammelten Daten
werden direkt nach Übertragung der Inhalte vom Subsystem gelöscht. Die
Verarbeitung dieser Daten erfolgt auf der Grundlage eines berechtigten
Interesses nach Art. 6 Abs. 1 <span class=SpellE>lit</span>. f DSGVO.</p>
<h3>Diagnose und Schutz der IT-Systeme</h3>
<p class=MsoNormal>Daneben erfolgt eine Speicherung der oben genannten Daten in
Diagnose-Protokollen. Die Protokollierung ist notwendig, um etwaige technische
Probleme analysieren oder Angriffe erkennen und abwehren zu können. Bei
Angriffen auf unsere IT-Systeme übergeben wir die Diagnose-Protokolle den
zuständigen Strafverfolgungsbehörden. Die Diagnose-Protokolle werden nach 14
Tagen automatisch gelöscht. Die Speicherung und Verarbeitung dieser Daten
erfolgt auf Grundlage eines berechtigten Interesses nach Art. 6 Abs. 1 <span
class=SpellE>lit</span>. f DSGVO.</p>
<h3>Analyse zur Optimierung der Inhalte und der Bedienung</h3>
<p class=MsoNormal>Die oben genannten Daten werden von einem Webanalyseprogramm
verarbeitet. Dabei werden die Daten pseudonymisiert und aggregiert, so dass sie
einzelnen Nutzern nicht mehr zugeordnet werden können. Das Analyseprogramm wird
auf einem von uns betriebenen Server ausgeführt, daher werden keine Daten an
Dritte übermittelt. Der Zweck dieser Erfassung besteht in der Analyse der
Nutzung unseres Angebots, durch die eine Verbesserung unserer Webseiten, der
Inhalte und der Bedienung ermöglicht wird. Das Analyseprogramm speichert die
anonymisierten Daten ohne zeitliche Begrenzung. Die Verarbeitung dieser Daten
erfolgt auf der Grundlage eines berechtigten Interesses (Art. 6 Abs. 1 <span
class=SpellE>lit</span>. f DSGVO).</p>
<h2>Weitere auf der Onlinepräsenz erfasste Daten</h2>
<p class=MsoNormal>Neben den oben aufgeführten Daten können weitere Daten von
uns erfasst, gespeichert und verarbeitet werden.</p>
<h3>Sonstige Daten</h3>
<p class=MsoNormal>Sämtliche Daten, die mit dem Aufruf einer Webseite von
unserer Onlinepräsenz an den Nutzer übertragen werden, werden von unseren
Servern bereitgestellt. Wir nutzen kein von Dritten bereitgestelltes Content <span
class=SpellE>Delivery</span> Network (CDN), um Teile unserer Onlinepräsenz (z.
B. <span class=SpellE>Javascript</span>- oder <span class=SpellE>Webfont</span>-Dateien)
von dort an den Nutzer zu übermitteln. Wir verlinken auch nicht in soziale
Netzwerke. Insofern können von Dritten keine personenbezogenen Daten über
unsere Onlinepräsenz erhoben werden, es sei denn, die Datenerfassung durch
Dritte basiert auf einer gesetzlichen Grundlage und/oder wurde behördlich
angeordnet.</p>
<p class=MsoNormal>In unseren Inhalten können sich jedoch Hyperlinks („Links“)
auf fremde Onlineangebote befinden. Mit dem Anklicken eines solchen Links
verlässt der Nutzer unsere Onlinepräsenz und damit den Geltungsbereich dieser
Datenschutzerklärung.</p>
<h2>Erhobene Daten bei Kontakt</h2>
<p class=MsoNormal>Unsere Onlinepräsenz hält unter anderem aufgrund gesetzlicher
Vorgaben verschiedene Möglichkeiten bereit, mit uns in Kontakt zu treten. Sofern
eine betroffene Person Kontakt zu uns aufnimmt, werden die von der betroffenen
Person übermittelten personenbezogenen Daten automatisch gespeichert (z. B.
Telefonnummer, E-Mail-Adresse). Diese Angaben werden zum Zwecke der Bearbeitung
sowie für sich möglicherweise anschließende Kommunikation von uns gespeichert. Sobald
die Speicherung dieser Daten nicht mehr erforderlich ist und keine gesetzlichen
Archivierungsgründe vorliegen, werden die Daten gelöscht. Die Erforderlichkeit
wird alle zwei Jahre überprüft. Es erfolgt keine Weitergabe dieser
personenbezogenen Daten an Dritte.</p>
<p class=MsoNormal>Von betroffenen Personen übermittelte Informationen zur
Bearbeitung einer Kontaktanfrage werden gemäß Art. 6 Abs. 1 <span class=SpellE>lit</span>.
b (vertragliche und vorvertragliche Beziehungen) oder <span class=SpellE>lit</span>.
f (andere Anfragen) der DSGVO verarbeitet.</p>
<h2>Speicherung und Löschung von personenbezogenen Daten</h2>
<p class=MsoNormal>Personenbezogene Daten werden von uns für die Dauer der
entsprechenden gesetzlichen Aufbewahrungspflichten oder für den zur
Vertragserfüllung erforderlichen Zeitraum gespeichert. Liegen solche Gründe
nicht vor, werden personenbezogene Daten für den Zeitraum, der zur Erreichung
des Speicherzwecks erforderlich ist, verarbeitet und gespeichert, sofern in
dieser Datenschutzerklärung nicht ausdrücklich anderes angegeben ist. Sobald die
Daten für ihre Zweckbestimmung nicht mehr erforderlich sind oder der
Speicherungszweck entfällt, werden sie nach Maßgabe der gesetzlichen Vorschriften
gelöscht oder in ihrer Verarbeitung eingeschränkt.</p>
<p class=MsoNormal>Sollten die Daten nicht gelöscht werden dürfen, weil sie
einer gesetzlichen Aufbewahrungspflicht unterliegen, wird deren Verarbeitung durch
Archivierung eingeschränkt. Die Daten werden erst nach Ablauf der gesetzlich vorgeschriebenen
Speicherfrist gelöscht.</p>
<p class=MsoNormal>Alle sechs Monate wird routinemäßig geprüft, ob der Speicherungszweck
weggefallen bzw. die Aufbewahrungspflicht abgelaufen ist. Anschließend wird gegebenenfalls
die Löschung durchgeführt.</p>
<h2>Rechte der betroffenen Personen</h2>
<p class=MsoNormal>Unter den angegebenen Kontaktdaten können betroffene
Personen jederzeit nachgenannte Rechte ausüben. Eine betroffene Person kann von
uns verlangen, dass</p>
<p class=MsoListParagraphCxSpFirst style='text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span
style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>Auskunft über sie betreffende, bei uns
gespeicherte Daten und deren Verarbeitung erteilt wird (Art. 15 DSGVO),</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span
style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>sie betreffende unrichtige personenbezogene
Daten berichtigt werden (Art. 16 DSGVO),</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span
style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>sie betreffende, bei uns gespeicherte
personenbezogene Daten gelöscht werden (Art. 17 DSGVO),</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span
style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>die Verarbeitung sie betreffender, bei uns gespeicherter
Daten, die aufgrund gesetzlicher Vorschriften oder anderer Gründe nicht
gelöscht werden dürfen, eingeschränkt wird (Art. 18 DSGVO),</p>
<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span
style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>sie betreffende Daten übertragbar sind, soweit
sie in die Datenverarbeitung eingewilligt oder einen Vertrag mit uns
geschlossen hat (Art. 20 DSGVO)</p>
<p class=MsoListParagraphCxSpLast style='text-indent:-18.0pt;mso-list:l0 level1 lfo4'><![if !supportLists]><span
style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>sie betreffende Daten nach einem Widerspruch
nicht weiter von uns verarbeitet werden (Art. 21 DSGVO),</p>
<p class=MsoNormal>Eine betroffene Person hat ferner jederzeit das Recht,</p>
<p class=MsoListParagraphCxSpFirst style='text-indent:-18.0pt;mso-list:l1 level1 lfo5'><![if !supportLists]><span
style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>eine erteilte Einwilligung in die Erhebung und
Verarbeitung personenbezogener Daten nach Art. 6 Abs. 1 <span class=SpellE>lit</span>.
a oder Art. 9 Abs. 2 lit. a DSGVO für die Zukunft zu widerrufen (Art. 7 Abs. 3
DSGVO),</p>
<p class=MsoListParagraphCxSpLast style='text-indent:-18.0pt;mso-list:l1 level1 lfo5'><![if !supportLists]><span
style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
Symbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>sich mit einer Beschwerde an eine
Aufsichtsbehörde zu wenden (Art. 15 Abs. 1 <span class=SpellE>lit</span>. f
DSGVO). Eine Liste der Aufsichtsbehörden lässt sich unter <a href="https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html" target="blank">https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html</a></span>
abrufen.</p>
<h2>Änderung unserer Datenschutzerklärung</h2>
<p class=MsoNormal>Wir behalten uns vor, diese Datenschutzerklärung ohne vorherige
Ankündigung an neue rechtliche oder technische Sachverhalte sowie an Änderungen
unserer Leistungen oder Prozesse anzupassen. Es gilt die jeweils auf der
Onlinepräsenz veröffentlichte Version der Datenschutzerklärung.</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace HaLive.Pages
{
public class PrivacyModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@@ -0,0 +1,55 @@
@{
var agent = String.IsNullOrWhiteSpace(Context.Request.Headers["User-Agent"]) ? "" : (string)Context.Request.Headers["User-Agent"];
}
<!DOCTYPE html>
<html lang="de" >
<head>
<!--
<PageMap>
<DataObject type="document">
<Attribute name="title">Johann Georg Hamann: Kommentierte Briefausgabe (&#8239;H&#8239;&#8239;K&#8239;&#8239;B&#8239;)</Attribute>
<Attribute name="author">Hg. v. Leonard Keidel und Janina Reibold, auf Grundlage der Vorarbeiten Arthur Henkels, unter Mitarbeit von G. Babelotzky, K. Bucher, Ch. Großmann, C.F. Haak, L. Klopfer, J. Knüchel, I. Langkabel und S. Martens (Heidelberg 2020ff.)</Attribute>
<Attribute name="description">Durchsuchbare Online-Ausgabe der Briefe von und an Johann Georg Hamann.</Attribute>
</DataObject>
<DataObject type="thumbnail">
<Attribute name="src" value="https://hamann-ausgabe.de/favicon.ico" />
</DataObject>
</PageMap>
-->
<environment names="Development">
<script src="/_framework/aspnetcore-browser-refresh.js"></script>
</environment>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hamann: Kommentierte Briefausgabe (&#8239;H&#8239;&#8239;K&#8239;&#8239;B&#8239;) - @ViewBag.Title</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header class="sticky-top">
<partial name="_Menu" />
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2019 Theodor Springmann Stiftung <span class="text-align-right"><a href="/Privacy">Impressum und Datenschutzerklärung</a></span>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
@* <script src="https://unpkg.com/@@popperjs/core@@2"></script> *@
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
@RenderSection("Scripts", required: false)
</body>
</html>

View File

@@ -0,0 +1,172 @@
@model Microsoft.AspNetCore.Mvc.RazorPages.PageModel
@functions {
List<MenuItem> BuildMenu() {
List<MenuItem> Menu = new List<MenuItem>();
Menu.Add(new MenuPageItem() {
FriendlyName = "Suche und Briefauswahl",
DefaultRoute = "/Index"
});
Menu.Add(new MenuPageItem() {
FriendlyName = "Briefansicht",
DefaultRoute = "/Briefe"
});
Menu.Add(new MenuSubMenuItem() {
FriendlyName = "Register",
DefaultRoute = "/Supplementa/Register",
menuPages = new List<MenuPageItem>()
{
new MenuPageItem()
{
FriendlyName = "Register",
DefaultRoute = "/Supplementa/Register"
},
new MenuPageItem()
{
FriendlyName = "Bibelstellenregister",
DefaultRoute = "/Supplementa/Bibelstellen"
},
new MenuPageItem()
{
FriendlyName = "Forschungsbibliographie",
DefaultRoute = "/Supplementa/Forschung"
}
}
});
Menu.Add(new MenuSubMenuItem()
{
FriendlyName = "Zur Edition",
DefaultRoute = "/Edition/Richtlinien",
menuPages = new List<MenuPageItem>()
{
new MenuPageItem()
{
FriendlyName = "Kontakt",
DefaultRoute = "/Edition/Kontakt"
},
new MenuPageItem()
{
FriendlyName = "Mitwirkende",
DefaultRoute = "/Edition/Mitwirkende"
},
new MenuPageItem()
{
FriendlyName = "Editionsrichtlinien",
DefaultRoute = "/Edition/Richtlinien"
},
new MenuPageItem()
{
FriendlyName = "Editionsgeschichte",
DefaultRoute = "/Edition/Editionsgeschichte"
},
new MenuPageItem()
{
FriendlyName = "Werkausgabe",
DefaultRoute = "/Edition/Werkausgabe"
}
}
});
return Menu;
}
void MarkActive(List<MenuItem> Menu) {
var path = ViewContext.HttpContext.Request.Path;
if (path == "/") {
Menu.First().Active = true;
return;
}
foreach (var item in Menu) {
if (item is MenuPageItem) {
var comparing = path.Value.Length > item.DefaultRoute.Length ? path.Value.Substring(0, item.DefaultRoute.Length) : path.Value;
if (item.DefaultRoute == comparing) {
item.Active = true;
return;
}
}
else if (item is MenuSubMenuItem) {
var submenu = (MenuSubMenuItem)item;
foreach (var sub in submenu.menuPages) {
var comparing = path.Value.Length > sub.DefaultRoute.Length ? path.Value.Substring(0, sub.DefaultRoute.Length) : path.Value;
if (sub.DefaultRoute == comparing) {
sub.Active = true;
item.Active = true;
return;
}
}
}
}
}
string setAct(MenuItem item) {
if (item.Active)
return "is-active";
else
return "";
}
}
@{
var Menu = BuildMenu();
MarkActive(Menu);
}
<nav class="navbar navbar-expand-xl navbar-light contentbox" style="">
<a class="navbar-brand hlink invlink" style="font-size: 170%" href="/">
<img src="/favicon.ico" alt="HKB-Logo" loading="lazy">
&nbsp;
<div class=" d-none d-lg-inline">
Johann Georg Hamann: Kommentierte Briefausgabe <span class="title-abbrv">(HKB)</span>
</div>
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="float-right collapse navbar-collapse" id="navbarNavDropdown">
<ul class="mr-auto"></ul>
<div class="navbar-nav">
@foreach (var item in Menu)
{
@if(item is MenuPageItem)
{
@if(!item.Active)
{
<a class="nav-item nav-link invlink @setAct(item)" href="@item.DefaultRoute">@item.FriendlyName</a>
}
@if(item.Active)
{
<span class="nav-item nav-link invlink @setAct(item)">@item.FriendlyName</span>
}
continue;
} else if (item is MenuSubMenuItem)
{
var submenu = (MenuSubMenuItem)item;
@if (submenu.menuPages.Any())
{
<div class="nav-item dropdown">
<a class="nav-link @setAct(item) dropdown-toggle" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="">
@item.FriendlyName
</a>
<div class="dropdown-menu @setAct(item) collapsed-menu pull-left" id="@item.FriendlyName" aria-labelledby="navbarDropdown">
@foreach (var sub in submenu.menuPages)
{
<a class="dropdown-item nav-link @setAct(sub)" href="@sub.DefaultRoute">@sub.FriendlyName</a>
}
</div>
</div>
}
else
{
<a class="nav-item nav-link @setAct(item)" href="@item.DefaultRoute">@item.FriendlyName</a>
}
}
}
</div>
</div>
</nav>
@if(ViewContext.HttpContext.Request.Path == "/" || ViewContext.HttpContext.Request.Path.StartsWithSegments("/Index"))
{
<div class="alert alert-light show impress d-none d-lg-block" role="alert">
<a class="hlink invlink" href="/Edition/Mitwirkende">
Hg. v. Leonard Keidel und Janina Reibold, auf Grundlage der Vorarbeiten Arthur Henkels, unter Mitarbeit von G. Babelotzky, K. Bucher, Ch. Großmann, C.F. Haak, L. Klopfer, J. Knüchel, I. Langkabel und S. Martens (Heidelberg 2020ff.)
</a>
</div>
}

View File

@@ -0,0 +1,177 @@
@page "{id=AT}"
@model HaLive.Pages.BibelstellenModel
@inject IReaderService readerservice;
@inject ILibrary lib;
@functions{
string setAct(string s)
{
if (Model.id.ToString().ToLower() == s.ToLower())
return "is-active";
else
return "";
}
}
@{
// Acquire data
ViewData["Title"] = "Bibelstellenregister";
var at = "AT";
var ap = "AP";
var nt = "NT";
var id = Model.id.ToUpper();
var comments = lib.CommentsByCategory["bibel"].ToLookup(x => x.Index.Substring(0, 2).ToUpper()).Contains(id) ?
lib.CommentsByCategory["bibel"].ToLookup(x => x.Index.Substring(0, 2).ToUpper())[id] : null;
var availableletters = lib.CommentsByCategory["bibel"].ToLookup(x => x.Index.Substring(0, 2).ToUpper());
// Parsing Rules
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> OTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "lemma", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "lemma"))),
( x => x.Name == "title", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "title")))
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> CTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "lemma", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div"))),
( x => x.Name == "title", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")))
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> STag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "line", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("br")) )
};
List<(Func<Text, bool>, Action<StringBuilder, Text>)> Text_Funcs = new List<(Func<Text, bool>, Action<StringBuilder, Text>)>() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)> Whitespace_Funcs = new List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)>() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
string handleComment(Comment comm)
{
StringBuilder sb = new StringBuilder();
var rd = readerservice.RequestStringReader(comm.Lemma);
new StandardSubscriber(rd, sb, OTag_Funcs, STag_Funcs, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
sb.Append(HTMLHelpers.CreateElement("div", "lemma", comm.Index));
new LinkBuilder(lib, rd, sb);
rd.Read();
var backlinks = lib.Backlinks.ContainsKey(comm.Index) ? lib.Backlinks[comm.Index].OrderBy(x => x.Letter) : null;
if (backlinks != null)
{
sb.Append(HTMLHelpers.CreateElement("div", "backlinks"));
var arrow = false;
foreach (var blk in backlinks)
{
var let = lib.Metas.ContainsKey(blk.Letter) ? lib.Metas[blk.Letter] : null;
if (let != null)
{
if (!arrow)
{
sb.Append("&emsp;&rarr;&nbsp;");
sb.Append("HKB&nbsp;");
arrow = true;
}
sb.Append(HTMLHelpers.CreateElement("a", "backlink", "/Briefe/" + let.Autopsic + "#" + blk.Page + "-" + blk.Line));
@* sb.Append(" "); *@
var linkstring = "";
var ZHstring = "";
if (let.ZH != null)
{
ZHstring += HTMLHelpers.ToRoman(Int32.Parse(let.ZH.Volume)) + "&nbsp;";
}
var pglnstring = "";
@* linkstring += "HKB&nbsp;"; *@
linkstring += let.Autopsic;
pglnstring += "&nbsp;(&#8239;" + ZHstring + blk.Page + "/" + blk.Line + "&#8239;)";
linkstring += pglnstring;
sb.Append(linkstring);
if (blk != backlinks.Last())
sb.Append(",&emsp;");
sb.Append(HTMLHelpers.CreateEndElement("a"));
}
}
sb.Append(HTMLHelpers.CreateEndElement("div"));
}
sb.Append(HTMLHelpers.CreateEndElement("div"));
rd = readerservice.RequestStringReader(comm.Entry);
new StandardSubscriber(rd, sb, OTag_Funcs, STag_Funcs, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
new LinkBuilder(lib, rd, sb);
rd.Read();
return sb.ToString();
}
}
<div class="mainhead row">
<!-- + sticky-top if sticky -->
<!--Sticky grey space on top of header -->
<div class="col">
<div class="widehead">
<div class="flexcol">
<div style="align-self: flex-end" class="printbutton">
<a class="" href="/pdf/Bibelstellen-Register_HamannBriefe.pdf">
PDF
</a>
</div>
<div class="flexrow" style="margin-bottom:-10px; align-items: last baseline;">
<div class="heading">
@ViewData["Title"]
</div>
</div>
<div class="alphabet">
<span><a class="invlink @setAct(at)" href="/Supplementa/Bibelstellen/AT">Altes Testament</a> &emsp;</span>
<span><a class="invlink @setAct(ap)" href="/Supplementa/Bibelstellen/AP">Apogryphen</a> &emsp;</span>
<span><a class="invlink @setAct(nt)" href="/Supplementa/Bibelstellen/NT">Neues Testament</a> &emsp;</span>
</div>
</div>
</div>
</div>
</div>
<div class="row no-gutters">
<div class="col">
<div class="registerbox">
<div class="text">
@foreach (var comm in comments.OrderBy(x => x.Order))
{
<div class="comment">
@Html.Raw(handleComment(comm))
@if (comm.Kommentare != null)
{
@foreach (var subcomm in comm.Kommentare.OrderBy(x => x.Value.Lemma.Length).ThenBy(x => x.Value.Lemma))
{
<div class="subsection">
@Html.Raw(handleComment(subcomm.Value))
</div>
}
}
</div>
}
</div>
</div>
</div>
</div>
@section Scripts {
<script>
// The function actually applying the offset
function offsetAnchor() {
if (location.hash.length !== 0) {
window.scrollTo(window.scrollX, window.scrollY - 280);
}
}
// Captures click events of all <a> elements with href starting with #
$(document).on('click', 'a[href^="#"]', function (event) {
// Click events are captured before hashchanges. Timeout
// causes offsetAnchor to be called after the page jump.
window.setTimeout(function () {
offsetAnchor();
}, 0);
});
// Set the offset when entering page with hash present in the url
window.setTimeout(offsetAnchor, 0);
$("#" + window.location.hash.substr(1)).prepend("<div class=\"selected\">☛</div> ");
</script>
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using HaDocument.Interfaces;
namespace HaLive.Pages
{
public class BibelstellenModel : PageModel
{
private ILibrary _lib;
[BindProperty(SupportsGet = true)]
public string id { get; set; }
public BibelstellenModel(ILibrary lib) {
_lib = lib;
}
public IActionResult OnGet()
{
if (!_lib.CommentsByCategory["bibel"].ToLookup(x => x.Index.Substring(0,2).ToUpper()).Contains(id.ToUpper())) {
Response.StatusCode = 404;
return RedirectToPage("/Error");
}
return Page();
}
}
}

View File

@@ -0,0 +1,207 @@
@page "{id=A}"
@model HaLive.Pages.ForschungModel
@inject IReaderService readerservice;
@inject ILibrary lib;
@functions{
string setAct(string s) {
if (Model.id.ToString().ToLower() == s.ToLower())
return "is-active";
else
return "";
}
}
@{
// Acquire data
ViewData["Title"] = "Forschungsbibliographie";
var id = Model.id.ToUpper();
var comments = Model.SelectComments();
var availableletters = lib.CommentsByCategoryLetter["forschung"].OrderBy(x => x.Key);
// Parsing Rules
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> OTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "lemma", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "lemma"))),
( x => x.Name == "title", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "title"))),
( x => x.Name == "titel", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "title")))
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> CTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "lemma", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div"))),
( x => x.Name == "title", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div"))),
( x => x.Name == "titel", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")))
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> STag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "line", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("br")) )
};
List<(Func<Text, bool>, Action<StringBuilder, Text>)> Text_Funcs = new List<(Func<Text, bool>, Action<StringBuilder, Text>)>() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)> Whitespace_Funcs = new List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)>() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
string handleComment(Comment comm) {
StringBuilder sb = new StringBuilder();
var rd = readerservice.RequestStringReader(comm.Lemma);
new StandardSubscriber(rd, sb, OTag_Funcs, STag_Funcs, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
sb.Append(HTMLHelpers.CreateElement("div", "lemma", comm.Index));
new LinkBuilder(lib, rd, sb);
rd.Read();
var backlinks = lib.Backlinks.ContainsKey(comm.Index) ? lib.Backlinks[comm.Index].OrderBy(x => x.Letter) : null;
if (backlinks != null) {
sb.Append(HTMLHelpers.CreateElement("div", "backlinks"));
var arrow = false;
foreach(var blk in backlinks) {
var let = lib.Metas.ContainsKey(blk.Letter) ? lib.Metas[blk.Letter] : null;
if (let != null) {
if (!arrow) {
sb.Append("&emsp;&rarr;&nbsp;");
sb.Append("HKB&nbsp;");
arrow = true;
}
sb.Append(HTMLHelpers.CreateElement("a", "backlink", "/Briefe/" + let.Autopsic + "#" + blk.Page + "-" + blk.Line));
@* sb.Append(" "); *@
var linkstring = "";
var ZHstring = "";
var pglnstring= "";
@* linkstring += "HKB&nbsp;"; *@
linkstring += let.Autopsic;
pglnstring += "&nbsp;(&#8239;" + blk.Page + "/" + blk.Line + "&#8239;)";
linkstring += pglnstring;
@* if (let.ZH != null) {
ZHstring += HTMLHelpers.CreateElement("span", "autopsic", "");
ZHstring += "ZH&nbsp;" + HTMLHelpers.ToRoman(Int32.Parse(let.ZH.Volume)) ;
ZHstring += HTMLHelpers.CreateEndElement("span");
linkstring += "&nbsp;" + ZHstring;
} *@
sb.Append(linkstring);
@* sb.Append("ZH" + "&nbsp;" +
HTMLHelpers.ToRoman(Int32.Parse(let.Volume)) +
"&nbsp;" +
blk.Page +
"/" +
blk.Line +
"&nbsp;(" +
let.Autopsic +
")"
); *@
if (blk != backlinks.Last())
sb.Append(",&emsp;");
sb.Append(HTMLHelpers.CreateEndElement("a"));
}
}
sb.Append(HTMLHelpers.CreateEndElement("div"));
}
sb.Append(HTMLHelpers.CreateEndElement("div"));
rd = readerservice.RequestStringReader(comm.Entry);
new StandardSubscriber(rd, sb, OTag_Funcs, STag_Funcs, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
new LinkBuilder(lib, rd, sb);
rd.Read();
return sb.ToString();
}
}
<div class="mainhead row"><!-- + sticky-top if sticky -->
<!--Sticky grey space on top of header -->
<div class="col">
<div class="widehead">
<div class="flexcol">
<div style="align-self: flex-end" class="printbutton">
<a class="" href="/pdf/Forschungsbibliographie_HamannBriefe.pdf">
PDF
</a>
</div>
<div class="flexrow" style="margin-bottom:-30px; align-items: last baseline;">
<div class="heading">
@ViewData["Title"]
</div>
<form>
<div class="form-inline hformbox">
<input type="search" class="form-control hform" asp-for="search" placeholder="Suchbegriff" />
<input type="submit" class="form-control hform" value="Suche in der Bibliographie" />
</div>
</form>
</div>
<div class="alphabet">
@if (String.IsNullOrWhiteSpace(Model.search))
{
<br/>
@foreach (var entry in availableletters)
{
<span><a class="invlink @setAct(entry.Key)" href="/Supplementa/Forschung/@entry.Key">@entry.Key</a> &emsp;</span>
}
<span class="caps">&emsp;<a class="@setAct("editionen")" href="/Supplementa/Forschung/editionen">Editionen</a></span>
}
else
{
<br/>
<span>Einträge, die &#x00BB;@Model.search&#x00AB; enthalten. <a href="/Supplementa/Forschung/A" class="hlink">&emsp;&emsp;&#x2190;&nbsp;Zurück</a></span>
@if (Model.maxSearch)
{
<br/><br/>
<span class="searchwarning">Zu viele Treffer. Die Anzeige wurde auf die ersten 150 Suchergebnisse beschränkt.</span>
}
}
</div>
</div>
</div>
</div>
</div>
<div class="row no-gutters">
<div class="col">
<div class="registerbox research">
<div class="text">
@if(comments == null || comments.Count() == 0)
{
@if(!String.IsNullOrWhiteSpace(Model.search))
{
<span class="searchwarning">Keine Einträge gefunden.</span>
}
}
@foreach (var comm in comments)
{
<div class="comment hangingindent">
@Html.Raw(handleComment(comm))
@if(comm.Kommentare != null)
{
@foreach (var subcomm in comm.Kommentare.OrderBy(x => x.Value.Order))
{
<div class="subsection hangingindent">
@Html.Raw(handleComment(subcomm.Value))
</div>
}
}
</div>
}
</div>
</div>
</div>
</div>
@section Scripts {
<script>
// The function actually applying the offset
function offsetAnchor() {
if (location.hash.length !== 0) {
window.scrollTo(window.scrollX, window.scrollY - 240);
}
}
// Captures click events of all <a> elements with href starting with #
$(document).on('click', 'a[href^="#"]', function(event) {
// Click events are captured before hashchanges. Timeout
// causes offsetAnchor to be called after the page jump.
window.setTimeout(function() {
offsetAnchor();
}, 0);
});
// Set the offset when entering page with hash present in the url
window.setTimeout(offsetAnchor, 0);
$( "#" + window.location.hash.substr(1) ).prepend("<div class=\"selected\">☛</div> ");
</script>
}

View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using HaDocument.Interfaces;
using HaDocument.Models;
using System.Collections.Concurrent;
using HaXMLReader.Interfaces;
namespace HaLive.Pages
{
public class ForschungModel : PageModel
{
private ILibrary _lib;
private IReaderService _readerService;
[BindProperty(SupportsGet = true)]
public string search { get; set; } = "";
public bool maxSearch = false;
[BindProperty(SupportsGet = true)]
public string id { get; set; }
public ForschungModel(ILibrary lib, IReaderService readerService) {
_lib = lib;
_readerService = readerService;
}
public IActionResult OnGet()
{
id = id.ToUpper();
if (!_lib.CommentsByCategoryLetter["forschung"].Contains(id) && id != "EDITIONEN") {
Response.StatusCode = 404;
return RedirectToPage("/Error");
}
return Page();
}
public IOrderedEnumerable<Comment> SelectComments() {
if (!String.IsNullOrWhiteSpace(search))
return Search(_lib.CommentsByCategory["forschung"]).OrderBy(x => x.Index);
if (id == "EDITIONEN")
return _lib.CommentsByCategory["editionen"].OrderBy(x => x.Index);
return _lib.CommentsByCategoryLetter["forschung"][id].OrderBy(x => x.Index);
}
private IEnumerable<Comment> Search(IEnumerable<Comment> all) {
var ret = new ConcurrentBag<Comment>();
var cnt = 0;
Parallel.ForEach (all, (comm, state) => {
if (cnt > 150) {
maxSearch = true;
state.Break();
}
if (SearchInComm(comm)) {
ret.Add(comm);
cnt++;
}
});
return ret;
}
private bool SearchInComm(Comment comment) {
var found = false;
var x = new RegisterSearch(comment, _readerService.RequestStringReader(comment.Entry), search);
found = x.Act();
if (!found) {
x = new RegisterSearch(comment, _readerService.RequestStringReader(comment.Lemma), search);
found = x.Act();
}
if (comment.Kommentare != null)
foreach (var sub in comment.Kommentare) {
if (!found) {
found = SearchInComm(sub.Value);
}
else break;
}
return found;
}
}
}

View File

@@ -0,0 +1,200 @@
@page "{id=A}"
@model HaLive.Pages.RegisterModel
@inject IReaderService readerservice;
@inject ILibrary lib;
@functions{
string setAct(string s) {
if (Model.id.ToString().ToLower() == s.ToLower())
return "is-active";
else
return "";
}
}
@{
// Acquire data
ViewData["Title"] = "Register";
var id = Model.id.ToUpper();
var comments = Model.SelectComments(lib);
var availableletters = lib.CommentsByCategoryLetter["neuzeit"].OrderBy(x => x.Key);
// Parsing Rules
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> OTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "titel", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("div", "titel")))
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> CTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "titel", (sb, tag) => sb.Append(HTMLHelpers.CreateEndElement("div")))
};
List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> STag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "line", (sb, tag) => sb.Append(HTMLHelpers.CreateElement("br")) )
};
List<(Func<Text, bool>, Action<StringBuilder, Text>)> Text_Funcs = new List<(Func<Text, bool>, Action<StringBuilder, Text>)>() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)> Whitespace_Funcs = new List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)>() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
string handleComment(Comment comm) {
StringBuilder sb = new StringBuilder();
var rd = readerservice.RequestStringReader(comm.Lemma);
new StandardSubscriber(rd, sb, OTag_Funcs, STag_Funcs, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
sb.Append(HTMLHelpers.CreateElement("div", "lemma", comm.Index));
new LinkBuilder(lib, rd, sb);
rd.Read();
var backlinks = lib.Backlinks.ContainsKey(comm.Index) ? lib.Backlinks[comm.Index].OrderBy(x => x.Letter) : null;
if (backlinks != null) {
sb.Append(HTMLHelpers.CreateElement("div", "backlinks"));
var arrow = false;
foreach(var blk in backlinks) {
var let = lib.Metas.ContainsKey(blk.Letter) ? lib.Metas[blk.Letter] : null;
if (let != null) {
if (!arrow) {
sb.Append("&emsp;&rarr;&nbsp;");
sb.Append("HKB&nbsp;");
arrow = true;
}
sb.Append(HTMLHelpers.CreateElement("a", "backlink", "/Briefe/" + let.Autopsic + "#" + blk.Page + "-" + blk.Line));
@* sb.Append(" "); *@
var linkstring = "";
var ZHstring = "";
if (let.ZH != null)
{
ZHstring += HTMLHelpers.ToRoman(Int32.Parse(let.ZH.Volume)) + "&nbsp;";
}
var pglnstring= "";
@* linkstring += "HKB&nbsp;"; *@
linkstring += let.Autopsic;
pglnstring += "&nbsp;(&#8239;" + ZHstring + blk.Page + "/" + blk.Line + "&#8239;)";
linkstring += pglnstring;
sb.Append(linkstring);
@* sb.Append("ZH" + "&nbsp;" +
HTMLHelpers.ToRoman(Int32.Parse(let.Volume)) +
"&nbsp;" +
blk.Page +
"/" +
blk.Line +
"&nbsp;(" +
let.Autopsic +
")"
); *@
if (blk != backlinks.Last())
sb.Append(",&emsp;");
sb.Append(HTMLHelpers.CreateEndElement("a"));
}
}
sb.Append(HTMLHelpers.CreateEndElement("div"));
}
sb.Append(HTMLHelpers.CreateEndElement("div"));
rd = readerservice.RequestStringReader(comm.Entry);
new StandardSubscriber(rd, sb, OTag_Funcs, STag_Funcs, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
new LinkBuilder(lib, rd, sb);
rd.Read();
return sb.ToString();
}
}
<div class="mainhead row no-gutters"><!-- + sticky-top if sticky -->
<!--Sticky grey space on top of header -->
<div class="col">
<div class="widehead">
<div class="flexcol">
<div style="align-self: flex-end" class="printbutton">
<a class="" href="/pdf/Register_HamannBriefe.pdf">
PDF
</a>
</div>
<div class="flexrow" style="margin-bottom:-30px; align-items: last baseline;">
<div class="heading">
Register
</div>
<form>
<div class="form-inline hformbox">
<input type="search" class="form-control hform" asp-for="search" placeholder="Suchbegriff" />
<input type="submit" class="form-control hform" value="Suche im Register" />
</div>
</form>
</div>
<div class="alphabet">
@if (String.IsNullOrWhiteSpace(Model.search))
{
<br/>
@foreach (var entry in availableletters)
{
<span><a class="invlink @setAct(entry.Key)" href="/Supplementa/Register/@entry.Key">@entry.Key</a> &emsp;</span>
}
}
else
{
<br/>
<span>Einträge, die &#x00BB;@Model.search&#x00AB; enthalten. <a href="/Supplementa/Register/A" class="hlink">&emsp;&emsp;&#x2190;&nbsp;Zurück</a></span>
@if (Model.maxSearch)
{
<br/><br/>
<span class="searchwarning">Zu viele Treffer. Die Anzeige wurde auf die ersten 150 Suchergebnisse beschränkt.</span>
}
}
</div>
</div>
</div>
</div>
</div>
<div class="row no-gutters">
<div class="col">
<div class="registerbox">
<div class="text">
@if(comments == null || comments.Count() == 0)
{
@if(!String.IsNullOrWhiteSpace(Model.search))
{
<span class="searchwarning">Keine Einträge gefunden.</span>
}
}
@foreach (var comm in comments)
{
<div class="comment">
@Html.Raw(handleComment(comm))
@if(comm.Kommentare != null)
{
@foreach (var subcomm in comm.Kommentare.OrderBy(x => x.Value.Order))
{
<div class="subsection">
@Html.Raw(handleComment(subcomm.Value))
</div>
}
}
</div>
}
</div>
</div>
</div>
</div>
@section Scripts {
<script>
// The function actually applying the offset
function offsetAnchor() {
if (location.hash.length !== 0) {
window.scrollTo(window.scrollX, window.scrollY - 280);
}
}
// Captures click events of all <a> elements with href starting with #
$(document).on('click', 'a[href^="#"]', function(event) {
// Click events are captured before hashchanges. Timeout
// causes offsetAnchor to be called after the page jump.
window.setTimeout(function() {
offsetAnchor();
}, 0);
});
// Set the offset when entering page with hash present in the url
window.setTimeout(offsetAnchor, 0);
$( "#" + window.location.hash.substr(1) ).prepend("<div class=\"selected\">☛</div> ");
</script>
}

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using HaDocument.Interfaces;
using HaDocument.Models;
using System.Collections.Concurrent;
using HaXMLReader.Interfaces;
namespace HaLive.Pages
{
public class RegisterModel : PageModel
{
private ILibrary _lib;
private IReaderService _readerService;
[BindProperty(SupportsGet = true)]
public string search { get; set; } = "";
public bool maxSearch = false;
[BindProperty(SupportsGet = true)]
public string id { get; set; }
public RegisterModel(ILibrary lib, IReaderService readerservice) {
_lib = lib;
_readerService = readerservice;
}
public IActionResult OnGet()
{
id = id.ToUpper();
if (!_lib.CommentsByCategoryLetter["neuzeit"].Contains(id)) {
Response.StatusCode = 404;
return RedirectToPage("/Error");
}
return Page();
}
public IOrderedEnumerable<Comment> SelectComments(ILibrary lib) {
if (!String.IsNullOrWhiteSpace(search))
return Search(lib.CommentsByCategoryLetter["neuzeit"].SelectMany(x => x)).OrderBy(x => x.Index);
return lib.CommentsByCategoryLetter["neuzeit"].Contains(id) ? lib.CommentsByCategoryLetter["neuzeit"][id].OrderBy(x => x.Index) : null;
}
private IEnumerable<Comment> Search(IEnumerable<Comment> all) {
var ret = new ConcurrentBag<Comment>();
var cnt = 0;
Parallel.ForEach (all, (comm, state) => {
if (cnt > 150) {
maxSearch = true;
state.Break();
}
if (SearchInComm(comm)) {
ret.Add(comm);
cnt++;
}
});
return ret;
}
private bool SearchInComm(Comment comment) {
var found = false;
var x = new RegisterSearch(comment, _readerService.RequestStringReader(comment.Entry), search);
found = x.Act();
if (!found) {
x = new RegisterSearch(comment, _readerService.RequestStringReader(comment.Lemma), search);
found = x.Act();
}
if (comment.Kommentare != null)
foreach (var sub in comment.Kommentare) {
if (!found) {
found = SearchInComm(sub.Value);
}
else break;
}
return found;
}
}
}

View File

@@ -0,0 +1,18 @@
<environment include="Development">
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</environment>
<environment exclude="Development">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js"
asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
asp-fallback-test="window.jQuery && window.jQuery.validator"
crossorigin="anonymous"
integrity="sha256-F6h55Qw6sweK+t7SiOJX+2bpSAa3b/fnlrVCJvmEj1A=">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"
asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
crossorigin="anonymous"
integrity="sha256-9GycpJnliUjJDVDqP0UEu/bsm9U+3dnQUH8+3W10vkY=">
</script>
</environment>

View File

@@ -0,0 +1,12 @@
@using HaLive
@using Models
@using System
@using System.Text
@using HaXMLReader.Interfaces
@using HaXMLReader;
@using HaXMLReader.EvArgs
@using HaDocument.Interfaces
@using HaDocument.Models
@namespace HaLive.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}

24
HaLive/Program.cs Normal file
View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace HaLive
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}

View File

@@ -0,0 +1,26 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:5000",
"sslPort": 44326
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"HaLive": {
"commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}

64
HaLive/Startup.cs Normal file
View File

@@ -0,0 +1,64 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using HaXMLReader;
using HaXMLReader.Interfaces;
using HaDocument.Interfaces;
using Microsoft.AspNetCore.Diagnostics;
namespace HaLive
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
//.AddRazorPagesOptions(options =>
//{
// options.RootDirectory = "/Pages/Main";
// options.Conventions.Folder
//})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton<ILibrary>(x => HaDocument.Document.Create(new Options()));
services.AddTransient<IReaderService, ReaderService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseStaticFiles();
app.UseMvc();
}
}
class Options : IHaDocumentOptions {
public string HamannXMLFilePath { get; set; } = @"Hamann.xml";
public string[] AvailableVolumes { get; set; } = { "1", "2", "3", "4", "5", "6", "7" };
public bool NormalizeWhitespace { get; set; } = true;
public (int, int) AvailableYearRange {get; set; } = (1751, 1788);
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

8
HaLive/appsettings.json Normal file
View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}

16
HaLive/probs.txt Normal file
View File

@@ -0,0 +1,16 @@
- Zahlen vor super sollten auf prop. Versalziffern, nicht mediäval (sieht blöd aus, vgl. Nr. 449, 188/8) S. kümmert sich drum klappt nicht, ist aber auch nicht schlimm
- Nr. 309: anchor ref klappt so mäßig, aber besser als erwartet. Da muss mindestens eine empty line zwischen HT und FN (ist im Quelltext, wird aber nicht ausgegeben) müssen in eigener Zeile anfangen -- keine breaks, wird programmiert klappt bisher nicht so
- liegengeblieben Probleme vom Hamann-Printer:
<edit ref="4125">1.)</edit> Z. 104852 verweist auf eine nicht existierende Editreason (4125) !
<edit ref="4126">2.)</edit> Z. 104853 verweist auf eine nicht existierende Editreason (4126) !
<edit ref="4127">3.)</edit> Z. 104854 verweist auf eine nicht existierende Editreason (4127) !
<edit ref="4128">4.</edit> Z. 104855 verweist auf eine nicht existierende Editreason (4128) !
(alles richtig eingetragen; er scheint Probleme zu haben, edits in fn zu bearbeiten)
<edit ref="5035"> […] Z. 191308 verweist auf eine nicht existierende Editreason (5035) !
(verstehe den Fehler nicht, ist alles richtig eingetragen, aber einerseits recht lang, andererseits in den traditions, mit Simon besprechen)
- added gut; hand refin klass. antiqua bodoni?

1197
HaLive/wwwroot/css/alt.css Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
:root {
--hamannGrau: #cbcaca;
--hamannDunkelGrau: darkgrey;
--hamannHighlight: red;
--commLineLength: 60;
--hamannWeiss: white;
}
.yearsidebar {
position: relative !important;
}
.yearsidebar .is-active {
color: var(--hamannHighlight) !important;
}
.del .del::before {
content: '<';
}
.del .del::after {
content: '>';
}

1889
HaLive/wwwroot/css/site.css Normal file

File diff suppressed because it is too large Load Diff

BIN
HaLive/wwwroot/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

110
HaLive/wwwroot/js/new.js Normal file
View File

@@ -0,0 +1,110 @@
/*
Funktion zum Einklappen der Kommentare der Seitenleiste, je nach verfügbarem Platz.
Benötigt jQuery.
(c) 2020 Theodor Springmann Stiftung Heidelberg
*/
$(function() {
/*
Jede Zeile in der Seitenleiste wird ausgewählt.
Voraussetzungen:
- Marginalspalte hat die Klasse "commentColumn"
- Kommentar in einer Zeile hat die Klasse "commBox"
- Eine Zeile ohne Kommentar ist ein <br class="emptyline"/>
*/
const sidebar = '.commentColumn';
const comment = '.commBox';
const emptyline = '.emptyline';
/*
Hilfsvariablen
- Funktion, um die Ergebnisse einer Query umzukehren.
- Variable, in der die Anzahl verfügbaren Platzes gespeichert wird.
- Größe eines REM
- Zeilenhöhe in commBox
- Padding von commBox
*/
jQuery.fn.reverse = [].reverse;
var emptylines_cnt = 0;
var rem = parseFloat(getComputedStyle(document.documentElement).fontSize);
var commBoxLineHeight = 1;
var commBoxPaddingHeight = 0.2;
/* Die Liste an Zeilen in der Seitenspalte wird rückwärts durchgegangen. */
$(sidebar + ' ' + comment + ',' + emptyline).reverse().each(function(elem) {
/* Fall 1: Es handelt sich um eine Leerzeile. Die Anzahl verfügbarer Leerzeilen wird erhöht. */
if ($(this).hasClass("emptyline")) {
emptylines_cnt++;
}
/* Fall 2: Es handelt sich um einen Kommentar, der evtl. gekürzt werden muss. */
else {
/* Von der Leerzeilenzahl bestimmte MÖGLICHE höhe des Divs berechnen
bei der von mir gewählten Zeilenhöhe wird ab 5 fre ien Textzeilen eine extra Kommentarzeile frei*/
if (emptylines_cnt >= 2) {
bonusLines = Math.floor(emptylines_cnt / 2);
emptylines_cnt = bonusLines + emptylines_cnt;
}
var possibleHeight = emptylines_cnt
* commBoxLineHeight
+ commBoxLineHeight
+ commBoxPaddingHeight;
possibleHeight = Math.floor(possibleHeight * 100) / 100;
var contentHeight = $(this).height();
/*contentHeight in rem umrechnen*/
contentHeight = contentHeight / rem;
contentHeight = Math.ceil(contentHeight * 100) / 100;
if (contentHeight > possibleHeight) {
$(this).toggleClass("short");
possibleHeight = String(possibleHeight) + "rem";
$(this).css("height", possibleHeight);
}
emptylines_cnt = 0;
}
});
$('button').on('click', function() {
if (this.parentNode.parentNode.classList.contains("short")) { /*testen ob parrentnode kurzkommentar ist. Wenn JA:*/
if (this.parentNode.parentNode.classList.contains("expanded")) { /*testen ob gerade expanded Wenn JA:*/
this.parentNode.parentNode.classList.remove("expanded"); /*entferne expandeded*/
} else { /*wenn parentnode nicht expanded ist*/
$("button").each(function(i) {
if (this.parentNode.parentNode.classList.contains("expanded")) {
this.parentNode.parentNode.classList.remove("expanded"); /*werden alle kommentare geschlossen*/
}
});
this.parentNode.parentNode.classList.add("expanded"); /*und der aktuelle kommentar expandiert*/
}
} else {
$("button").each(function(i) { /*wenn die parentnode nicht short ist*/
if (this.parentNode.parentNode.classList.contains("expanded")) {
this.parentNode.parentNode.classList.remove("expanded"); /*werden alle kommentare geschlossen*/
}
});
}
});
$('button').on('click', function() {
var ntht_button = 1;
$(this).prevAll().each(function(i) {
++ntht_button
});
var commBox = this.parentNode.parentNode;
var childrenOfCommbox = commBox.children
for (var i = 0; i < childrenOfCommbox.length; i++) {
if (i == ntht_button) {
childrenOfCommbox[i].classList.remove("invisible");
childrenOfCommbox[i].style.display = "block";
childrenOfCommbox[i].style.width = "100%";
} else if (i !== ntht_button && i !== 0) {
childrenOfCommbox[i].classList.add("invisible");
childrenOfCommbox[i].style.display = "none";
}
}
});
});

102
HaLive/wwwroot/js/site.js Normal file
View File

@@ -0,0 +1,102 @@
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
// for details on configuring this project to bundle and minify static web assets.
// Write your JavaScript code.
$(function() {
var commentColum = document.querySelectorAll("div.commentColumn");
var nodeList = Array.from(commentColum[0].querySelectorAll("div.commBox, br.emptyline"));
var nodeliLength = nodeList.length;
var brcounter = 0;
/* im Folgenden erstelle ich ein dictionary (map) mit der Zeilennummer des Kommentars als Schüssel und den Folgezeilen als Wert.
Da ich leider zu dumm bin, um es anders zu machen, geht die Liste von der höchsten Zeilennummer zu nidrigsten. Desswegen referenziere ich später die Kommentare durch ihre ID=Zeilennummer */
var commentLine_emptyLines = new Map();
for (var i = nodeliLength; i > 0; i--) {
if (nodeList[i - 1] == '[object HTMLBRElement]') {
brcounter++;
} else if (nodeList[i - 1] == '[object HTMLDivElement]') {
commentLine_emptyLines.set(i, brcounter);
brcounter = 0;
}
}
/*dann stelle ich die höhe jedes Div.commBox so ein, dass die Höhe des Inhalts realisiert wird, wenn genug Platz ist.
Wenn zu wenig Platz ist, wird das Div so groß wie möglich gemacht.*/
$(".commBox").each(function(i) {
/*Zahl der leeren Folgezeilen über Zeilenzahl des Kommentars bekommen*/
var emptyLines = commentLine_emptyLines.get(parseInt(this.id));
/* Von der Leerzeilenzahl bestimmte MÖGLICHE höhe des Divs berechnen
bei der von mir gewählten Zeilenhöhe wird ab 5 (nach jetztiger einstellung ab 6) Freien Textzeilen eine extra Kommentarzeile frei*/
if (emptyLines >= 4) {
bonusLines = Math.floor(emptyLines / 4);
emptyLines = bonusLines + emptyLines;
}
var possibleHeight = emptyLines * 1.1 + 1.1 + 0.2;
possibleHeight = Math.floor(possibleHeight * 100) / 100;
console.log(possibleHeight);
var contentHeight = $(this).height();
/*contentHeight in rem umrechnen*/
contentHeight = contentHeight / parseFloat(getComputedStyle(document.documentElement).fontSize);
contentHeight = Math.ceil(contentHeight * 100) / 100;
console.log(contentHeight);
if (contentHeight < possibleHeight) {
possibleHeight = Math.ceil((contentHeight + 0.2) * 100) / 100;
} else if (contentHeight > possibleHeight) {
$(this).toggleClass("short");
} else {
possibleHeight = contentHeight;
}
possibleHeight = String(possibleHeight) + "rem";
$(this).css("height", possibleHeight);
});
$("button").each(function(i) { /*wenn die parentnode nicht short ist*/
if (this.parentNode.parentNode.classList.contains("short")) {} else {
this.firstChild.data = "▷";
}
});
$('button').on('click', function() {
if (this.parentNode.parentNode.classList.contains("short")) { /*testen ob parrentnode kurzkommentar ist. Wenn JA:*/
if (this.parentNode.parentNode.classList.contains("expanded")) { /*testen ob gerade expanded Wenn JA:*/
this.parentNode.parentNode.classList.remove("expanded"); /*entferne expandeded*/
this.firstChild.data = "▶ ";
} else { /*wenn parentnode nicht expanded ist*/
$("button").each(function(i) {
if (this.parentNode.parentNode.classList.contains("expanded")) {
this.parentNode.parentNode.classList.remove("expanded"); /*werden alle kommentare geschlossen*/
this.firstChild.data = "▶ ";
}
});
this.parentNode.parentNode.classList.add("expanded"); /*und der aktuelle kommentar expandiert*/
this.firstChild.data = "▲";
}
} else {
$("button").each(function(i) { /*wenn die parentnode nicht short ist*/
if (this.parentNode.parentNode.classList.contains("expanded")) {
this.parentNode.parentNode.classList.remove("expanded"); /*werden alle kommentare geschlossen*/
this.firstChild.data = "▶ ";
}
});
}
});
$('button').on('click', function() {
var ntht_button = 1;
$(this).prevAll().each(function(i) {
++ntht_button
});
var commBox = this.parentNode.parentNode;
var childrenOfCommbox = commBox.children
for (var i = 0; i < childrenOfCommbox.length; i++) {
if (i == ntht_button) {
childrenOfCommbox[i].classList.remove("invisible");
childrenOfCommbox[i].style.display = "block";
} else if (i !== ntht_button && i !== 0) {
childrenOfCommbox[i].classList.add("invisible");
childrenOfCommbox[i].style.display = "none";
}
}
});
});

View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2011-2018 Twitter, Inc.
Copyright (c) 2011-2018 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,331 @@
/*!
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
select {
word-wrap: normal;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,36 @@
Copyright JS Foundation and other contributors, https://js.foundation/
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at https://github.com/jquery/jquery
The following license applies to all parts of this software except as
documented below:
====
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
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 AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
====
All files located in the node_modules and external directories are
externally maintained libraries used by this software which have their
own licenses; we recommend you read them, as their terms may differ from
the terms above.

10364
HaLive/wwwroot/lib/jquery/dist/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B