Ported libs fo net V6

This commit is contained in:
schnulller
2022-05-17 01:21:10 +02:00
parent cb23a75761
commit 2ffd46cd62
79 changed files with 225299 additions and 124 deletions

View File

@@ -0,0 +1,15 @@
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using HaDocument.Models;
namespace HaDocument.Comparers {
public class CommentComparer : IComparer<Comment> {
public int Compare(Comment first, Comment second) {
if (first.Order != second.Order)
return first.Order.CompareTo(second.Order);
else
return first.Index.CompareTo(second.Index);
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HaDocument.Models;
namespace HaDocument.Comparers
{
public class DefaultComparer : IComparer<Meta>
{
public int Compare(Meta first, Meta second)
{
if (first.Sort != second.Sort)
return System.DateTime.Compare(first.Sort, second.Sort);
else if (first.Order != second.Order)
return first.Order.CompareTo(second.Order);
else
return String.Compare(first.Index, second.Index);
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using HaDocument.Models;
using System.Collections.Generic;
namespace HaDocument.Comparers {
public class PersonComparer : IComparer<Person> {
public int Compare(Person first, Person second) {
var cmp = String.Compare(first.Surname, second.Surname);
if (cmp == 0) cmp = String.Compare(first.Name, second.Name);
return cmp;
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HaDocument.Models;
namespace HaDocument.Comparers
{
public class ZHComparer : IComparer<Meta>
{
public int Compare(Meta first, Meta second)
{
var firstNumber = 0;
var secondNumber = 0;
Int32.TryParse(first.Index, out firstNumber);
Int32.TryParse(second.Index, out secondNumber);
return firstNumber.CompareTo(secondNumber);
//var firstIndex = from c in first.Meta.Autopsic
// where char.IsDigit(c)
// select c;
//var secondIndex = from c in second.Meta.Autopsic
// where char.IsDigit(c)
// select c;
//int firstNumber = 0;
//int secondNumber = 0;
//Int32.TryParse(String.Join("", firstIndex), out firstNumber);
//Int32.TryParse(String.Join("", secondIndex), out secondNumber);
//if (firstNumber.CompareTo(secondNumber) != 0)
// return firstNumber.CompareTo(secondNumber);
//var firstChar = from c in first.Meta.Autopsic
// where char.IsMeta(c)
// select c;
//var secondChar = from c in first.Meta.Autopsic
// where char.IsMeta(c)
// select c;
//return String.Compare(String.Join("", firstChar), String.Join("", secondChar));
}
}
}

55
HaDocumentV6/Document.cs Normal file
View File

@@ -0,0 +1,55 @@
using HaDocument.Models;
using HaDocument.Interfaces;
using HaDocument.Logic;
using HaDocument.Reactors;
using HaXMLReader.Interfaces;
using HaXMLReader;
namespace HaDocument
{
/// <summary>
/// Provides basic Access to the Letter.
/// Initializes the parsing.
/// Needs an Option Object as specified in IHaDocumentOptions.
/// In case, the options change, the Object must be disposed and recreated.
/// </summary>
public static class Document
{
private static IHaDocumentOptions _settings;
private static IReader _reader = null;
private static IntermediateLibrary _lib = new IntermediateLibrary();
private static ILibrary _library;
public static ILibrary Create(IHaDocumentOptions Settings) {
SettingsValidator.Validate(Settings);
_settings = Settings;
_createReader();
_createReactors();
_reader.Read();
_library = _createLibrary();
return GetLibrary();
}
private static void _createReactors() {
new EditreasonReactor(_reader, _lib, _settings.NormalizeWhitespace);
new HandDefsReactor(_reader, _lib);
new LetterReactor(_reader, _lib, _settings.NormalizeWhitespace);
new LocationDefsReactor(_reader, _lib);
new MarginalReactor(_reader, _lib, _settings.NormalizeWhitespace);
new MetaReactor(_reader, _lib, _settings.AvailableVolumes, _settings.AvailableYearRange);
new PersonDefsReactor(_reader, _lib);
new TraditionsReactor(_reader, _lib, _settings.NormalizeWhitespace);
new CommentReactor(_reader, _lib, _settings.NormalizeWhitespace);
}
private static void _createReader() {
_reader = new FileReader(_settings.HamannXMLFilePath);
}
private static ILibrary _createLibrary()
=> _lib.GetLibrary(_settings);
public static ILibrary GetLibrary()
=> _library;
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace HaDocument.Exceptions {
public class ObjectBotchedException : Exception {
public ObjectBotchedException() { }
public ObjectBotchedException(string msg) : base (msg) { }
public ObjectBotchedException(string msg, Exception inner) : base (msg, inner) { }
}
}

View File

@@ -0,0 +1,10 @@
using System;
namespace HaDocument.Exceptions {
public class ObjectNotFoundException : Exception {
public ObjectNotFoundException() { }
public ObjectNotFoundException(string msg) : base (msg) { }
public ObjectNotFoundException(string msg, Exception inner) : base (msg, inner) { }
}
}

View File

@@ -0,0 +1,10 @@
using System;
namespace HaDocument.Exceptions {
public class SettingsInvalidException : Exception {
public SettingsInvalidException() { }
public SettingsInvalidException(string msg) : base (msg) { }
public SettingsInvalidException(string msg, Exception inner) : base (msg, inner) { }
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\HaXMLReaderV6\HaXMLReaderV6.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,7 @@
using System;
namespace HaDocument.Interfaces {
public interface IDocument {
}
}

View File

@@ -0,0 +1,10 @@
using System;
namespace HaDocument.Interfaces {
public interface IHaDocumentOptions {
string HamannXMLFilePath { get; set; }
string[] AvailableVolumes { get; set; }
bool NormalizeWhitespace { get; set; }
(int, int) AvailableYearRange { get; set; }
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Immutable;
using HaDocument.Models;
using System.Linq;
namespace HaDocument.Interfaces {
public interface ILibrary {
IHaDocumentOptions Options { get; }
ImmutableDictionary<string, Tradition> Traditions { get; }
ImmutableDictionary<string, Person> Persons { get; }
ImmutableDictionary<string, Meta> Metas { get; }
ImmutableDictionary<string, Marginal> Marginals { get; }
ImmutableDictionary<string, Location> Locations { get; }
ImmutableDictionary<string, Letter> Letters { get; }
ImmutableDictionary<string, Person> HandPersons { get; }
ImmutableDictionary<string, Editreason> Editreasons { get; }
ImmutableDictionary<string, Comment> Comments { get; }
ImmutableDictionary<string, ImmutableList<Backlink>> Backlinks { get; }
ImmutableDictionary<string, ImmutableList<Hand>> Hands { get; }
ImmutableDictionary<string, ImmutableDictionary<string, ImmutableDictionary<string, string>>> Structure { get; }
ImmutableDictionary<string, Lookup<string, Comment>> CommentsByCategoryLetter { get; }
Lookup<string, Comment> CommentsByCategory { get; }
Lookup<string, Marginal> MarginalsByLetter { get; }
Lookup<string, Editreason> EditreasonsByLetter { get; }
ImmutableSortedSet<Meta> MetasByDate { get; }
ILookup<string, Meta> MetasByYear { get; }
ImmutableDictionary<string, Comment> SubCommentsByID { get; }
}
}

View File

@@ -0,0 +1,7 @@
using System;
namespace HaDocument {
interface ITemporaryLibrary {
}
}

View File

@@ -0,0 +1,16 @@
using HaXMLReader.EvArgs;
using System.Linq;
namespace HaDocument {
static class Helpers {
internal static string GetElementString(Tag tag) {
var res = "<" + (tag.EndTag ? "/" : "") + tag.Name.ToLower();
if (!tag.EndTag && tag.Values != null && tag.Values.Any()) {
foreach (var kvp in tag.Values) {
res += " " + kvp.Key.ToLower() + "=\"" + kvp.Value.ToLower() + "\"";
}
}
return res + (tag.IsEmpty ? "/" : "") + ">";
}
}
}

View File

@@ -0,0 +1,10 @@
using System;
using HaDocument.Interfaces;
namespace HaDocument.Logic {
static class SettingsValidator {
internal static void Validate(IHaDocumentOptions settings) {
}
}
}

View File

@@ -0,0 +1,24 @@
namespace HaDocument.Models {
public class Backlink {
public string Index { get; } = "";
public string Letter { get; } = "";
public string Page { get; } = "";
public string Line { get; } = "";
public string MarginalIndex { get; } = "";
public Backlink(
string index,
string letter,
string page,
string line,
string marginalindex
) {
Index = index;
Letter = letter;
Page = page;
Line = line;
MarginalIndex = marginalindex;
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
namespace HaDocument.Models {
public class Comment{
public string Entry { get; } = "";
public string Index { get; } = "";
public string Type { get; } = "";
public string Lemma { get; } = "";
public string Parent { get; } = "";
public int Order { get; } = -1;
public ImmutableSortedDictionary<string, Comment> Kommentare { get; }
public Comment(
string entry,
string index,
string type,
string lemma,
int order,
SortedDictionary<string, Comment> subComments,
string parent=""
) {
Entry = entry;
Index = index;
Type = type;
Lemma = lemma;
Order = order;
Parent = parent;
if (subComments != null)
Kommentare = ImmutableSortedDictionary.ToImmutableSortedDictionary(subComments);
else
Kommentare = null;
}
}
}

View File

@@ -0,0 +1,32 @@
namespace HaDocument.Models {
public class Editreason {
public string Index { get; } = "";
public string Element { get; } = "";
public string Letter { get; } = "";
public string StartPage { get; } = "";
public string StartLine { get; } = "";
public string EndPage { get; } = "";
public string EndLine { get; } = "";
public string Reference { get; } = "";
public Editreason(
string index,
string element,
string letter = "",
string startpage = "",
string startline = "",
string endpage = "",
string endline = "",
string reference = ""
) {
Index = index;
Element = element;
Letter = letter;
StartPage = startpage;
StartLine = startline;
EndPage = endpage;
EndLine = endline;
Reference = reference;
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using HaXMLReader.EvArgs;
using System.Collections.Generic;
namespace HaDocument.Models {
public abstract class HaModel {
protected static List<(Func<Tag, bool>, Action<Tag>)> FieldActions = null;
internal static void AddAction(Func<Tag, bool> If, Action<Tag> Then) {
if (If == null || Then == null) throw new ArgumentNullException();
if (FieldActions == null) FieldActions = new List<(Func<Tag, bool>, Action<Tag>)>();
FieldActions.Add((If, Then));
}
}
}

View File

@@ -0,0 +1,26 @@
namespace HaDocument.Models {
public class Hand : HaModel {
public string Letter { get; } = "";
public string Person { get; } = "";
public string StartPage { get; } = "";
public string StartLine { get; } = "";
public string EndPage { get; } = "";
public string EndLine {get; } = "";
public Hand(
string letter,
string person,
string startpage,
string startline,
string endpage,
string endline
) {
Letter = letter;
Person = person;
StartPage = startpage;
StartLine = startline;
EndPage = endpage;
EndLine = endline;
}
}
}

View File

@@ -0,0 +1,70 @@
using System.Collections.Generic;
using HaDocument.Interfaces;
namespace HaDocument.Models
{
public class IntermediateLibrary
{
public Dictionary<string, Tradition> Traditions;
public Dictionary<string, Person> Persons;
public Dictionary<string, Meta> Metas;
public Dictionary<string, Marginal> Marginals;
public Dictionary<string, Location> Locations;
public Dictionary<string, Letter> Letters;
public Dictionary<string, Person> HandPersons;
public Dictionary<string, Editreason> Editreasons;
public Dictionary<string, Comment> Comments;
public Dictionary<string, List<Backlink>> Backlinks;
public Dictionary<string, List<Hand>> Hands;
// Helper Library for precalculationg the Structure of the Document:
public Dictionary<string, Dictionary<string, HashSet<string>>> LetterPageLines;
public Library GetLibrary(IHaDocumentOptions options)
{
var Structure = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
foreach (var letter in LetterPageLines)
{
if (Metas.ContainsKey(letter.Key) &&
Metas[letter.Key].ZH != null)
{
if (!Structure.ContainsKey(Metas[letter.Key].ZH.Volume))
{
Structure.Add(Metas[letter.Key].ZH.Volume, new Dictionary<string, Dictionary<string, string>>());
}
foreach (var page in letter.Value)
{
if (!Structure[Metas[letter.Key].ZH.Volume].ContainsKey(page.Key))
{
Structure[Metas[letter.Key].ZH.Volume].Add(page.Key, new Dictionary<string, string>());
}
foreach (var line in page.Value)
{
if (!Structure[Metas[letter.Key].ZH.Volume][page.Key].ContainsKey(line))
{
Structure[Metas[letter.Key].ZH.Volume][page.Key].Add(line, letter.Key);
}
}
}
}
}
return new Library(
Traditions,
Persons,
Metas,
Marginals,
Locations,
Letters,
HandPersons,
Editreasons,
Comments,
Backlinks,
Hands,
Structure,
options
);
}
}
}

View File

@@ -0,0 +1,14 @@
namespace HaDocument.Models {
public class Letter : HaModel {
public string Index { get; } = "";
public string Element { get; } = "";
public Letter(
string index,
string element
) {
Index = index;
Element = element;
}
}
}

View File

@@ -0,0 +1,150 @@
using System;
using HaDocument.Interfaces;
using System.Collections.Immutable;
using System.Collections.Generic;
using HaDocument.Models;
using HaDocument.Comparers;
using System.Linq;
namespace HaDocument.Models
{
public class Library : ILibrary
{
public IHaDocumentOptions Options { get; }
public ImmutableDictionary<string, Tradition> Traditions { get; }
public ImmutableDictionary<string, Person> Persons { get; }
public ImmutableDictionary<string, Meta> Metas { get; }
public ImmutableDictionary<string, Marginal> Marginals { get; }
public ImmutableDictionary<string, Location> Locations { get; }
public ImmutableDictionary<string, Letter> Letters { get; }
public ImmutableDictionary<string, Person> HandPersons { get; }
public ImmutableDictionary<string, Editreason> Editreasons { get; }
public ImmutableDictionary<string, Comment> Comments { get; }
public ImmutableDictionary<string, ImmutableList<Backlink>> Backlinks { get; }
public ImmutableDictionary<string, ImmutableList<Hand>> Hands { get; }
// Structure for lookups from ZH:
public ImmutableDictionary<string, ImmutableDictionary<string, ImmutableDictionary<string, string>>> Structure { get; }
// Lookups:
// Auswählen von Kommentaren nach (1) Kategorie, (2) Anfangsbuchstaben vom Lemma.
// So: _ = CommentsByCategoryLetter['neuzeit']['A']
public ImmutableDictionary<string, Lookup<string, Comment>> CommentsByCategoryLetter { get; }
public Lookup<string, Comment> CommentsByCategory { get; }
// Auswählen von Subkommentaren nach ID
public ImmutableDictionary<string, Comment> SubCommentsByID { get; }
// Auswählen von Marginalien nach Briefen
public Lookup<string, Marginal> MarginalsByLetter { get; }
// Ausw?hlen von Edits nach Briefen
public Lookup<string, Editreason> EditreasonsByLetter { get; }
// Auswählen von Briefen nach autoptischer Numemr und in zeitlich sortierter Reihenfolge.
public ImmutableSortedSet<Meta> MetasByDate { get; }
// Auswählen von Briefen nach dem Jahr, sortiert nach Datum
public ILookup<string, Meta> MetasByYear { get; }
public Library(
Dictionary<string, Tradition> traditions,
Dictionary<string, Person> persons,
Dictionary<string, Meta> meta,
Dictionary<string, Marginal> marginals,
Dictionary<string, Location> locations,
Dictionary<string, Letter> letters,
Dictionary<string, Person> handPersons,
Dictionary<string, Editreason> editReasons,
Dictionary<string, Comment> comments,
Dictionary<string, List<Backlink>> backlinks,
Dictionary<string, List<Hand>> hands,
Dictionary<string, Dictionary<string, Dictionary<string, string>>> Structure,
IHaDocumentOptions options
)
{
// Dictionaries
Traditions = ImmutableDictionary.ToImmutableDictionary(traditions);
Persons = ImmutableDictionary.ToImmutableDictionary(persons);
Metas = ImmutableDictionary.ToImmutableDictionary(meta);
Marginals = ImmutableDictionary.ToImmutableDictionary(marginals);
Locations = ImmutableDictionary.ToImmutableDictionary(locations);
Letters = ImmutableDictionary.ToImmutableDictionary(letters);
HandPersons = ImmutableDictionary.ToImmutableDictionary(handPersons);
Editreasons = ImmutableDictionary.ToImmutableDictionary(editReasons);
Comments = ImmutableDictionary.ToImmutableDictionary(comments);
var backbuilder = ImmutableDictionary.CreateBuilder<string, ImmutableList<Backlink>>();
foreach (var entry in backlinks)
backbuilder.Add(entry.Key, ImmutableList.ToImmutableList(entry.Value));
Backlinks = backbuilder.ToImmutableDictionary();
var handbuilder = ImmutableDictionary.CreateBuilder<string, ImmutableList<Hand>>();
foreach (var entry in hands)
handbuilder.Add(entry.Key, ImmutableList.ToImmutableList(entry.Value));
Hands = handbuilder.ToImmutableDictionary();
// Lookups
CommentsByCategory = (Lookup<string, Comment>)Comments.Values.ToLookup(x => x.Type);
var CommentsByLetter_builder = ImmutableDictionary.CreateBuilder<string, Lookup<string, Comment>>();
foreach (var ts in CommentsByCategory)
{
CommentsByLetter_builder.Add(ts.Key, (Lookup<string, Comment>)ts.ToLookup(x => x.Index.Substring(0, 1).ToUpper()));
}
CommentsByCategoryLetter = CommentsByLetter_builder.ToImmutableDictionary();
MarginalsByLetter = (Lookup<string, Marginal>)Marginals.Values.ToLookup(x => x.Letter);
EditreasonsByLetter = (Lookup<string, Editreason>)Editreasons.Values.ToLookup(x => x.Letter);
MetasByDate = Metas.Values.ToImmutableSortedSet<Meta>(new DefaultComparer());
MetasByYear = Metas.Values.ToLookup(x => x.Sort.Year.ToString());
var tempbuilder = ImmutableDictionary.CreateBuilder<string, Comment>();
foreach (var comm in Comments)
if (comm.Value.Kommentare != null)
foreach (var subcomm in comm.Value.Kommentare)
if (!tempbuilder.ContainsKey(subcomm.Key))
tempbuilder.Add(subcomm.Key, subcomm.Value);
SubCommentsByID = tempbuilder.ToImmutableDictionary();
var tempstructurebuilder = ImmutableDictionary.CreateBuilder<string, ImmutableDictionary<string, ImmutableDictionary<string, string>>>();
foreach (var volume in Structure)
{
if (volume.Value != null)
{
var tempvolbuilder = ImmutableDictionary.CreateBuilder<string, ImmutableDictionary<string, string>>();
foreach (var page in volume.Value)
{
if (page.Value != null)
{
tempvolbuilder.Add(page.Key, page.Value.ToImmutableDictionary());
}
}
if (tempvolbuilder.Any())
{
tempstructurebuilder.Add(volume.Key, tempvolbuilder.ToImmutableDictionary());
}
}
}
this.Structure = tempstructurebuilder.ToImmutableDictionary();
Options = options;
}
// public List<Meta> MetasByDate() {
// var ret = Metas.OrderBy(x => x.Value, new DefaultComparer()).ToLookup(x => x.Value.Autopsic, x => x.Value);
// ret.Sort(new DefaultComparer());
// return ret;
// }
public ImmutableList<Meta> MetasByZH()
{
return Metas.Values.ToImmutableList().Sort(new Comparers.ZHComparer());
}
public List<Person> PersonByAlphabet()
{
var ret = Persons.Values.ToList();
ret.Sort(new PersonComparer());
return ret;
}
}
}

View File

@@ -0,0 +1,14 @@
namespace HaDocument.Models {
public class Location {
public string Index { get; } = "";
public string Name { get; } = "";
public Location(
string index,
string name
) {
Index = index;
Name = name;
}
}
}

View File

@@ -0,0 +1,23 @@
namespace HaDocument.Models {
public class Marginal {
public string Index { get; } = "";
public string Letter { get; } = "";
public string Page { get; } = "";
public string Line { get; } = "";
public string Element { get; } = "";
public Marginal(
string index,
string letter,
string page,
string line,
string elemnt
) {
Index = index;
Letter = letter;
Page = page;
Line = line;
Element = elemnt;
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using HaXMLReader.EvArgs;
namespace HaDocument.Models {
public class Meta {
public string Index { get; } = "";
public string Autopsic { get; } = "";
public string Date { get; } = "";
public DateTime Sort { get; } = new DateTime(1700, 1, 1);
public int Order { get; } = -1;
public string Location { get; } = "";
public List<string> Senders { get; } = null;
public List<string> Receivers { get; } = null;
public OptionalBool hasOriginal { get; } = OptionalBool.None;
public OptionalBool isProofread { get; } = OptionalBool.None;
public OptionalBool isDraft { get; } = OptionalBool.None;
public ZHInfo ZH { get; } = null;
public Meta(
string index,
string autopsic,
string date,
DateTime sort,
int order,
OptionalBool hasOriginal,
OptionalBool isProofread,
OptionalBool isDraft,
string location,
List<string> senders,
List<string> receivers,
ZHInfo ZH
) {
Index = index;
Autopsic = autopsic;
Date = date;
Sort = sort;
Order = order;
Location = location;
Senders = senders;
Receivers = receivers;
this.hasOriginal = hasOriginal;
this.isProofread = isProofread;
this.isDraft = isDraft;
this.ZH = ZH;
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace HaDocument.Models
{
public enum OptionalBool
{
True,
False,
None
}
}

View File

@@ -0,0 +1,20 @@
namespace HaDocument.Models {
public class Person {
public string Index { get; } = "";
public string Name { get; } = "";
public string Prename { get; } = "";
public string Surname { get; } = "";
public Person(
string index,
string name,
string prename,
string surname
) {
Index = index;
Name = name;
Prename = prename;
Surname = surname;
}
}
}

View File

@@ -0,0 +1,14 @@
namespace HaDocument.Models {
public class Tradition {
public string Index { get; } = "";
public string Element { get; } = "";
public Tradition(
string index,
string element
) {
Index = index;
Element = element;
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace HaDocument.Models
{
public class ZHInfo
{
public bool alternativeLineNumbering { get; } = false;
public bool dateChanged { get; } = false;
public string Volume { get; } = "";
public string Page { get; } = "";
public ZHInfo(bool alternativeLineNumbering, bool dateChanged, string Volume, string Page) {
this.alternativeLineNumbering = alternativeLineNumbering;
this.dateChanged = dateChanged;
this.Volume = Volume;
this.Page = Page;
}
}
}

View File

@@ -0,0 +1,178 @@
using HaXMLReader.Interfaces;
using HaXMLReader.EvArgs;
using HaDocument.Models;
using System.Collections.Generic;
using System;
using HaDocument.Comparers;
namespace HaDocument.Reactors {
class CommentReactor : Reactor {
Dictionary<string, Comment> CreatedInstances;
private bool _normalizeWhitespace = false;
// State
private string Type = "";
private string Index = "";
private string Lemma = "";
private string Entry = "";
private int Order = -1;
private SortedDictionary<string, Comment> Subcomments;
private bool subsection = false;
private string subsectionIndex = "";
private string subsectionLemma = "";
private string subsectionEntry = "";
private int subsectionOrder = -1;
internal CommentReactor(IReader reader, IntermediateLibrary lib, bool normalizeWhitespace) : base(reader, lib) {
_normalizeWhitespace = normalizeWhitespace;
_lib.Comments = _lib.Comments ?? new Dictionary<string, Comment>();
CreatedInstances = _lib.Comments;
reader.OpenTag += Listen;
}
protected override void Listen(object _, Tag tag) {
if (
!tag.IsEmpty &&
!tag.EndTag &&
tag.Name == "kommcat" &&
!string.IsNullOrWhiteSpace(tag["value"])
) {
Type = tag["value"];
Activate(_reader, tag);
}
else if (
tag.EndTag &&
tag.Name == "kommcat"
) {
ResetType();
Deactivate();
}
}
protected override void Activate(IReader _, Tag tag) {
_reader.Tag += OnTag;
}
private void OnTag(object _, Tag tag) {
if (
!tag.IsEmpty &&
!tag.EndTag &&
tag.Name == "kommentar" &&
!string.IsNullOrWhiteSpace(tag["id"])
) {
Index = tag["id"];
Order = String.IsNullOrWhiteSpace(tag["sort"]) ? 0 : Int32.Parse(tag["sort"]);
}
else if (
tag.EndTag &&
tag.Name == "kommentar"
) {
AddComment();
}
else if (
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "lemma"
) {
_ = new ElementStringBinder(_reader, tag, AddLemma, _normalizeWhitespace);
}
else if (
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "eintrag"
) {
_ = new ElementStringBinder(_reader, tag, AddEntry, _normalizeWhitespace);
}
else if (
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "subsection"
) {
if (!String.IsNullOrWhiteSpace(tag["id"])) subsectionIndex = tag["id"];
if (!String.IsNullOrWhiteSpace(tag["sort"])) subsectionOrder = Int32.Parse(tag["sort"]);
if (Subcomments ==null) Subcomments = new SortedDictionary<string, Comment>();
subsection = true;
}
else if (
tag.EndTag &&
tag.Name == "subsection"
) {
subsection = false;
AddSubsection();
}
}
private void Deactivate() {
_reader.Tag -= OnTag;
}
private void AddLemma(string str) {
if (String.IsNullOrEmpty(str)) return;
if (subsection) subsectionLemma = str;
else Lemma = str;
}
private void AddEntry(string str) {
if (String.IsNullOrWhiteSpace(str)) str = "";
if (subsection) subsectionEntry = str;
else Entry = str;
}
private void AddSubsection() {
if (String.IsNullOrWhiteSpace(subsectionIndex)) return;
if (String.IsNullOrWhiteSpace(subsectionLemma)) return;
if (!Subcomments.ContainsKey(subsectionIndex))
{
Subcomments.Add(subsectionIndex, new Comment(
subsectionEntry,
subsectionIndex,
Type,
subsectionLemma,
subsectionOrder,
null,
Index
));
}
ResetSubsection();
}
private void AddComment() {
if (String.IsNullOrWhiteSpace(Index)) return;
if (String.IsNullOrWhiteSpace(Lemma)) return;
if (CreatedInstances.ContainsKey(Index)) return;
CreatedInstances.Add(Index, new Comment(
Entry,
Index,
Type,
Lemma,
Order,
Subcomments
));
Reset();
}
protected override void Reset() {
Index = "";
Lemma = "";
Entry = "";
Order = -1;
Subcomments = null;
ResetSubsection();
}
private void ResetSubsection() {
subsection = false;
subsectionEntry = "";
subsectionIndex = "";
subsectionLemma = "";
subsectionOrder = -1;
}
private void ResetType() {
Type = "";
}
}
}

View File

@@ -0,0 +1,154 @@
using HaDocument.Models;
using System.Collections.Generic;
using HaXMLReader.EvArgs;
using HaXMLReader.Interfaces;
using System;
namespace HaDocument.Reactors {
class EditreasonReactor : Reactor {
internal Dictionary<string, Editreason> CreatedInstances;
private Dictionary<string, string[]> _intermediateReasons = new Dictionary<string, string[]>();
private bool _normalizeWhitespace = false;
// State
private string Index = "";
private string letter = "";
private string page = "";
private string line = "";
private Stack<string> index;
private ElementStringBinder _element = null;
internal EditreasonReactor(IReader reader, IntermediateLibrary lib, bool normalizeWhitespace) : base (reader, lib) {
CreatedInstances = lib.Editreasons;
index = new Stack<string>();
_normalizeWhitespace = normalizeWhitespace;
lib.Editreasons = new Dictionary<string, Editreason>();
CreatedInstances = lib.Editreasons;
reader.Tag += Listen;
reader.ReadingStop += Scaffold;
}
protected void Scaffold(object _, EventArgs __) {
foreach (var entry in _intermediateReasons) {
if (
!String.IsNullOrWhiteSpace(entry.Value[0]) &&
!String.IsNullOrWhiteSpace(entry.Value[1]) &&
!String.IsNullOrWhiteSpace(entry.Value[2]) &&
!String.IsNullOrWhiteSpace(entry.Value[3])
) {
CreatedInstances.Add(
entry.Key,
new Editreason(
entry.Key,
entry.Value[0],
entry.Value[1],
entry.Value[2],
entry.Value[3],
entry.Value[5],
entry.Value[6],
entry.Value[4]
)
);
}
}
}
protected override void Listen(object sender, Tag tag) {
if (
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "editreason" &&
!String.IsNullOrWhiteSpace(tag["index"])
) {
Activate(_reader, tag);
}
else if (
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "letterText"
) {
letter = tag["index"];
}
else if (
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "letterTradition"
) {
letter = tag["ref"];
}
else if (
!tag.EndTag &&
tag.IsEmpty &&
tag.Name == "page"
) {
page = tag["index"];
}
else if (
!tag.EndTag &&
tag.IsEmpty &&
tag.Name == "line"
) {
line = tag["index"];
}
else if (
!tag.EndTag &&
tag.Name == "edit" &&
!String.IsNullOrWhiteSpace(tag["ref"])
) {
if (!_intermediateReasons.ContainsKey(tag["ref"])) {
_intermediateReasons.Add(tag["ref"], new string[7]);
}
_intermediateReasons[tag["ref"]][1] = letter;
_intermediateReasons[tag["ref"]][2] = page;
_intermediateReasons[tag["ref"]][3] = line;
if (!tag.IsEmpty) {
index.Push(tag["ref"]);
new ElementStringBinder(_reader, tag, AddReference);
}
}
}
protected override void Activate(IReader reader, Tag tag) {
if (!_active && reader != null && tag != null) {
_active = true;
_reader = reader;
Index = tag["index"];
_element = new ElementStringBinder(reader, tag, Add, _normalizeWhitespace);
}
}
private void Add(string element) {
if (String.IsNullOrWhiteSpace(element)) return;
if (!_intermediateReasons.ContainsKey(Index)) {
_intermediateReasons.Add(Index, new string[7]);
}
_intermediateReasons[Index][0] = element;
Reset();
}
private void AddReference(string element) {
if (String.IsNullOrWhiteSpace(element)) return;
var ci = index.Pop();
if (!_intermediateReasons.ContainsKey(ci)) {
_intermediateReasons.Add(ci, new string[7]);
}
_intermediateReasons[ci][4] = element;
_intermediateReasons[ci][5] = page;
_intermediateReasons[ci][6] = line;
}
protected override void Reset() {
Index = "";
_active = false;
_element = null;
}
protected void Deactivate() {
_element.Unsubscribe();
Reset();
}
}
}

View File

@@ -0,0 +1,99 @@
using System;
using HaDocument.Models;
using HaXMLReader.EvArgs;
using HaXMLReader.Interfaces;
using System.Text;
using System.Xml;
using System.Collections.Generic;
namespace HaDocument.Reactors {
class ElementStringBinder {
private StringBuilder _stringBuilder;
private XmlWriter _txtwriter;
private Stack<Tag> _stack;
private IReader _reader;
private Action<string> _callback;
private bool _normalizeWhitespace = false;
internal ElementStringBinder(IReader reader, Tag start, Action<string> callback) {
_reader = reader;
_callback = callback;
_stack = new Stack<Tag>();
_stringBuilder = new StringBuilder();
_txtwriter = XmlWriter.Create(_stringBuilder, new XmlWriterSettings() {
CheckCharacters = false,
ConformanceLevel = ConformanceLevel.Fragment,
Encoding = Encoding.UTF8,
OmitXmlDeclaration = true,
NewLineHandling = NewLineHandling.None
});
_stack.Push(start);
_writeTag(start);
Subscribe();
}
internal ElementStringBinder(IReader reader, Tag start, Action<string> callback, bool normalizeWhitespace) : this(reader, start, callback) {
_normalizeWhitespace = normalizeWhitespace;
}
internal void Subscribe() {
_reader.Tag += OnTag;
_reader.Text += OnText;
_reader.Whitespace += OnWhiteSpace;
}
internal void Unsubscribe() {
_reader.Tag -= OnTag;
_reader.Text -= OnText;
_reader.Whitespace -= OnWhiteSpace;
}
internal string GetElementText() {
_txtwriter.Flush();
_txtwriter.Dispose();
Unsubscribe();
var ret = _stringBuilder.ToString();
_stringBuilder = new StringBuilder();
return ret;
}
private void _writeTag(Tag tag) {
var writer = _txtwriter;
if (tag.EndTag) {
writer.WriteEndElement();
return;
}
writer.WriteStartElement(tag.Name);
if (tag.Values != null && tag.Values.Count > 0)
foreach (var kv in tag.Values)
writer.WriteAttributeString(kv.Key, kv.Value);
if ( tag.IsEmpty )
writer.WriteEndElement();
}
private void OnTag(object _, Tag tag) {
_writeTag(tag);
if (!tag.IsEmpty && tag.EndTag) _stack.Pop();
else if (!tag.IsEmpty) _stack.Push(tag);
if (_stack.Count == 0 ) _callback(GetElementText());
}
private void OnText(object _, Text text) {
if (_normalizeWhitespace) {
var neu = text.Value.Replace('\n', ' ').Replace("\t", "").Replace("\r", "");
_txtwriter.WriteString(neu);
}
else
_txtwriter.WriteString(text.Value);
}
private void OnWhiteSpace(object _, Whitespace ws) {
if (_normalizeWhitespace)
_txtwriter.WriteWhitespace(" ");
else
_txtwriter.WriteWhitespace(ws.Value);
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using HaXMLReader.EvArgs;
using HaXMLReader.Interfaces;
using HaDocument.Models;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace HaDocument.Reactors {
class HandDefsReactor : Reactor {
internal Dictionary<string, Person> CreatedInstances;
// State
private string Index;
private string Name;
internal HandDefsReactor(IReader reader, IntermediateLibrary lib) : base(reader, lib) {
lib.HandPersons = new Dictionary<string, Person>();
CreatedInstances = lib.HandPersons;
reader.Tag += Listen;
}
protected override void Listen(object sender, Tag tag) {
if (
!tag.EndTag &&
tag.IsEmpty &&
tag.Name == "handDef" &&
!String.IsNullOrWhiteSpace(tag["index"]) &&
!String.IsNullOrWhiteSpace(tag["name"])
) {
Activate(_reader, tag);
}
}
protected override void Activate(IReader reader, Tag tag) {
if (!_active && reader != null && tag != null) {
Reset();
_active = true;
Index = tag["index"];
Name = tag["name"];
Add();
_active = false;
}
}
protected override void Reset() {
Index = "";
Name = "";
}
protected void Add() {
CreatedInstances.Add(Index, new Person(Index, Name, "", ""));
}
}
}

View File

@@ -0,0 +1,151 @@
using System;
using HaXMLReader.EvArgs;
using HaXMLReader.Interfaces;
using HaDocument.Models;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Linq;
namespace HaDocument.Reactors
{
class LetterReactor : Reactor
{
internal Dictionary<string, Letter> CreatedInstances;
internal Dictionary<string, List<Hand>> CreatedHands;
internal Dictionary<string, Dictionary<string, HashSet<string>>> CreatedStructure;
// State
private string Index = "";
private ElementStringBinder _element = null;
private bool _normalizeWhitespace = false;
private string _page = "";
private string _line = "";
private List<Hand> _hands;
private string _person = "";
private string _handstartpg = "";
private string _handstartln = "";
internal LetterReactor(IReader reader, IntermediateLibrary lib, bool normalizeWhitespace) : base(reader, lib)
{
_normalizeWhitespace = normalizeWhitespace;
lib.Letters = new Dictionary<string, Letter>();
if (lib.Hands == null)
lib.Hands = new Dictionary<string, List<Hand>>();
if (lib.LetterPageLines == null)
lib.LetterPageLines = new Dictionary<string, Dictionary<string, HashSet<string>>>();
CreatedHands = lib.Hands;
CreatedInstances = lib.Letters;
CreatedStructure = lib.LetterPageLines;
reader.OpenTag += Listen;
reader.SingleTag += Listen;
reader.CloseTag += Listen;
}
protected override void Listen(object sender, Tag tag)
{
if (
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "letterText" &&
!String.IsNullOrWhiteSpace(tag["index"])
)
{
Activate(_reader, tag);
if (!CreatedStructure.ContainsKey(tag["index"]))
this.CreatedStructure.Add(tag["index"], new Dictionary<string, HashSet<string>>());
}
else if (
!tag.EndTag &&
_active &&
tag.Name == "line" &&
!String.IsNullOrWhiteSpace(tag["index"])
)
{
_line = tag["index"];
if (!CreatedStructure[Index][_page].Contains(_line))
{
CreatedStructure[Index][_page].Add(_line);
}
}
else if (
!tag.EndTag &&
_active &&
tag.Name == "page" &&
!String.IsNullOrWhiteSpace(tag["index"])
)
{
_page = tag["index"];
if (!CreatedStructure[Index].ContainsKey(_page))
CreatedStructure[Index].Add(_page, new HashSet<string>());
}
else if (
_active &&
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "hand" &&
!String.IsNullOrWhiteSpace(tag["ref"])
)
{
_person = tag["ref"];
_handstartln = _line;
_handstartpg = _page;
}
else if (
_active &&
tag.EndTag &&
tag.Name == "hand"
)
{
if (_hands == null)
_hands = new List<Hand>();
_hands.Add(new Hand(Index, _person, _handstartpg, _handstartln, _page, _line));
}
}
protected override void Activate(IReader reader, Tag tag)
{
if (!_active && reader != null && tag != null)
{
_active = true;
_reader = reader;
Index = tag["index"];
_element = new ElementStringBinder(reader, tag, Add, _normalizeWhitespace);
}
}
private void Add(string text)
{
if (String.IsNullOrWhiteSpace(text)) return;
var letter = new Letter(
Index,
text
);
CreatedInstances.TryAdd(Index, letter);
if (_hands != null)
{
if (!CreatedHands.ContainsKey(Index))
CreatedHands.Add(Index, _hands);
else
CreatedHands[Index].AddRange(_hands);
}
Reset();
}
protected override void Reset()
{
Index = "";
_active = false;
_element = null;
_hands = null;
}
protected void Deactivate()
{
_element.Unsubscribe();
Reset();
}
}
}

View File

@@ -0,0 +1,56 @@
using System;
using HaXMLReader.EvArgs;
using HaXMLReader.Interfaces;
using HaDocument.Models;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace HaDocument.Reactors {
class LocationDefsReactor : Reactor {
internal Dictionary<string, Location> CreatedInstances;
// State
private string Index;
private string Name;
internal LocationDefsReactor(IReader reader, IntermediateLibrary lib) : base(reader, lib) {
lib.Locations = new Dictionary<string, Location>();
CreatedInstances = lib.Locations;
reader.Tag += Listen;
}
protected override void Listen(object sender, Tag tag) {
if (
!tag.EndTag &&
tag.IsEmpty &&
tag.Name == "locationDef" &&
!String.IsNullOrWhiteSpace(tag["index"]) &&
!String.IsNullOrWhiteSpace(tag["name"])
) {
Activate(_reader, tag);
}
}
protected override void Activate(IReader reader, Tag tag) {
if (!_active && reader != null && tag != null) {
Reset();
_active = true;
Index = tag["index"];
Name = tag["name"];
Add();
_active = false;
}
}
protected override void Reset() {
Index = "";
Name = "";
}
protected void Add() {
CreatedInstances.Add(Index, new Location(Index, Name));
}
}
}

View File

@@ -0,0 +1,100 @@
using HaDocument.Models;
using System.Collections.Generic;
using HaXMLReader.EvArgs;
using HaXMLReader.Interfaces;
using System;
namespace HaDocument.Reactors {
class MarginalReactor : Reactor {
internal Dictionary<string, Marginal> CreatedInstances;
internal Dictionary<string, List<Backlink>> CreatedBacklinks;
private bool _normalizeWhitespace = false;
// State
private string Index = "";
private string Letter = "";
private string Page = "";
private string Line = "";
private ElementStringBinder _element = null;
internal MarginalReactor(IReader reader, IntermediateLibrary lib, bool normalizeWhitespace) : base(reader, lib) {
_normalizeWhitespace = normalizeWhitespace;
lib.Marginals = new Dictionary<string, Marginal>();
lib.Backlinks = new Dictionary<string, List<Backlink>>();
CreatedBacklinks = lib.Backlinks;
CreatedInstances = lib.Marginals;
reader.OpenTag += Listen;
}
protected override void Listen(object sender, Tag tag) {
if (
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "marginal" &&
!String.IsNullOrEmpty(tag["index"]) &&
!String.IsNullOrWhiteSpace(tag["letter"]) &&
!String.IsNullOrWhiteSpace(tag["page"]) &&
!String.IsNullOrWhiteSpace(tag["line"])
) {
Activate(_reader, tag);
}
}
protected override void Activate(IReader reader, Tag tag) {
if (!_active && reader != null && tag != null) {
_active = true;
_reader = reader;
Index = tag["index"];
Letter = tag["letter"];
Page = tag["page"];
Line = tag["line"];
_element = new ElementStringBinder(_reader, tag, Add, _normalizeWhitespace);
reader.Tag += OnTag;
}
}
private void OnTag(object _, Tag tag) {
if(
!tag.EndTag &&
tag.Name =="link"
) {
var id = "";
if (tag.Values.ContainsKey("subref"))
id = tag["subref"];
else if (tag.Values.ContainsKey("ref"))
id = tag["ref"];
if (!String.IsNullOrWhiteSpace(id)) {
if (!CreatedBacklinks.ContainsKey(id))
CreatedBacklinks.Add(id, new List<Backlink>());
CreatedBacklinks[id].Add(new Backlink(id, Letter, Page, Line, Index));
}
}
}
private void Add(string element) {
if (String.IsNullOrWhiteSpace(element)) return;
var marg = new Marginal(
Index,
Letter,
Page,
Line,
element
);
CreatedInstances.TryAdd(Index, marg);
Reset();
}
protected override void Reset() {
Index = "";
_active = false;
_element = null;
_reader.Tag -= OnTag;
}
public void Deactivate() {
_element.Unsubscribe();
Reset();
}
}
}

View File

@@ -0,0 +1,196 @@
using System;
using HaXMLReader.EvArgs;
using HaXMLReader.Interfaces;
using HaDocument.Models;
using System.Collections.Generic;
using System.Linq;
namespace HaDocument.Reactors {
class MetaReactor : Reactor {
internal Dictionary<string, Meta> CreatedInstances { get; }
private string[] _availableVolumes;
private (int, int) _availableYearRange;
// State
private string Index { get; set; } = "";
private string Autopsic { get; set; } = "";
private string Volume { get; set; } = "";
private string Page { get; set; } = "";
private string Date { get; set; } = "";
private DateTime Sort { get; set; } = new DateTime(1700, 1, 1);
private int Order { get; set; } = -1;
private bool AltLineNumbering { get; set; } = false;
private bool inZH { get; set; } = false;
private OptionalBool hasOriginal { get; set; } = OptionalBool.None;
private OptionalBool isProofread { get; set; } = OptionalBool.None;
private OptionalBool isDraft { get; set; } = OptionalBool.None;
private bool dateChanged {get; set; } = false;
private string Location { get; set; } = "";
private List<string> Senders { get; set; } = null;
private List<string> Receivers { get; set; } = null;
internal MetaReactor(IReader reader, IntermediateLibrary lib, string[] availableVolumes, (int, int) availableYearRange) : base(reader, lib) {
_availableVolumes = availableVolumes;
_availableYearRange = availableYearRange;
lib.Metas = new Dictionary<string, Meta>();
CreatedInstances = lib.Metas;
reader.OpenTag += Listen;
}
protected override void Listen(object sender, Tag tag) {
if (
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name =="letterDesc" &&
!String.IsNullOrWhiteSpace(tag["ref"])
) {
Activate(_reader, tag);
}
}
protected override void Activate(IReader reader, Tag tag) {
if (!_active && reader != null && tag != null) {
Reset();
_active = true;
Index = tag["ref"];
reader.Tag += OnTag;
_reader = reader;
}
}
public void Deactivate() {
if (_active) {
Abort();
Add();
}
}
public void Abort() {
if (_active) {
_active = false;
_reader.Tag -= OnTag;
}
}
private void OnTag(object _, Tag tag) {
switch (tag.Name)
{
case "autopsic":
Autopsic = tag["value"];
if (String.IsNullOrWhiteSpace(Autopsic)) Abort();
break;
case "begin":
Page = tag["page"];
Volume = tag["vol"];
break;
case "date":
Date = tag["value"];
break;
case "location":
Location = tag["ref"];
break;
case "sender":
if (!String.IsNullOrWhiteSpace(tag["ref"])) Senders.Add(tag["ref"]);
break;
case "receiver":
if (!String.IsNullOrWhiteSpace(tag["ref"])) Receivers.Add(tag["ref"]);
break;
case "sort":
DateTime res;
System.DateTime.TryParse(tag["value"], out res);
Sort = res;
int res2 = 0;
Int32.TryParse(tag["order"], out res2);
Order = res2;
break;
case "hasOriginal":
var val = tag["value"];
if (val.ToLower() == "true")
hasOriginal = OptionalBool.True;
else if (val.ToLower() == "false")
hasOriginal = OptionalBool.False;
else
hasOriginal = OptionalBool.None;
break;
case "isProofread":
var val2 = tag["value"];
if (val2.ToLower() == "true")
isProofread = OptionalBool.True;
else if (val2.ToLower() == "false")
isProofread = OptionalBool.False;
else
isProofread = OptionalBool.None;
break;
case "isDraft":
var val3 = tag["value"];
if (val3.ToLower() == "true")
isDraft = OptionalBool.True;
else if (val3.ToLower() == "false")
isDraft = OptionalBool.False;
else
isDraft = OptionalBool.None;
break;
case "ZHInfo":
if (!tag.EndTag) {
inZH = tag["inzh"] == "false" ? false : true;
}
break;
case "dateChanged":
dateChanged = tag["value"].ToLower() == "true" ? true : false;
break;
case "alternativeLineNumbering":
AltLineNumbering = tag["value"].ToLower() == "true" ? true : false;
break;
case "letterDesc":
if (tag.EndTag) Deactivate();
break;
}
}
private void Add() {
if (
_availableVolumes.Contains(Volume) ||
(Sort.Year >= _availableYearRange.Item1 && Sort.Year <= _availableYearRange.Item2) ||
(_availableVolumes == null && _availableYearRange.Item1 == 0 && _availableYearRange.Item2 == 0)
) {
var ZHInfo = !inZH ? null : new ZHInfo(AltLineNumbering, dateChanged, Volume, Page);
var meta = new Meta(
Index,
Autopsic,
Date,
Sort,
Order,
hasOriginal,
isProofread,
isDraft,
Location,
Senders,
Receivers,
ZHInfo
);
CreatedInstances.TryAdd(meta.Index, meta);
}
}
protected override void Reset() {
inZH = true;
hasOriginal = OptionalBool.None;
isProofread = OptionalBool.None;
isDraft = OptionalBool.None;
dateChanged = false;
Index = "";
Autopsic = "";
Volume = "";
Page = "";
Date = "";
DateTime Sort = new DateTime(1700, 1, 1);
Order = -1;
AltLineNumbering = false;
Location = "";
Senders = new List<string>();
Receivers = new List<string>();
}
}
}

View File

@@ -0,0 +1,60 @@
using System;
using HaXMLReader.EvArgs;
using HaXMLReader.Interfaces;
using HaDocument.Models;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace HaDocument.Reactors {
class PersonDefsReactor : Reactor {
internal Dictionary<string, Person> CreatedInstances;
// State
private string Index;
private string Name;
private string Prename = "";
private string Surname = "";
internal PersonDefsReactor(IReader reader, IntermediateLibrary lib) : base(reader, lib) {
lib.Persons = new Dictionary<string, Person>();
CreatedInstances = lib.Persons;
reader.Tag += Listen;
}
protected override void Listen(object sender, Tag tag) {
if (!tag.EndTag &&
tag.IsEmpty &&
tag.Name == "personDef" &&
!String.IsNullOrWhiteSpace(tag["index"]) &&
!String.IsNullOrWhiteSpace(tag["name"])
) {
Activate(_reader, tag);
}
}
protected override void Activate(IReader reader, Tag tag) {
if (!_active && reader != null && tag != null) {
Reset();
_active = true;
Index = tag["index"];
Name = tag["name"];
Prename = tag["vorname"];
Surname = tag["nachname"];
Add();
_active = false;
}
}
protected override void Reset() {
Index = "";
Name = "";
Prename = "";
Surname = "";
}
public void Add() {
CreatedInstances.Add(Index, new Person(Index, Name, Prename, Surname));
}
}
}

View File

@@ -0,0 +1,20 @@
using HaDocument.Models;
using HaXMLReader.Interfaces;
using HaXMLReader.EvArgs;
namespace HaDocument.Reactors {
abstract class Reactor {
protected IReader _reader;
protected IntermediateLibrary _lib;
protected bool _active = false;
internal Reactor(IReader reader, IntermediateLibrary lib) {
_reader = reader;
_lib = lib;
}
protected abstract void Listen(object sender, Tag tag);
protected abstract void Activate(IReader reader, Tag tag);
protected abstract void Reset();
}
}

View File

@@ -0,0 +1,156 @@
using HaDocument.Models;
using System.Collections.Generic;
using HaXMLReader.EvArgs;
using HaXMLReader.Interfaces;
using System;
namespace HaDocument.Reactors
{
class TraditionsReactor : Reactor
{
internal Dictionary<string, Tradition> CreatedInstances;
internal Dictionary<string, Dictionary<string, HashSet<string>>> CreatedStructure;
internal Dictionary<string, List<Hand>> CreatedHands;
private bool _normalizeWhitespace = false;
// State
private string Index = "";
private string _page = "";
private string _line = "";
private List<Hand> _hands;
private string _person = "";
private string _handstartpg = "";
private string _handstartln = "";
private ElementStringBinder _element = null;
internal TraditionsReactor(IReader reader, IntermediateLibrary lib, bool normalizeWhitespace) : base(reader, lib)
{
_normalizeWhitespace = normalizeWhitespace;
_lib.Traditions = new Dictionary<string, Tradition>();
if (lib.LetterPageLines == null)
lib.LetterPageLines = new Dictionary<string, Dictionary<string, HashSet<string>>>();
if (lib.Hands == null)
lib.Hands = new Dictionary<string, List<Hand>>();
CreatedHands = lib.Hands;
CreatedInstances = _lib.Traditions;
CreatedStructure = lib.LetterPageLines;
reader.Tag += Listen;
}
protected override void Listen(object sender, Tag tag)
{
if (!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "letterTradition" &&
!String.IsNullOrWhiteSpace(tag["ref"])
)
{
Activate(_reader, tag);
}
else if (
!tag.EndTag &&
_active &&
tag.Name == "ZHText"
)
{
if (!CreatedStructure.ContainsKey(tag["index"]))
this.CreatedStructure.Add(tag["index"], new Dictionary<string, HashSet<string>>());
}
else if (
!tag.EndTag &&
_active &&
tag.Name == "line" &&
!String.IsNullOrWhiteSpace(tag["index"])
)
{
_line = tag["index"];
if (!CreatedStructure[Index][_page].Contains(_line))
{
CreatedStructure[Index][_page].Add(_line);
}
}
else if (
!tag.EndTag &&
_active &&
tag.Name == "page" &&
!String.IsNullOrWhiteSpace(tag["index"])
)
{
_page = tag["index"];
if (!CreatedStructure[Index].ContainsKey(_page))
{
CreatedStructure[Index].Add(_page, new HashSet<string>());
}
}
else if (
_active &&
!tag.EndTag &&
!tag.IsEmpty &&
tag.Name == "hand" &&
!String.IsNullOrWhiteSpace(tag["ref"])
)
{
_person = tag["ref"];
_handstartln = _line;
_handstartpg = _page;
}
else if (
_active &&
tag.EndTag &&
tag.Name == "hand"
)
{
if (_hands == null)
_hands = new List<Hand>();
_hands.Add(new Hand(Index, _person, _handstartpg, _handstartln, _page, _line));
}
}
protected override void Activate(IReader reader, Tag tag)
{
if (!_active && reader != null && tag != null)
{
_active = true;
Index = tag["ref"];
_element = new ElementStringBinder(reader, tag, Add, _normalizeWhitespace);
}
}
private void Add(string element)
{
if (String.IsNullOrWhiteSpace(element)) return;
var reason = new Tradition(
Index,
element);
CreatedInstances.TryAdd(Index, reason);
if (_hands != null)
{
if (!CreatedHands.ContainsKey(Index))
CreatedHands.Add(Index, _hands);
else
CreatedHands[Index].AddRange(_hands);
}
Reset();
}
protected override void Reset()
{
Index = "";
_page = "";
_line = "";
_active = false;
_element = null;
_hands = null;
}
protected void Deactivate()
{
_element.Unsubscribe();
Reset();
}
}
}

View File

@@ -0,0 +1,14 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using HaWeb.Models;
namespace HaWeb.Controllers;
public class ErrorController : Controller
{
[Route("Error404/")]
public IActionResult ErrorNotFound() {
return View();
}
}

View File

@@ -1,29 +1,161 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using HaWeb.Models;
using HaDocument.Interfaces;
using HaXMLReader.Interfaces;
using System.Text;
using HaXMLReader;
using HaXMLReader.EvArgs;
using HaDocument.Models;
using System.Collections.Concurrent;
namespace HaWeb.Controllers;
[Route("Register/[action]/{id?}")]
public class RegisterController : Controller
{
private static HashSet<string> _permittedRegister;
private static HashSet<string> _permittedBibelstellen;
private static HashSet<string> _permittedForschung;
[BindProperty(SupportsGet = true)]
public string? search { get; set; }
[BindProperty(SupportsGet = true)]
public string? id { get; set; }
// DI
private ILibrary _lib;
private IReaderService _readerService;
public RegisterController(ILibrary lib, IReaderService readerService)
{
_lib = lib;
_readerService = readerService;
_permittedRegister = new HashSet<string>();
_lib.CommentsByCategoryLetter["neuzeit"].Select(x => _permittedRegister.Add(x.Key));
_permittedForschung = new HashSet<string>();
_lib.CommentsByCategoryLetter["forschung"].Select(x => _permittedForschung.Add(x.Key));
_permittedForschung.Add("Editionen");
_permittedBibelstellen = new HashSet<string>();
_permittedBibelstellen.Add("NT");
_permittedBibelstellen.Add("AP");
_permittedBibelstellen.Add("AT");
}
public IActionResult Register(string? id)
{
var category = "neuzeit";
var defaultLetter = "A";
normalizeID(id, defaultLetter);
ViewData["Title"] = "Allgemeines Register";
ViewData["SEODescription"] = "Johann Georg Hamann: Kommentierte Briefausgabe. Personen-, Sach- und Ortsregister.";
return standardModel(category, id, defaultLetter, new RegisterViewModel(), _permittedRegister);
}
public IActionResult Bibelstellen(string? id)
{
var category = "bibel";
var defaultLetter = "AT";
normalizeID(id, defaultLetter);
ViewData["Title"] = "Bibelstellenregister";
ViewData["SEODescription"] = "Johann Georg Hamann: Kommentierte Briefausgabe. Bibelstellenregister.";
var model = new RegisterViewModel() {
AvailableCategories = new List<(string, string)>() { ("Altes Testament", "AT"), ("Apogryphen", "AP"), ("Neues Testament", "NT") },
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].Select(x => new CommentModel(x)).OrderBy(x => x.Comment.Order).ToList() : null,
};
return standardModel(category, id, defaultLetter, new RegisterViewModel(), _permittedBibelstellen);
}
public IActionResult Forschung(string? id)
{
var category = "forschung";
var defaultLetter = "A";
normalizeID(id, defaultLetter);
if (id != null && id.ToUpper() == "EDITIONEN") category = "editionen";
var model = new RegisterViewModel()
{
AvailableSideCategories = new List<(string, string)>() { ("Editionen", "Editionen") },
};
ViewData["Title"] = "Forschungsbibliographie";
ViewData["SEODescription"] = "Johann Georg Hamann: Kommentierte Briefausgabe. Forschungsbibliographie.";
return standardModel(category, id, defaultLetter, new RegisterViewModel(), _permittedForschung);
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
public IActionResult Register(string? id)
private IActionResult standardModel(string category, string? id, string defaultid, HaWeb.Models.RegisterViewModel model, HashSet<string> permitted)
{
return View("Index");
if (!validationCheck(permitted)) {
Response.StatusCode = 404;
return Redirect("/Error404");
}
model.Category = category;
model.Id = id;
model.Search = search ?? "";
model.Comments = model.Comments ?? _lib.CommentsByCategoryLetter[category][id].Select(x => new CommentModel(x)).OrderBy(x => x.Comment.Index).ToList();
model.AvailableCategories = model.AvailableCategories ?? _lib.CommentsByCategoryLetter[category].Select(x => (x.Key.ToUpper(), x.Key.ToUpper())).ToList();
model.AvailableCategories.Sort();
foreach (var k in model.Comments)
k.SetHTML(_lib, _readerService);
return View("Index", model);
}
private void normalizeID(string? id, string defaultid) {
id = id ?? defaultid;
id = id.ToUpper();
}
public IActionResult Bibelstellen(string? id)
private bool validationCheck(HashSet<string> permitted)
{
return View("Index");
if (!permitted.Contains(id))
{
return false;
}
return true;
}
public IActionResult Forschung(string? id)
{
return View("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,64 @@
namespace HaWeb.HTMLHelpers;
public static class ConversionHelpers {
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;
}
}

View File

@@ -0,0 +1,122 @@
namespace HaWeb.HTMLHelpers;
using HaDocument.Interfaces;
using HaDocument.Models;
using System;
using System.Text;
using HaXMLReader.Interfaces;
using HaXMLReader.EvArgs;
using HaXMLReader;
using System.Collections.Generic;
public class LinkHelper {
private ILibrary _lib;
private IReader _reader;
private StringBuilder _sb;
private bool _followlinksinchildren;
private bool _followlinksinthis;
public LinkHelper(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.TagHelpers.CreateEndElement("a"));
}
else {
if (tag.Name == "wwwlink" && tag.Values.ContainsKey("address") && _followlinksinthis)
_sb.Append(HTMLHelpers.TagHelpers.CreateCustomElement("a",
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "class", Value = "hlink wwwlink invlink" },
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "href", Value = tag["address"]},
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "target", Value = "_blank"},
new HaWeb.HTMLHelpers.TagHelpers.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.TagHelpers.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.ConversionHelpers.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.TagHelpers.CreateElement("a", "hlink link invlink", "/Supplementa/Register/" + linkloc[0] + "#" + comment.Index));
else if (comment.Type == "bibel")
_sb.Append(HTMLHelpers.TagHelpers.CreateElement("a", "hlink link invlink", "/Supplementa/Bibelstellen/" + linkloc[0] + linkloc[1] + "#" + comment.Index));
else if (comment.Type == "forschung")
_sb.Append(HTMLHelpers.TagHelpers.CreateElement("a", "hlink link invlink", "/Supplementa/Forschung/" + linkloc[0] + "#" + comment.Index));
_sb.Append(GetLemmaString(tag, comment));
}
}
if (tag.IsEmpty && _followlinksinthis) _sb.Append(HTMLHelpers.TagHelpers.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 LinkHelper(_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.TagHelpers.CreateElement("div", "reference")) ),
( x => x.Name == "titel", (strbd, x) => strbd.Append(HTMLHelpers.TagHelpers.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.TagHelpers.CreateEndElement("div")) ),
( x => x.Name == "titel", (strbd, x) => strbd.Append(HTMLHelpers.TagHelpers.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 XMLHelper(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;
}
~LinkHelper() {
Dispose();
}
}

View File

@@ -0,0 +1,18 @@
namespace HaWeb.HTMLHelpers;
public static class StringHelpers {
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,59 @@
namespace HaWeb.HTMLHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
public static class TagHelpers
{
public struct Attribute
{
public string Name;
public string Value;
}
public static string CreateElement(string elementname, string classes = "", string ids = "")
{
string res = "<" + elementname;
if (!String.IsNullOrWhiteSpace(classes))
if (elementname == "button")
res += CreateAttribute(new Attribute() { Name = "type", Value = classes });
else
res += CreateAttribute(new Attribute() { Name = "class", Value = classes });
if (!String.IsNullOrWhiteSpace(ids))
if (elementname == "a")
res += CreateAttribute(new Attribute() { Name = "href", Value = ids });
else
res += CreateAttribute(new Attribute() { Name = "id", Value = ids });
return res + ">";
}
public static string CreateCustomElement(string elementname, params 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(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 Attribute() { Name = "class", Value = classes });
if (!String.IsNullOrWhiteSpace(ids))
res += CreateAttribute(new Attribute() { Name = "id", Value = ids });
return res + "></" + elementname + ">";
}
}

View File

@@ -0,0 +1,101 @@
namespace HaWeb.HTMLHelpers;
using HaXMLReader.Interfaces;
using HaXMLReader.EvArgs;
using System.Text;
using System.Collections.Generic;
using System;
public class XMLHelper {
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 XMLHelper(
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;
}
}
~XMLHelper() {
Dispose();
}
}

View File

@@ -27,4 +27,10 @@
<PackageReference Include="LigerShark.WebOptimizer.Core" Version="3.0.357" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\HaXMLReaderV6\HaXMLReaderV6.csproj" />
<ProjectReference Include="..\HaDocumentV6\HaDocumentV6.csproj" />
</ItemGroup>
</Project>

221642
HaWeb/Hamann.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
namespace HaWeb.Models;
using HaDocument.Models;
using HaDocument.Interfaces;
using System.Text;
using HaXMLReader.Interfaces;
using HaXMLReader.EvArgs;
public class CommentModel
{
public Comment Comment { get; private set; }
public string? ParsedComment { get; private set; }
public List<CommentModel>? SubComments { get; private set; }
// Parsing Rules
private static List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> _OTagFuncs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "lemma", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateElement("div", "lemma"))),
( x => x.Name == "title", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateElement("div", "title"))),
( x => x.Name == "titel", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateElement("div", "title")))
};
private static List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> _CTagFuncs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "lemma", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateEndElement("div"))),
( x => x.Name == "title", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateEndElement("div"))),
( x => x.Name == "titel", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateEndElement("div")))
};
private static List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> _STagFuncs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "line", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateElement("br")) )
};
private static List<(Func<Text, bool>, Action<StringBuilder, Text>)> _TextFuncs = new List<(Func<Text, bool>, Action<StringBuilder, Text>)>() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
private static List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)> _WhitespaceFuncs = new List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)>() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
public CommentModel(Comment comment)
{
this.Comment = comment;
if (comment.Kommentare != null && comment.Kommentare.Any())
{
SubComments = comment.Kommentare.Select(x => new CommentModel(x.Value)).OrderBy(x => x.Comment.Order).ToList();
}
}
public string returnHTML(ILibrary _lib, IReaderService _readerService)
{
StringBuilder sb = new StringBuilder();
var rd = _readerService.RequestStringReader(Comment.Lemma);
new HTMLHelpers.XMLHelper(rd, sb, _OTagFuncs, _STagFuncs, _CTagFuncs, _TextFuncs, _WhitespaceFuncs);
sb.Append(HTMLHelpers.TagHelpers.CreateElement("div", "lemma", Comment.Index));
new HTMLHelpers.LinkHelper(_lib, rd, sb);
rd.Read();
var backlinks = _lib.Backlinks.ContainsKey(Comment.Index) ? _lib.Backlinks[Comment.Index]
.Where(x => _lib.Metas.ContainsKey(x.Letter))
.OrderBy(x => _lib.Metas[x.Letter].Sort)
.ThenBy(x => _lib.Metas[x.Letter].Order) : null;
if (backlinks != null)
{
sb.Append(HTMLHelpers.TagHelpers.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.TagHelpers.CreateElement("a", "backlink", "/Briefe/" + let.Autopsic + "#" + blk.Page + "-" + blk.Line));
var linkstring = "";
var pglnstring = "";
linkstring += let.Autopsic;
pglnstring += "&nbsp;(&#8239;" + blk.Page + "/" + blk.Line + "&#8239;)";
linkstring += pglnstring;
sb.Append(linkstring);
if (blk != backlinks.Last())
sb.Append(",&emsp;");
sb.Append(HTMLHelpers.TagHelpers.CreateEndElement("a"));
}
}
sb.Append(HTMLHelpers.TagHelpers.CreateEndElement("div"));
}
sb.Append(HTMLHelpers.TagHelpers.CreateEndElement("div"));
rd = _readerService.RequestStringReader(Comment.Entry);
new HTMLHelpers.XMLHelper(rd, sb, _OTagFuncs, _STagFuncs, _CTagFuncs, _TextFuncs, _WhitespaceFuncs);
new HTMLHelpers.LinkHelper(_lib, rd, sb);
rd.Read();
if (SubComments != null && SubComments.Any())
{
foreach (var k in SubComments)
{
k.SetHTML(_lib, _readerService);
}
}
return sb.ToString();
}
public void SetHTML(ILibrary _lib, IReaderService _readerService) {
ParsedComment = returnHTML(_lib, _readerService);
}
}

View File

@@ -0,0 +1,13 @@
namespace HaWeb.Models;
using HaDocument.Models;
public class RegisterViewModel {
public string Category { get; set; } = "";
public string Id { get; set; } = "";
public string Search { get; set; } = "";
public bool MaxSearch { get; set; } = false;
// TODO: no null-checks in the Page Logic
public List<CommentModel>? Comments { get; set; } = null;
public List<(string, string)>? AvailableCategories { get; set; } = null;
public List<(string, string)>? AvailableSideCategories { get; set; } = null;
}

View File

@@ -0,0 +1,36 @@
namespace HaWeb.Models;
using HaDocument.Models;
using HaDocument.Comparers;
using HaDocument.Interfaces;
using System.Collections.Generic;
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);
}
}

View File

@@ -1,8 +1,15 @@
using HaXMLReader;
using HaXMLReader.Interfaces;
using HaDocument.Interfaces;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<ILibrary>(x => HaDocument.Document.Create(new Options()));
builder.Services.AddTransient<IReaderService, ReaderService>();
// builder.Services.AddWebOptimizer();
var app = builder.Build();
@@ -22,3 +29,10 @@ app.UseStaticFiles();
app.UseRouting();
app.MapControllers();
app.Run();
class Options : IHaDocumentOptions {
public string HamannXMLFilePath { get; set; } = @"Hamann.xml";
public string[] AvailableVolumes { get; set; } = { };
public bool NormalizeWhitespace { get; set; } = true;
public (int, int) AvailableYearRange {get; set; } = (1751, 1788);
}

76
HaWeb/Search.cs Normal file
View File

@@ -0,0 +1,76 @@
namespace HaWeb;
using HaDocument.Models;
using HaDocument.Interfaces;
using HaDocument.Comparers;
using HaXMLReader.Interfaces;
using HaWeb.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;
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,112 @@
@{
ViewData["Title"] = "Editionsgeschichte";
ViewData["SEODescription"] = "Johann Georg Hamann: Kommentierte Briefausgabe. Editionsgeschichtliche Voraussetzungen.";
}
<div class="ha-static">
<div class="md:pr-80">
<h1>Editionsgeschichtliche Voraussetzungen</h1>
<p>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="ha-sup" 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="ha-sup" name="FnZ-3" href="#FnA-3">3</a></p>
<p>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="ha-sup" 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>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="ha-sup" 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="italic">in persona</span> dessen Leiter Anton Kippenberg, ausgehandelt. Jedes Jahr sollten parallel je ein Band der Werke und Briefe erscheinen.<a class="ha-sup" name="FnZ-6" href="#FnA-6">6</a></p>
<p>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="ha-sup" 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="ha-sup" name="FnZ-8" href="#FnA-8">8</a></p>
<p>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="ha-sup" 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="ha-sup" name="FnZ-10" href="#FnA-10">10</a></p>
<p>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="ha-sup" 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="ha-sup" 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="ha-sup" name="FnZ-13" href="#FnA-13">13</a></p>
<p>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="ha-sup" 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>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="ha-sup" name="FnZ-15" href="#FnA-15">15</a> um eine Entkoppelung des Erscheinens der Briefbände von den Werkbänden baten.<a class="ha-sup" name="FnZ-16" href="#FnA-16">16</a> Kippenberg ging mit Verweis auf die vertraglichen Regelungen von 1930 jedoch nicht darauf ein<a class="ha-sup" 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="ha-sup" 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>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="ha-sup" name="FnZ-19" href="#FnA-19">19</a></p>
<p>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="ha-sup" name="FnZ-20" href="#FnA-20">20</a></p>
<p>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="ha-sup" name="FnZ-21" href="#FnA-21">21</a></p>
<p>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>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="ha-sup" 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="ha-sup" name="FnZ-23" href="#FnA-23">23</a> Band IV erschien als erster Band unter alleiniger Herausgeberschaft von Henkel 1959.<a class="ha-sup" 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="ha-sup" name="FnZ-25" href="#FnA-25">25</a> Der Textbestand ist freilich identisch.</p>
<p>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>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="ha-sup" name="FnZ-26" href="#FnA-26">26</a> 1957 hat es ein solches jedoch definitiv noch gegeben.</br></p>
<!-- Leerzeile -->
<p>Die letzten drei Bände der Briefausgabe erschienen, herausgegeben von Arthur Henkel: 1965, 1975 und 1979.<a class="ha-sup" 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>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><span class="italic">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>
<div class="my-8 mx-8">
<div class="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" name="FnA-3" href="#FnZ-3">3</a>Vgl. ebd., S. 150154.</div>
<div class="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" name="FnA-9" href="#FnZ-9">9</a>Vgl. Insel-Verlag an Ziesemer, 23.1.1937 (GSA 50/3859).</div>
<div class="ha-footnote"><a class="ha-sup ha-footnote-ref" name="FnA-10" href="#FnZ-10">10</a>Petersen an Kippenberg, 21.12.1929 (DLA, A: Petersen, 73.480/1).</div>
<div class="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="italic">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="italic">»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="ha-footnote"><a class="ha-sup ha-footnote-ref" name="FnA-12" href="#FnZ-12">12</a>Ziesemer an Insel-Verlag, 22.7. und 27.9.1937 (GSA 50/3859).</div>
<div class="ha-footnote"><a class="ha-sup ha-footnote-ref" name="FnA-13" href="#FnZ-13">13</a>Sitzungsberichte der Preussischen Akademie der Wissenschaften, Philosophisch-Historische Klasse (1938), LXVIII.</div>
<div class="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" name="FnA-17" href="#FnZ-17">17</a>Forsthoff an Petersen, 22.12.1940 (DLA, A: Petersen, 73.486/1).</div>
<div class="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" name="FnA-19" href="#FnZ-19">19</a>Kippenberg an Ziesemer, 27.1.1944 (GSA 50/3859).</div>
<div class="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" name="FnA-25" href="#FnZ-25">25</a>Ebd., S. XXIII.</div>
<div class="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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>

View File

@@ -4,8 +4,9 @@
}
<div class="ha-static">
<div class="md:pr-80">
<h1>Kontakt</h1>
<table class="">
<table>
<tr>
<td>Theodor Springmann Stiftung <br>
Dr. Janina Reibold <br>
@@ -25,13 +26,14 @@
<h3>Anmeldung zur regelmäßigen Mitteilung über den Stand der kommentierten Hamann-Ausgabe</h3>
<p>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>
<p>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.
<h3>Ihre Mitarbeit am Online-Kommentar</h3>
<p>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>
<p>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).
<h3>Zitierempfehlung</h3>
Johann Georg Hamann: <span class="italic">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]
<p>Johann Georg Hamann: <span class="italic">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]
</div>
</div>

View File

@@ -5,24 +5,26 @@
<div class="ha-static">
<h1>Mitwirkende</h1>
<h3>Philologische Mitarbeit</h3>
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)
<div class="md:pr-80">
<h1>Mitwirkende</h1>
<h3>Philologische Mitarbeit</h3>
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)
<h3>Technische Umsetzung</h3>
Carl Friedrich Haak (20182020)<br/>
Simon Martens (seit 2018)
<h3>Technische Umsetzung</h3>
Carl Friedrich Haak (20182020)<br/>
Simon Martens (seit 2018)
<h3>Zitierempfehlung</h3>
Johann Georg Hamann: <span class="italic">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]
<h3>Zitierempfehlung</h3>
<p>Johann Georg Hamann: <span class="italic">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]
</div>
</div>

View File

@@ -4,83 +4,84 @@
}
<div class="ha-static">
<h1>Editionsrichtlinien</h1>
<p>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 27. Januar 2022.</p>
<p>Die in den Brief-Manuskripten enthaltenen Auszeichnungen werden, teilweise in veränderter Form gegenüber ZH, wiedergegeben:</p>
<table class="fullwidth">
<tr>
<th>Handschrift/Abschrift</th>
<th>ZH</th>
<th>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>
<div class="md:pr-80">
<h1>Editionsrichtlinien</h1>
<p>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 27. Januar 2022.
<p>Die in den Brief-Manuskripten enthaltenen Auszeichnungen werden, teilweise in veränderter Form gegenüber ZH, wiedergegeben:
</div>
<div class="desktop:pr-8">
<table class="">
<tr>
<th>Handschrift od. Abschrift</th>
<th>Z&#x200A;H</th>
<th>H&#x200A;K&#x200A;B</th>
</tr>
<tr>
<td>Deutsche Kurrentschrift</td>
<td>Fraktur</td>
<td><span class="ha-serif">Serifenschrift (Linux Libertine)</span></td>
</tr>
<tr>
<td>Lateinische Schreibschrift</td>
<td>Antiqua</td>
<td><span class="ha-aq">serifenlose Schrift (Linux Biolinum)</span></td>
</tr>
<tr>
<td>Unterstreichung (einfache bis dreifache)</td>
<td>Sperrung / fette Sperrung</td>
<td><span class="ha-ul">Unterstreichung</span> (einfache bis dreifache)</td>
</tr>
<tr>
<td>Durchstreichung</td>
<td>in spitzen Klammern ⟨...⟩</td>
<td><span class="ha-del">Durchstreichung</span> (einfache bis doppelte)</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="ha-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="ha-added">grau hinterlegt</span></td>
</tr>
<tr>
<td>Herausgeberanmerkung</td>
<td>kleinere Schrift</td>
<td><span class="ha-note">Kursive in grauer Farbe</span></td>
</table>
</div>
<div class="md:pr-80">
<p>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>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>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>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>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>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>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>Die Forschungsbibliographie enthält Titel zu Hamanns Leben und Werk und soll beständig aktualisiert werden.
<p>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>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>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>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>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>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>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>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>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>Die Forschungsbibliographie enthält Titel zu Hamanns Leben und Werk und soll beständig aktualisiert werden. </p>
<p>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>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="italic">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]
</div>
<h3>Zitierempfehlung</h3>
<p>Johann Georg Hamann: <span class="italic">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]
</div>
</div>

View File

@@ -0,0 +1,38 @@
@{
ViewData["Title"] = "Werkausgabe";
ViewData["SEODescription"] = "Johann Georg Hamann: Kommentierte Briefausgabe. Informationen zur Werkausgabe.";
}
<div class="ha-static">
<div class="md:pr-80">
<h1>Werkausgabe</h1>
<h3>Kommentierte Neuedition ausgewählter Werke</h3>
<p>Die Edition der Werke Hamanns durch Josef Nadler<a class="ha-sup" 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="ha-sup" 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="list-disc ml-8">
<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>Der Kommentar wird sowohl als Stellen-, als auch als systematisch aufgebauter Kommentar erfolgen. Darüber hinaus wird jeder Band
<ul class="list-disc ml-8">
<li>eine ausführliche Einleitung</li>
<li>Dokumente zur Entstehungsgeschichte</li>
<li>eine Bibliographie</li>
</ul>
<p>enthalten.
<h3>Bereits erschienene Bände</h3>
<p>Johann Georg Hamann, <span class="italic">Fliegender Brief.</span> 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>Johann Georg Hamann, <span class="italic">Sokratische Denkwürdigkeiten. Wolken.</span> Historisch-kritische Ausgabe. Mit einer Einführung, einem Stellenkommentar und Dokumenten zur Entstehungsgeschichte hg. von Janina Reibold und Leonard Keidel. Unter Mitarbeit von Konrad Bucher. [= Philosophische Bibliothek 748] (Hamburg: Meiner Verlag 2021) [<a class="ExternerLink" href="https://meiner.de/philosophische-bibliothek/h/hamann/sokratische-denkwurdigkeiten-wolken.html">‣</a>]
<h3>Geplante Bände</h3>
<p>Kreuzzüge des Philologen
<div class="my-8 mx-8">
<div class="ha-footnote"><a class="ha-sup ha-footnote-ref" 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="ha-footnote"><a class="ha-sup ha-footnote-ref" 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>

View File

@@ -0,0 +1 @@
Die Seite wurde nicht gefunden!

View File

@@ -1 +1,11 @@
Hello from Register!
@model RegisterViewModel;
@using System.Diagnostics;
@foreach (var k in Model.Comments) {
<div>@Html.Raw(k.ParsedComment)</div>
@if (k.SubComments != null ) {
@foreach (var sk in k.SubComments) {
<div>@Html.Raw(sk.ParsedComment)</div>
}
}
}

View File

@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="@ViewData["SEODescription"]">
<title>H&#x200A;K&#x200a;B &#x2013; @ViewData["Title"]</title>
<title>HKB: @ViewData["Title"]</title>
<!-- crossorigin is a workaround to prevent double downloading bugs in chrome -->
<link rel="preload" href="/css/output.css" as="style" />

View File

@@ -7,6 +7,7 @@ module.exports = {
fontFamily: {
sans: ['Biolinum', 'sans-serif'],
serif: ['Libertine', 'serif'],
classy: ['Playfair', 'serif'],
},
screens: {
'sm': '786px',

View File

@@ -652,8 +652,8 @@ body {
background-color: rgb(248 250 252 / var(--tw-bg-opacity));
padding-top: 3rem;
padding-bottom: 3rem;
padding-left: 4rem;
padding-right: 4rem;
padding-left: 3rem;
padding-right: 3rem;
font-family: Libertine, serif;
-webkit-hyphens: auto;
-ms-hyphens: auto;
@@ -662,7 +662,8 @@ body {
@media (min-width: 1024px) {
.ha-static {
padding-right: 20rem;
padding-left: 4rem;
padding-right: 4rem;
}
}
@@ -709,26 +710,40 @@ body {
}
.ha-static table th {
padding-left: 0.5rem;
padding-right: 0.5rem;
text-align: left;
font-weight: 400;
--tw-text-opacity: 1;
color: rgb(216 0 0 / var(--tw-text-opacity));
}
.ha-static .fullwidth {
width: 100%;
@media (min-width: 1190px) {
.ha-static table th {
padding-right: 1rem;
}
}
@media (min-width: 1024px) {
.ha-static .fullwidth {
margin-right: -20rem;
}
.ha-static table tr td {
padding-left: 0.5rem;
padding-right: 0.5rem;
vertical-align: top;
}
@media (min-width: 1190px) {
.ha-static .fullwidth {
max-width: 1190px;
.ha-static table tr td {
white-space: nowrap;
padding-right: 1rem;
}
.ha-static table tr td:last-child {
white-space: normal;
}
}
.ha-static table tr:nth-child(even) {
--tw-bg-opacity: 1;
background-color: rgb(226 232 240 / var(--tw-bg-opacity));
}
.ha-static p {
@@ -750,8 +765,71 @@ body {
text-decoration-style: solid;
}
.ha-static .ha-footnote {
position: relative;
font-size: 0.875rem;
line-height: 1.25rem;
}
@media (min-width: 1190px) {
.ha-static .ha-footnote {
font-size: 1rem;
line-height: 1.5rem;
}
}
.ha-static .ha-footnote .ha-footnote-ref {
position: absolute;
left: -2.5rem;
display: inline-block;
width: 2rem;
text-align: right;
}
/* Classes from .NET */
.ha-serif {
font-family: Libertine, serif;
}
.ha-aq {
font-family: Biolinum, sans-serif;
}
.ha-ul {
-webkit-text-decoration-line: underline;
text-decoration-line: underline;
}
.ha-del {
-webkit-text-decoration-line: line-through;
text-decoration-line: line-through;
}
.ha-hand {
font-family: Playfair, serif;
font-size: 0.9rem;
}
.ha-added {
--tw-bg-opacity: 1;
background-color: rgb(209 213 219 / var(--tw-bg-opacity));
padding-left: 0.25rem;
padding-right: 0.25rem;
}
.ha-note {
font-style: italic;
--tw-text-opacity: 1;
color: rgb(75 85 99 / var(--tw-text-opacity));
}
.ha-sup {
position: relative;
top: -0.5em;
font-size: 80%;
}
/* Classes from Javascript */
.active {
@@ -891,11 +969,25 @@ body {
position: sticky;
}
.my-8 {
margin-top: 2rem;
margin-bottom: 2rem;
}
.mx-8 {
margin-left: 2rem;
margin-right: 2rem;
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
.ml-8 {
margin-left: 2rem;
}
.mb-6 {
margin-bottom: 1.5rem;
}
@@ -960,6 +1052,10 @@ body {
cursor: default;
}
.list-disc {
list-style-type: disc;
}
.flex-row {
flex-direction: row;
}
@@ -1186,6 +1282,12 @@ body {
hyphens: auto;
}
.unhyphenate {
-webkit-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
.ha-menu-arrowsymbol::after {
display: inline-block;
margin-left: 0.2em;
@@ -1236,6 +1338,10 @@ body {
.md\:hidden {
display: none;
}
.md\:pr-80 {
padding-right: 20rem;
}
}
@media (min-width: 1190px) {
@@ -1255,6 +1361,10 @@ body {
padding-left: 2rem;
padding-right: 2rem;
}
.desktop\:pr-8 {
padding-right: 2rem;
}
}
@media (min-width: 1440px) {

View File

@@ -139,7 +139,7 @@
} */
.ha-static {
@apply w-full bg-slate-50 py-12 px-16 hyphenate md:pr-80 font-serif
@apply w-full bg-slate-50 py-12 px-12 md:px-16 hyphenate font-serif
}
.ha-static h1 {
@apply font-bold text-xl desktop:font-normal desktop:text-4xl mb-6
@@ -158,11 +158,19 @@
}
.ha-static table th {
@apply text-left font-normal text-hamannHighlight
@apply pl-2 pr-2 desktop:pr-4 text-left font-normal text-hamannHighlight
}
.ha-static .fullwidth {
@apply w-full desktop:max-w-screen-desktop md:-mr-80
.ha-static table tr td {
@apply pl-2 pr-2 desktop:pr-4 align-top desktop:whitespace-nowrap
}
.ha-static table tr td:last-child {
@apply desktop:whitespace-normal
}
.ha-static table tr:nth-child(even) {
@apply bg-slate-200
}
.ha-static p {
@@ -177,7 +185,46 @@
@apply underline decoration-solid
}
.ha-static .ha-footnote {
@apply relative text-sm desktop:text-base
}
.ha-static .ha-footnote .ha-footnote-ref {
@apply inline-block absolute text-right w-8 -left-10
}
/* Classes from .NET */
.ha-serif {
@apply font-serif
}
.ha-aq {
@apply font-sans
}
.ha-ul {
@apply underline
}
.ha-del {
@apply line-through
}
.ha-hand {
@apply font-classy text-[0.9rem]
}
.ha-added {
@apply bg-gray-300 px-1
}
.ha-note {
@apply italic text-gray-600
}
.ha-sup {
@apply relative -top-[0.5em] text-[80%]
}
/* Classes from Javascript */
.active {
@@ -216,7 +263,6 @@
.ha-topnav.ha-topnav-collapsed .ha-topnav-dropdown .ha-topnav-dropdown-content a {
@apply py-1 desktop:py-2
}
}
* {
@@ -236,6 +282,10 @@ body {
hyphens: auto;
}
.unhyphenate {
hyphens: none;
}
.ha-menu-arrowsymbol::after {
display: inline-block;
margin-left: 0.2em;

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using HaXMLReader.Interfaces;
namespace HaXMLReader.EvArgs
{
public class Tag : EventArgs, IReaderEvArg
{
public string Name { get; set; } = "";
public Dictionary<string, string> Values { get; set; } = new Dictionary<string, string>();
public bool IsEmpty { get; set; } = false;
public bool EndTag { get; set; } = false;
// Privides safe access to the values Dict
public string this[string key]
{
get
{
if (Values != null && Values.ContainsKey(key))
return Values[key];
else
return "";
}
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using HaXMLReader.Interfaces;
namespace HaXMLReader.EvArgs
{
public class Text : EventArgs, IReaderEvArg
{
public string Value { get; set; } = "";
}
}

View File

@@ -0,0 +1,8 @@
using HaXMLReader.Interfaces;
namespace HaXMLReader.EvArgs {
public class Whitespace : System.EventArgs, IReaderEvArg {
public string Value { get; set; }
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Linq;
using System.IO;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using HaXMLReader.EvArgs;
using HaXMLReader.Interfaces;
namespace HaXMLReader
{
public class FileReader : Reader, IReader
{
private readonly string _uri;
private MemoryStream _memoryStream;
public FileReader(string uri)
{
_uri = uri;
_memoryStream = new MemoryStream(File.ReadAllBytes(_uri));
CreateReader();
}
public FileReader(string uri, Action<string[]> Logsink) : this(uri)
{
_LogSink = Logsink;
}
public override void Dispose()
{
base.Dispose();
_memoryStream.Dispose();
}
protected override XmlReader GetReader() {
return XmlReader.Create(_memoryStream, _Settings);
}
}
}

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,28 @@
using System;
using System.Xml;
using HaXMLReader.EvArgs;
namespace HaXMLReader.Interfaces {
public interface IReader {
event EventHandler ReadingStart;
event EventHandler ReadingStop;
event EventHandler<Tag> Tag;
event EventHandler<Tag> OpenTag;
event EventHandler<Tag> CloseTag;
event EventHandler<Tag> SingleTag;
event EventHandler<Whitespace> Whitespace;
event EventHandler<Text> Text;
void Log(params string[] message);
void Read();
void Dispose();
void ImportSettings(XmlReaderSettings settings);
IReader CreateReaderForSubtree(Func<Tag, bool> Condition);
IReader CreateReaderForSubtree(string elementname);
// Legacy
void Close();
}
}

View File

@@ -0,0 +1,7 @@
using System;
namespace HaXMLReader.Interfaces {
public interface IReaderEvArg {
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Xml.Linq;
namespace HaXMLReader.Interfaces {
/// <summary>
/// Is a simple service to create appropriate IReader Instances.
/// </summary>
public interface IReaderService {
IReader RequestReader(XElement element);
IReader RequestReader(XElement element, Action<string[]> logsink);
IReader RequestReader(string uri);
IReader RequestReader(string uri, Action<string[]> logsink);
IReader RequestStringReader(string toread);
}
}

174
HaXMLReaderV6/Reader.cs Normal file
View File

@@ -0,0 +1,174 @@
using System;
using HaXMLReader.EvArgs;
using System.Linq;
using System.IO;
using System.Xml;
using System.Collections;
using System.ComponentModel;
using System.Collections.Generic;
using HaXMLReader.Interfaces;
namespace HaXMLReader
{
public abstract class Reader : IReader
{
public event EventHandler ReadingStart;
public event EventHandler ReadingStop;
public event EventHandler<Tag> Tag;
public event EventHandler<Tag> OpenTag;
public event EventHandler<Tag> CloseTag;
public event EventHandler<Tag> SingleTag;
public event EventHandler<Whitespace> Whitespace;
public event EventHandler<Text> Text;
protected Action<string[]> _LogSink { get; set; }
private XmlReader _XReader { get; set; } = null;
//State:
internal XmlReaderSettings _Settings = new XmlReaderSettings()
{
CloseInput = true,
CheckCharacters = false,
ConformanceLevel = ConformanceLevel.Fragment,
IgnoreComments = true,
IgnoreProcessingInstructions = true,
IgnoreWhitespace = false
};
public void Log(params string[] message)
{
if (_LogSink != null) _LogSink.Invoke(message.Select(x => x = "HamannDocument: \t" + x).ToArray());
}
public void Read()
{
if (_XReader == null ||
_XReader.ReadState == ReadState.Closed ||
_XReader.ReadState == ReadState.EndOfFile ||
_XReader.ReadState == ReadState.Error) {
CreateReader();
}
ReadingStart?.Invoke(this, EventArgs.Empty);
while (_XReader.Read())
{
_Read();
}
ReadingStop?.Invoke(this, EventArgs.Empty);
Dispose();
}
private void _Read() {
try {
switch (_XReader.NodeType)
{
case XmlNodeType.Text:
Text?.Invoke(this, new Text() { Value = _XReader.Value });
break;
case XmlNodeType.SignificantWhitespace:
Whitespace?.Invoke(this, new Whitespace() { Value = _XReader.Value });
break;
case XmlNodeType.Whitespace:
Whitespace?.Invoke(this, new Whitespace() { Value = _XReader.Value });
break;
case XmlNodeType.Element:
var tag = _TagCreation();
Tag?.Invoke(this, tag);
if (tag.IsEmpty) SingleTag?.Invoke(this, tag);
else OpenTag?.Invoke(this, tag);
break;
case XmlNodeType.EndElement:
var tg = _TagCreation();
Tag?.Invoke(this, tg);
CloseTag?.Invoke(this, tg);
break;
}
}
catch (XmlException ex) {
Log(ex.Message);
throw ex;
}
}
public IReader CreateReaderForSubtree(string elementname) {
if (_XReader == null) CreateReader();
else throw new InvalidOperationException("Der Status des Readers kann nicht verändert werden.");
_skipUntilElement(elementname);
return _createReaderForSubtree();
}
public IReader CreateReaderForSubtree(Func<Tag, bool> Condition) {
if (_XReader == null) CreateReader();
else throw new InvalidOperationException("Der Status des Readers kann nicht verändert werden.");
while (_XReader.Read()) {
if(_XReader.NodeType == XmlNodeType.Element) {
var tag = _TagCreation();
if (Condition(tag))
return _createReaderForSubtree();
}
}
return null;
}
private IReader _createReaderForSubtree() {
if (_XReader.NodeType == XmlNodeType.Attribute)
_XReader.MoveToElement();
return new XmlReaderReader(_XReader.ReadSubtree());
}
public void ImportSettings(XmlReaderSettings settings) {
_Settings = settings;
}
public virtual void Dispose() {
}
// Legacy:
public void Close() {
_XReader.Close();
}
protected void CreateReader() {
if (_XReader == null ||
_XReader.ReadState == ReadState.Closed ||
_XReader.ReadState == ReadState.EndOfFile ||
_XReader.ReadState == ReadState.Error) {
_XReader = GetReader();
}
}
protected abstract XmlReader GetReader();
private void _skipUntilElement(string name) {
if (_XReader == null) CreateReader();
else throw new InvalidOperationException("Der Status des Readers kann nicht verändert werden.");
_XReader.ReadToFollowing(name);
}
private Tag _TagCreation() {
var tag = new Tag();
tag.Name = _XReader.Name;
tag.IsEmpty = _XReader.IsEmptyElement;
tag.EndTag = _XReader.NodeType == XmlNodeType.EndElement ? true : false;
if (_XReader.HasAttributes)
{
int no = _XReader.AttributeCount;
for (int step = 0; step < no; step++)
{
_XReader.MoveToAttribute(step);
tag.Values.Add(_XReader.Name.ToLower(), _XReader.Value);
}
}
return tag;
}
private void _checkReadStateInteractive() {
if (_XReader != null && _XReader.ReadState != ReadState.Interactive) {
Dispose();
var ex = new InvalidOperationException("The Reader is currently not in a reading state");
Log(ex.Message);
throw ex;
}
return;
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Xml.Linq;
using HaXMLReader.Interfaces;
namespace HaXMLReader {
/// <summary>
/// Very basic IReader-Factory. Lifetime of a reader must be handled outside.
/// Allows using any Reader as a service e.g. within web projects.
/// Allow injecting the service into another project.
/// </summary>
public class ReaderService : IReaderService {
public IReader RequestReader(XElement element) => new XElementReader(element);
public IReader RequestReader(XElement element, Action<string[]> logsink) => new XElementReader(element, logsink);
public IReader RequestReader(string uri) => new FileReader(uri);
public IReader RequestReader(string uri, Action<string[]> logsink) => new FileReader(uri, logsink);
public IReader RequestStringReader(String toread) => new UTF8StringReader(toread);
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Text;
using System.IO;
using System.Xml;
using HaXMLReader.Interfaces;
namespace HaXMLReader {
public class UTF8StringReader : Reader, IReader {
private readonly string _str;
private StringReader _memoryStream;
public UTF8StringReader(string str)
{
_str = str;
_memoryStream = new StringReader(str);
CreateReader();
}
public UTF8StringReader(string str, Action<string[]> Logsink) : this(str)
{
_LogSink = Logsink;
}
public override void Dispose()
{
base.Dispose();
_memoryStream.Dispose();
}
protected override XmlReader GetReader() {
return XmlReader.Create(_memoryStream, _Settings);
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Linq;
using System.IO;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using HaXMLReader.Interfaces;
using System.Xml.Linq;
namespace HaXMLReader
{
public class XElementReader : Reader, IReader
{
private readonly XElement _element;
public XElementReader(XElement element)
{
_element = element;
CreateReader();
}
public XElementReader(XElement element, Action<string[]> Logsink) : this(element)
{
_LogSink = Logsink;
}
public override void Dispose()
{
base.Dispose();
}
protected override XmlReader GetReader() {
return _element.CreateReader();
}
}
}

View File

@@ -0,0 +1,16 @@
using System.Xml;
using HaXMLReader.Interfaces;
namespace HaXMLReader {
public class XmlReaderReader : Reader, IReader {
private XmlReader _initial;
public XmlReaderReader(XmlReader reader) {
_initial = reader;
}
protected override XmlReader GetReader() {
return _initial;
}
}
}