mirror of
https://github.com/Theodor-Springmann-Stiftung/hamann-ausgabe-core.git
synced 2025-10-29 01:05:32 +00:00
Added Search Page. Final Version for 1st internal relaese
This commit is contained in:
@@ -87,7 +87,8 @@ public class IndexController : Controller {
|
||||
}
|
||||
|
||||
|
||||
private List<(string Key, string Person)> _getAvailablePersons(ILibrary lib) {
|
||||
private List<(string Key, string Person)>? _getAvailablePersons(ILibrary lib) {
|
||||
if (!lib.Persons.Any()) return null;
|
||||
return lib.Persons
|
||||
.OrderBy(x => x.Value.Surname)
|
||||
.ThenBy(x => x.Value.Prename)
|
||||
@@ -153,8 +154,16 @@ public class IndexController : Controller {
|
||||
List<(string Volume, List<string> Pages)>? availablePages = null;
|
||||
availablePages = lib.Structure.Where(x => x.Key != "-1").Select(x => (x.Key, x.Value.Select(x => x.Key).ToList())).ToList();
|
||||
zhvolume = zhvolume == null ? "1" : zhvolume;
|
||||
var model = new IndexViewModel(letters, page, pages, _getAvailablePersons(lib), availablePages.OrderBy(x => x.Volume).ToList(), zhvolume, zhpage);
|
||||
if (person != null) model.ActivePerson = person;
|
||||
var model = new IndexViewModel(
|
||||
letters,
|
||||
page,
|
||||
pages,
|
||||
_getAvailablePersons(lib),
|
||||
availablePages.OrderBy(x => x.Volume).ToList(),
|
||||
zhvolume,
|
||||
zhpage,
|
||||
person
|
||||
);
|
||||
return View("~/Views/HKB/Dynamic/Index.cshtml", model);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ public class RegisterController : Controller {
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Forschung(string? id, string? search) {
|
||||
public IActionResult Forschung(string? id) {
|
||||
// Setup settings and variables
|
||||
var lib = _lib.GetLibrary();
|
||||
var url = "/HKB/Register/Forschung/";
|
||||
@@ -146,16 +146,6 @@ public class RegisterController : Controller {
|
||||
return View("~/Views/HKB/Dynamic/Register.cshtml", model);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[DisableFormValueModelBinding]
|
||||
[ValidateAntiForgeryToken]
|
||||
[Route("/HKB/Register/Forschung/{id}")]
|
||||
[Route("/HKB/Register/Register/{id}")]
|
||||
[Route("/HKB/Register/Bibelstellen/{id}")]
|
||||
public IActionResult Search(string? id) {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
private string? normalizeID(string? id, string defaultid) {
|
||||
if (id == null) return null;
|
||||
return id.ToUpper();
|
||||
|
||||
@@ -28,9 +28,6 @@ public class SucheController : Controller {
|
||||
if (search == null) return _error404();
|
||||
var lib = _lib.GetLibrary();
|
||||
|
||||
var stopwatch = new System.Diagnostics.Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
if (category == "letters") {
|
||||
if (String.IsNullOrWhiteSpace(search))
|
||||
return _paginateSendLetters(lib, page, search, SearchResultType.InvalidSearchTerm, null, null);
|
||||
@@ -46,13 +43,24 @@ public class SucheController : Controller {
|
||||
);
|
||||
var keys = res.Select(x => x.Index).Where(x => lib.Metas.ContainsKey(x)).Select(x => lib.Metas[x]);
|
||||
var letters = keys.ToLookup(x => x.Sort.Year).OrderBy(x => x.Key).ToList();
|
||||
return _paginateSendLetters(lib, page, search, SearchResultType.Success, ret, letters);
|
||||
} else if (category == " register") {
|
||||
|
||||
return _paginateSendLetters(lib, page, search, SearchResultType.Success, ret, letters);
|
||||
} else if (category == "register") {
|
||||
if (String.IsNullOrWhiteSpace(search))
|
||||
return _paginateSendRegister(lib, page, search, SearchResultType.InvalidSearchTerm, null);
|
||||
search = search.Trim();
|
||||
|
||||
List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? res = null;
|
||||
if (page == 0)
|
||||
res = _xmlService.SearchCollection("register-comments", search, _readerService);
|
||||
if (page == 1)
|
||||
res = _xmlService.SearchCollection("forschung-comments", search, _readerService);
|
||||
if (res == null || !res.Any())
|
||||
return _paginateSendRegister(lib, page, search, SearchResultType.NotFound, null);
|
||||
|
||||
return _paginateSendRegister(lib, page, search, SearchResultType.Success, _createComments("neuzeit", res.Select((x) => (x.Index, x.Results.Select((y) => y.Identifier).ToList())).OrderBy(x => x.Index).ToList()));
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
Console.WriteLine("SEARCH: " + stopwatch.ElapsedMilliseconds);
|
||||
return _error404();
|
||||
}
|
||||
|
||||
@@ -101,7 +109,7 @@ public class SucheController : Controller {
|
||||
if (pages != null && page >= pages.Count) return _error404();
|
||||
if (pages == null && page > 0) return _error404();
|
||||
List<(int Year, List<BriefeMetaViewModel> LetterList)>? letters = null;
|
||||
if (pages != null)
|
||||
if (pages != null && metasbyyear != null)
|
||||
letters = metasbyyear
|
||||
.Where(x => x.Key >= pages[page].StartYear && x.Key <= pages[page].EndYear)
|
||||
.Select(x => (x.Key, x
|
||||
@@ -110,10 +118,41 @@ public class SucheController : Controller {
|
||||
.ThenBy(x => x.Meta.Order)
|
||||
.ToList()))
|
||||
.ToList();
|
||||
var model = new SucheViewModel(SearchType.Letter, SearchResultType.Success, page, _paginate(pages), activeSearch, searchResults, letters);
|
||||
var model = new SucheViewModel("letters", SRT, page, _paginate(pages), activeSearch, searchResults, letters, null);
|
||||
return View("~/Views/HKB/Dynamic/Suche.cshtml", model);
|
||||
}
|
||||
|
||||
private IActionResult _paginateSendRegister(
|
||||
ILibrary lib,
|
||||
int page,
|
||||
string activeSearch,
|
||||
SearchResultType SRT,
|
||||
List<CommentModel> comments) {
|
||||
var model = new SucheViewModel("register", SRT, page, new List<string>() { "Allgmeines Register", "Forschungsbibliographie" }, activeSearch, null, null, comments);
|
||||
return View("~/Views/HKB/Dynamic/Suche.cshtml", model);
|
||||
}
|
||||
|
||||
|
||||
private List<CommentModel> _createComments(string category, List<(string, List<string>)>? comments) {
|
||||
var lib = _lib.GetLibrary();
|
||||
var res = new List<CommentModel>();
|
||||
if (comments == null) return res;
|
||||
foreach (var comm in comments) {
|
||||
var commobj = lib.Comments[comm.Item1];
|
||||
var parsedComment = HTMLHelpers.CommentHelpers.CreateHTML(lib, _readerService, commobj, category, Settings.ParsingState.CommentType.Comment);
|
||||
List<string>? parsedSubComments = new List<string>();
|
||||
var distinctList = comm.Item2.Distinct().ToList();
|
||||
foreach (var subcomm in distinctList) {
|
||||
if (subcomm != comm.Item1) {
|
||||
var subcommobj = lib.SubCommentsByID[subcomm];
|
||||
parsedSubComments.Add(HTMLHelpers.CommentHelpers.CreateHTML(lib, _readerService, subcommobj, category, Settings.ParsingState.CommentType.Subcomment));
|
||||
}
|
||||
}
|
||||
res.Add(new CommentModel(parsedComment, parsedSubComments));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private IActionResult _error404() {
|
||||
Response.StatusCode = 404;
|
||||
return Redirect("/Error404");
|
||||
|
||||
@@ -19,7 +19,8 @@ public class IndexViewModel {
|
||||
List<(string Key, string Name)>? availablePersons,
|
||||
List<(string Volume, List<string> Pages)>? availablePages,
|
||||
string? activeVolume,
|
||||
string? activePage
|
||||
string? activePage,
|
||||
string? activePerson
|
||||
) {
|
||||
Letters = letters;
|
||||
if (letters != null)
|
||||
@@ -32,5 +33,6 @@ public class IndexViewModel {
|
||||
AvailablePages = availablePages;
|
||||
ActiveVolume = activeVolume;
|
||||
ActivePage = activePage;
|
||||
ActivePerson = activePerson;
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,11 @@ using System.Collections.Generic;
|
||||
public class SearchResult {
|
||||
public string Search { get; private set; }
|
||||
public string Index { get; private set; }
|
||||
public string Identifier { get; set; }
|
||||
public string? Page { get; set; }
|
||||
public string? Line { get; set; }
|
||||
public string? Lemma { get; set; }
|
||||
public string? Link { get; set; }
|
||||
public string? Preview { get; set; }
|
||||
|
||||
// TODO:
|
||||
public string? ParsedPreview { get; set; }
|
||||
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
namespace HaWeb.Models;
|
||||
using HaDocument.Models;
|
||||
|
||||
public enum SearchType {
|
||||
Letter,
|
||||
Register,
|
||||
Marginals
|
||||
}
|
||||
|
||||
public enum SearchResultType {
|
||||
Success,
|
||||
OutOfBounds,
|
||||
@@ -16,22 +10,25 @@ public enum SearchResultType {
|
||||
|
||||
public class SucheViewModel {
|
||||
public List<(int Year, List<BriefeMetaViewModel> LetterList)>? Letters { get; private set; }
|
||||
public List<CommentModel>? Comments { get; private set; }
|
||||
|
||||
public int Count { get; private set; }
|
||||
public int ActivePage { get; private set; }
|
||||
public List<string>? AvailablePages { get; private set; }
|
||||
public string ActiveSearch { get; private set; }
|
||||
public Dictionary<string, List<SearchResult>>? SearchResults { get; private set; }
|
||||
public SearchResultType SearchResultType { get; private set; }
|
||||
public SearchType SearchType { get; private set; }
|
||||
public string SearchType { get; private set; }
|
||||
|
||||
public SucheViewModel(
|
||||
SearchType searchType,
|
||||
string searchType,
|
||||
SearchResultType searchResultType,
|
||||
int activePage,
|
||||
List<string>? availablePages,
|
||||
string activeSearch,
|
||||
Dictionary<string, List<SearchResult>>? searchResults,
|
||||
List<(int Year, List<BriefeMetaViewModel> LetterList)>? letters
|
||||
List<(int Year, List<BriefeMetaViewModel> LetterList)>? letters,
|
||||
List<CommentModel>? comments
|
||||
) {
|
||||
Letters = letters;
|
||||
if (letters != null)
|
||||
@@ -45,5 +42,6 @@ public class SucheViewModel {
|
||||
AvailablePages = availablePages;
|
||||
ActiveSearch = activeSearch;
|
||||
SearchResults = searchResults;
|
||||
Comments = comments;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,10 @@ using WhitespaceFuncList = List<(Func<HaXMLReader.EvArgs.Whitespace, HaWeb.HTMLP
|
||||
|
||||
|
||||
public class SearchRules {
|
||||
public static readonly TagFuncList OTagRules = new TagFuncList() {
|
||||
( (x, _) => x.Name.ToLower() == "kommentar" || x.Name.ToLower() == "subsection", (_, tag, reader) => reader.State.CurrentIdentifier = tag["id"]),
|
||||
};
|
||||
|
||||
public static readonly TextFuncList TextRules = new TextFuncList() {
|
||||
( (x, _) => true, (sb, text, reader) => {
|
||||
var t = text.Value;
|
||||
@@ -18,8 +22,8 @@ public class SearchRules {
|
||||
if (sb.Length >= sw.Length) {
|
||||
if (sb.ToString().ToUpperInvariant().Contains(sw)) {
|
||||
if (reader.State.Results == null)
|
||||
reader.State.Results = new List<(string Page, string Line)>();
|
||||
reader.State.Results.Add((reader.CurrentPage, reader.CurrentLine));
|
||||
reader.State.Results = new List<(string Page, string Line, string Identifier)>();
|
||||
reader.State.Results.Add((reader.CurrentPage, reader.CurrentLine, reader.State.CurrentIdentifier));
|
||||
}
|
||||
sb.Remove(0, sb.Length - sw.Length);
|
||||
}
|
||||
@@ -36,8 +40,8 @@ public class SearchRules {
|
||||
if (sb.Length >= sw.Length) {
|
||||
if (sb.ToString().Contains(sw)) {
|
||||
if (reader.State.Results == null)
|
||||
reader.State.Results = new List<(string Page, string Line)>();
|
||||
reader.State.Results.Add((reader.CurrentPage, reader.CurrentLine));
|
||||
reader.State.Results = new List<(string Page, string Line, string Identifier)>();
|
||||
reader.State.Results.Add((reader.CurrentPage, reader.CurrentLine, reader.State.CurrentIdentifier));
|
||||
}
|
||||
sb.Remove(0, sb.Length - sw.Length);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,9 @@ using System.Text;
|
||||
|
||||
public class SearchState : HaWeb.HTMLParser.IState {
|
||||
internal string SearchWord;
|
||||
internal string? CurrentIdentifier;
|
||||
internal bool Normalize;
|
||||
internal List<(string Page, string Line)>? Results;
|
||||
internal List<(string Page, string Line, string Identifier)>? Results;
|
||||
|
||||
public SearchState(string searchword, bool normalize = false) {
|
||||
Normalize = normalize;
|
||||
|
||||
@@ -91,7 +91,10 @@
|
||||
<div class="ha-filtertitle">
|
||||
Suche in Z H
|
||||
@if (Model.ActivePage != null) {
|
||||
<a class="ha-reversefilter" asp-controller="Index" asp-action="Index">← Auswahl aufheben</a>
|
||||
<div class="ha-activefilterinfo">
|
||||
Briefe auf ZH <span class="caps-allpeteite">@Model.ActiveVolume / @Model.ActivePage</span> 
|
||||
<a class="ha-reversefilter" asp-controller="Index" asp-action="Index">← Auswahl aufheben</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<form class="ha-zhform" id="ha-zhform">
|
||||
@@ -172,9 +175,14 @@
|
||||
@if(Model.AvailablePersons != null) {
|
||||
<div class="ha-personfilter">
|
||||
<div class="ha-filtertitle">
|
||||
Korrespondenzpartner:innen
|
||||
@if (Model.ActivePerson != null) {
|
||||
<a class="ha-reversefilter" asp-controller="Index" asp-action="Index">← Auswahl aufheben</a>
|
||||
<div>
|
||||
Korrespondenzpartner:innen
|
||||
</div>
|
||||
@if (Model.ActivePerson != null && Model.AvailablePersons.Where(x => x.Key == Model.ActivePerson).Any()) {
|
||||
<div class="ha-activefilterinfo">
|
||||
Briefe von und an @Model.AvailablePersons.Where(x => x.Key == Model.ActivePerson).First().Name. 
|
||||
<a class="ha-reversefilter" asp-controller="Index" asp-action="Index">← Auswahl aufheben</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="ha-personlist">
|
||||
|
||||
@@ -37,10 +37,36 @@
|
||||
</div>
|
||||
}
|
||||
@if (Model.AllowSearch) {
|
||||
<form asp-controller="Register" asp-action="Search" asp-route-id="@string.Empty" method="GET" >
|
||||
<form class="ha-searchform" id="ha-searchform" asp-controller="Suche" asp-action="Index" method="get">
|
||||
<input id="ha-searchformtext" name="search" type="text" placeholder="Suchbegriff"/>
|
||||
<input type="hidden" name="category" type="text" value="register"/>
|
||||
<input type="hidden" name="page" type="text" value="@(Model.Category == "forschung" ? "1" : "0")"/>
|
||||
<button id="ha-searchformsubmit" type="submit">Durchsuchen</button>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
const ACTIVATESEARCHFILTER = function(filter, button) {
|
||||
let f = filter.value;
|
||||
if (f === "") {
|
||||
button.disabled = true;
|
||||
return;
|
||||
}
|
||||
button.disabled = false;
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
let searchfilter = document.getElementById("ha-searchformtext");
|
||||
let searchsubmitbtn = document.getElementById("ha-searchformsubmit");
|
||||
let searchform = document.getElementById("ha-searchform");
|
||||
ACTIVATESEARCHFILTER(searchfilter, searchsubmitbtn);
|
||||
searchfilter.addEventListener("input", () => ACTIVATESEARCHFILTER(searchfilter, searchsubmitbtn));
|
||||
});
|
||||
</script>
|
||||
|
||||
@* <form asp-controller="Suche" asp-action="Index" method="GET" >
|
||||
<input type="text" name="search" placeholder="Suchbegriff" />
|
||||
<button type="submit">Suchen</button>
|
||||
</form>
|
||||
</form> *@
|
||||
}
|
||||
<div class="ha-register-nav" id="ha-register-nav">
|
||||
<div class="ha-register-left-nav">
|
||||
|
||||
@@ -2,63 +2,93 @@
|
||||
@{
|
||||
ViewData["Title"] = "Briefauswahl & Suche";
|
||||
ViewData["SEODescription"] = "Johann Georg Hamann: Kommentierte Briefausgabe, Hg. v. Leonard Keidel und Janina Reibold. Durchsuchbare Online-Ausgabe der Briefe von und an Johann Georg Hamann.";
|
||||
ViewData["showCredits"] = "true";
|
||||
ViewData["showCredits"] = "false";
|
||||
}
|
||||
|
||||
<div class="ha-search">
|
||||
@if (Model.Letters != null) {
|
||||
|
||||
<div class="ha-searchhead">
|
||||
<h1>Suche</h1>
|
||||
|
||||
@* Full-Text-Search *@
|
||||
<div class="ha-searchfilter">
|
||||
<div class="ha-filtertitle">
|
||||
@if (Model.ActiveSearch != null) {
|
||||
|
||||
<a class="ha-reversefilter" asp-controller="Suche" asp-action="index">← Auswahl aufheben</a>
|
||||
}
|
||||
</div>
|
||||
<form class="ha-searchform" id="ha-searchform" asp-controller="Suche" asp-action="Index" method="get">
|
||||
<input id="ha-searchformtext" name="search" type="text" placeholder="Suchbegriff" value="@Model.ActiveSearch"/>
|
||||
<button id="ha-searchformsubmit" type="submit">Suchen</button>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
const ACTIVATESEARCHFILTER = function(filter, button) {
|
||||
let f = filter.value;
|
||||
if (f === "") {
|
||||
button.disabled = true;
|
||||
return;
|
||||
}
|
||||
button.disabled = false;
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
let searchfilter = document.getElementById("ha-searchformtext");
|
||||
let searchsubmitbtn = document.getElementById("ha-searchformsubmit");
|
||||
let searchform = document.getElementById("ha-searchform");
|
||||
ACTIVATESEARCHFILTER(searchfilter, searchsubmitbtn);
|
||||
searchfilter.addEventListener("input", () => ACTIVATESEARCHFILTER(searchfilter, searchsubmitbtn));
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="ha-searchnav">
|
||||
@if (Model.AvailablePages != null && Model.AvailablePages.Any() && Model.AvailablePages.Count > 1) {
|
||||
@for(var i = 0; i < Model.AvailablePages.Count; i++) {
|
||||
<a class="@(Model.ActivePage == i ? "active" : "")" asp-route-search="@Model.ActiveSearch" asp-controller="Suche" asp-route-page="@i">
|
||||
<span>
|
||||
@Model.AvailablePages[i]
|
||||
</span>
|
||||
</a>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div class="ha-searchhead">
|
||||
<h1>Volltextsuche</h1>
|
||||
<div class="ha-searchfilter">
|
||||
<div class="ha-searchfilterinfo">
|
||||
Die Volltextsuche kann Brieftexte, Stellenkommentare, Forschungsbibliographie- und Registereinträge über Seiten- und Zeilengrenzen hinweg durchsuchen. Angezeigt werden dabei exakte Übereinstimmungen mit dem Suchbegriff. Von dieser Regel ausgenommen sind Abweichungen in der Groß- und Kleinschreibung.
|
||||
</div>
|
||||
@if (Model.ActiveSearch != null) {
|
||||
<div class="ha-activefilterinfo">
|
||||
@if (Model.SearchType == "letters") {
|
||||
<span>Biefe, die »@Model.ActiveSearch« enthalten. </span><br>
|
||||
}
|
||||
@if (Model.SearchType == "register") {
|
||||
<span>Registereinträge, die »@Model.ActiveSearch« enthalten. </span><br>
|
||||
<a class="ha-reversefilter" asp-controller="Register" asp-action="Allgemein">← Registerübersicht</a><span> / </span>
|
||||
}
|
||||
@if (Model.SearchType == "marginals") {
|
||||
<span>Stellenkommentare, die »@Model.ActiveSearch« enthalten. </span><br>
|
||||
}
|
||||
<a class="ha-reversefilter" asp-controller="Index" asp-action="Index">← Briefübersicht</a>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="ha-searchbody">
|
||||
<form class="ha-searchform" id="ha-searchform" asp-controller="Suche" asp-action="Index" method="get">
|
||||
<input id="ha-searchformtext" name="search" type="text" placeholder="Suchbegriff" value="@Model.ActiveSearch"/>
|
||||
<input type="hidden" name="category" type="text" value="@Model.SearchType"/>
|
||||
<button id="ha-searchformsubmit" type="submit">Suchen</button>
|
||||
</form>
|
||||
|
||||
<div class="ha-alternativesearches">
|
||||
@if (Model.SearchType != "letters") {
|
||||
<a asp-controller="Suche" asp-action="index" asp-route-search="@Model.ActiveSearch" asp-route-category="letters">
|
||||
Stattdessen Briefe nach »@Model.ActiveSearch« durchsuchen →
|
||||
</a>
|
||||
}
|
||||
@if (Model.SearchType != "register") {
|
||||
<a asp-controller="Suche" asp-action="index" asp-route-search="@Model.ActiveSearch" asp-route-category="register">
|
||||
Stattdessen Register & Bibliographie nach »@Model.ActiveSearch« durchsuchen →
|
||||
</a>
|
||||
}
|
||||
@if (Model.SearchType != "marginals") {
|
||||
<a asp-controller="Suche" asp-action="index" asp-route-search="@Model.ActiveSearch" asp-route-category="marginals">
|
||||
Stattdessen Stellenkommentare nach »@Model.ActiveSearch« durchsuchen →
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const ACTIVATESEARCHFILTER = function(filter, button) {
|
||||
let f = filter.value;
|
||||
if (f === "") {
|
||||
button.disabled = true;
|
||||
return;
|
||||
}
|
||||
button.disabled = false;
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
let searchfilter = document.getElementById("ha-searchformtext");
|
||||
let searchsubmitbtn = document.getElementById("ha-searchformsubmit");
|
||||
let searchform = document.getElementById("ha-searchform");
|
||||
ACTIVATESEARCHFILTER(searchfilter, searchsubmitbtn);
|
||||
searchfilter.addEventListener("input", () => ACTIVATESEARCHFILTER(searchfilter, searchsubmitbtn));
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="ha-searchnav">
|
||||
@if (Model.AvailablePages != null && Model.AvailablePages.Any() && Model.AvailablePages.Count > 1) {
|
||||
@for(var i = 0; i < Model.AvailablePages.Count; i++) {
|
||||
<a class="@(Model.ActivePage == i ? "active" : "")" asp-route-search="@Model.ActiveSearch" asp-controller="Suche" asp-route-page="@i" asp-route-category="@Model.SearchType">
|
||||
<span>
|
||||
@Model.AvailablePages[i]
|
||||
</span>
|
||||
</a>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ha-searchbody">
|
||||
|
||||
@* Letter Search *@
|
||||
@if (Model.Letters != null) {
|
||||
<div class="ha-letterlist">
|
||||
@* Letter Loop *@
|
||||
@foreach (var year in Model.Letters) {
|
||||
foreach (var letter in year.LetterList) {
|
||||
<div class="ha-letterlistentry">
|
||||
@@ -82,10 +112,23 @@
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="ha-filterlist">
|
||||
|
||||
@* Register Search *@
|
||||
@if (Model.SearchType == "register" && Model.Comments != null && Model.Comments.Any()) {
|
||||
<div class="ha-commentlist @(Model.ActivePage == 1 ? "ha-forschung" : "")">
|
||||
@foreach (var k in Model.Comments) {
|
||||
<div class="ha-comment">
|
||||
<div class="ha-headcomment">@Html.Raw(k.ParsedComment)</div>
|
||||
@if (k.ParsedSubComments != null ) {
|
||||
@foreach (var sk in k.ParsedSubComments) {
|
||||
<div class="ha-subcomment">@Html.Raw(sk)</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -18,7 +18,7 @@
|
||||
</a>
|
||||
|
||||
<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. 1955–1979]) 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><a asp-controller="Suche" asp-action="Index" class="dark:text-slate-50 text-hamannSlate-900">Startseite: Suche und Briefauswahl</a>
|
||||
<p><a asp-controller="Index" asp-action="Index" class="dark:text-slate-50 text-hamannSlate-900">Startseite: Suche und Briefauswahl</a>
|
||||
<p><a asp-controller="Edition" asp-action="Richtlinien" class="dark:text-slate-50 text-hamannSlate-900">Editionsrichtlinien</a>
|
||||
<p><a asp-controller="Edition" asp-action="Editionsgeschichte" class="dark:text-slate-50 text-hamannSlate-900">Editionsgeschichte</a>
|
||||
</div>
|
||||
|
||||
@@ -19,5 +19,5 @@ public interface IXMLService {
|
||||
public void UnUseProduction();
|
||||
public void SetInProduction();
|
||||
public void SetInProduction(XDocument document);
|
||||
public List<(string Index, List<(string Page, string Line, string Preview)> Results)>? SearchCollection(string collection, string searchword, IReaderService reader);
|
||||
public List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? SearchCollection(string collection, string searchword, IReaderService reader);
|
||||
}
|
||||
@@ -112,16 +112,16 @@ public class XMLService : IXMLService {
|
||||
_collectedProduction = ret.ToDictionary(x => x.Key, y => y.Value);
|
||||
}
|
||||
|
||||
public List<(string Index, List<(string Page, string Line, string Preview)> Results)>? SearchCollection(string collection, string searchword, IReaderService reader) {
|
||||
public List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? SearchCollection(string collection, string searchword, IReaderService reader) {
|
||||
if (!_collectedProduction.ContainsKey(collection)) return null;
|
||||
var searchableObjects = _collectedProduction[collection].Items;
|
||||
var res = new ConcurrentBag<(string Index, List<(string Page, string Line, string preview)> Results)>();
|
||||
var res = new ConcurrentBag<(string Index, List<(string Page, string Line, string preview, string identifier)> Results)>();
|
||||
var sw = StringHelpers.NormalizeWhiteSpace(searchword.Trim());
|
||||
Parallel.ForEach(searchableObjects, (obj) => {
|
||||
if (obj.Value.SearchText != null) {
|
||||
var state = new SearchState(sw);
|
||||
var rd = reader.RequestStringReader(obj.Value.SearchText);
|
||||
var parser = new HaWeb.HTMLParser.LineXMLHelper<SearchState>(state, rd, new StringBuilder(), null, null, null, SearchRules.TextRules, SearchRules.WhitespaceRules);
|
||||
var parser = new HaWeb.HTMLParser.LineXMLHelper<SearchState>(state, rd, new StringBuilder(), SearchRules.OTagRules, null, null, SearchRules.TextRules, SearchRules.WhitespaceRules);
|
||||
rd.Read();
|
||||
if (state.Results != null)
|
||||
res.Add((
|
||||
@@ -134,7 +134,8 @@ public class XMLService : IXMLService {
|
||||
.Where(y => y.Page == x.Page && y.Line == x.Line)
|
||||
.Select(x => x.Text)
|
||||
.FirstOrDefault(string.Empty)
|
||||
: ""
|
||||
: "",
|
||||
x.Identifier
|
||||
)).ToList()));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"StoredFilePathLinux": "/home/simon/Downloads/test/",
|
||||
"StoredFilePathWindows": "D:/test/",
|
||||
"StoredFilePathWindows": "C:/Users/simon/Downloads/test/",
|
||||
"FileSizeLimit": 52428800,
|
||||
"AvailableStartYear": 1700,
|
||||
"AvailableEndYear": 1800,
|
||||
|
||||
@@ -131,8 +131,12 @@
|
||||
@apply text-2xl pr-4 pl-1 mb-1 pb-1 pt-3 font-serif leading-none border-b border-gray-400
|
||||
}
|
||||
|
||||
.ha-index .ha-indexbody .ha-filterlist .ha-activefilterinfo {
|
||||
@apply font-sans text-sm bg-slate-200 px-1 rounded mt-1
|
||||
}
|
||||
|
||||
.ha-index .ha-indexbody .ha-filterlist .ha-reversefilter {
|
||||
@apply inline-block text-sm ml-2
|
||||
@apply inline-block text-right decoration-dotted underline hover:decoration-solid
|
||||
}
|
||||
|
||||
/* .ha-index .ha-indexbody .ha-filterlist .ha-gotofilter {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -37,6 +37,34 @@
|
||||
@apply bg-slate-100 dark:bg-zinc-900
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commenthead .ha-letlinks {
|
||||
@apply desktop:bg-slate-50 dark:bg-slate-900 dark:text-slate-50
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commenthead .ha-letlinks::before {
|
||||
@apply bg-hamannSlate-500 dark:bg-slate-500
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commenthead .ha-letlinks.ha-expanded-box {
|
||||
@apply shadow-md dark:shadow-lg
|
||||
}
|
||||
|
||||
.ha-search .ha-btn-collapsed-box {
|
||||
@apply hidden desktop:block absolute -top-[0.15rem] cursor-pointer mt-0.5
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-comment .ha-commenthead .ha-letlinks .ha-hkb {
|
||||
@apply text-slate-900 dark:text-white
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-comment .ha-commenthead .ha-letlinks a {
|
||||
@apply hover:text-hamannSlate-900 dark:hover:text-gray-200 no-underline hover:underline
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-comment .ha-commenthead .ha-letlinks {
|
||||
@apply text-slate-700 dark:text-white
|
||||
}
|
||||
|
||||
/* NON THEME RULES */
|
||||
.ha-search .ha-searchhead {
|
||||
@apply pt-9 md:pt-12 px-9 md:px-16 border-b-2
|
||||
@@ -58,8 +86,40 @@
|
||||
@apply border-b-4
|
||||
}
|
||||
|
||||
.ha-search .ha-searchhead .ha-searchfilter {
|
||||
@apply w-[34rem] mb-4 md:mb-7
|
||||
}
|
||||
|
||||
.ha-search .ha-searchhead .ha-searchfilter .ha-searchfilterinfo {
|
||||
@apply border p-2 mb-1.5 hyphenate text-sm
|
||||
}
|
||||
|
||||
.ha-search .ha-searchhead .ha-searchfilter .ha-searchform {
|
||||
@apply py-1 flex flex-row gap-x-2
|
||||
}
|
||||
|
||||
.ha-search .ha-searchhead .ha-searchfilter .ha-searchform input {
|
||||
@apply px-1 border grow min-w-0
|
||||
}
|
||||
|
||||
.ha-search .ha-searchhead .ha-searchfilter .ha-searchform button {
|
||||
@apply float-right px-2 border border-slate-200 hover:border-black disabled:bg-gray-200 disabled:hover:border-slate-200 disabled:text-gray-600
|
||||
}
|
||||
|
||||
.ha-search .ha-searchhead .ha-activefilterinfo {
|
||||
@apply font-sans text-base bg-slate-200 px-1 rounded my-1
|
||||
}
|
||||
|
||||
.ha-search .ha-searchhead .ha-reversefilter {
|
||||
@apply inline-block text-right decoration-dotted underline hover:decoration-solid
|
||||
}
|
||||
|
||||
.ha-search .ha-searchhead .ha-searchfilter .ha-alternativesearches a {
|
||||
@apply block text-base underline decoration-dotted hover:decoration-solid
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody {
|
||||
@apply pt-4 clear-both flex flex-row gap-x-4
|
||||
@apply pt-4 md:pr-[29rem] pb-9 md:pb-12 rounded-b-sm
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-letterlist {
|
||||
@@ -89,23 +149,6 @@
|
||||
button {
|
||||
@apply dark:!bg-zinc-900 dark:!border-zinc-800
|
||||
}
|
||||
|
||||
/* Old stuff
|
||||
.ha-search .ha-searchbody .ha-letterlist .ha-letterlistentry .ha-letterlistentryheader {
|
||||
@apply border-b flex flex-row py-1 px-2 bg-slate-100
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-letterlist .ha-letterlistentry .ha-letterlistentryheader .ha-letterlistautopsic {
|
||||
@apply text-3xl font-bold grow
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-letterlist .ha-letterlistentry .ha-letterlistentryheader .ha-letterlistpills {
|
||||
@apply grow-0
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-letterlist .ha-letterlistentry .ha-letterlistletterdata {
|
||||
@apply px-2 py-1
|
||||
} */
|
||||
|
||||
.ha-search .ha-searchbody .ha-letterlist .ha-letterlistentry .ha-letterlistsearchresults {
|
||||
|
||||
@@ -123,83 +166,96 @@
|
||||
@apply inline-block pl-4
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist {
|
||||
@apply hidden md:flex flex-col gap-y-5 pb-4 float-right max-w-lg basis-1/3 min-w-0 shrink
|
||||
.ha-search .ha-searchbody .ha-commentlist {
|
||||
@apply pt-2 md:pt-4 px-9 md:px-16 numeric-mediaeval font-serif
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-filtertitle {
|
||||
@apply text-2xl pr-4 pl-1 mb-1 pb-1 pt-3 font-serif leading-none border-b border-gray-400
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-reversefilter {
|
||||
@apply inline-block text-sm ml-2
|
||||
}
|
||||
|
||||
/* .ha-search .ha-searchbody .ha-filterlist .ha-gotofilter {
|
||||
@apply bg-slate-100
|
||||
} */
|
||||
|
||||
/* .ha-search .ha-searchbody .ha-filterlist .ha-gotofilter .ha-filtertitle {
|
||||
@apply inline-block border-none
|
||||
} */
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-gotofilter form {
|
||||
@apply font-sans py-1 pl-1 pr-2
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-gotofilter form .ha-gototext {
|
||||
@apply inline-block font-sans mr-2
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-gotofilter form input {
|
||||
@apply w-14 px-1 border
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-gotofilter form button {
|
||||
@apply float-right inline-block px-2 border bg-slate-50 disabled:bg-gray-200 border-slate-200 hover:border-black disabled:hover:border-slate-200 disabled:text-gray-600
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-zhsearchfilter .ha-zhform {
|
||||
@apply py-1 pl-1 pr-2
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-zhsearchfilter .ha-zhform > span {
|
||||
@apply whitespace-nowrap
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-zhsearchfilter .ha-zhform input {
|
||||
@apply w-14 px-1 border
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-zhsearchfilter .ha-zhform button {
|
||||
@apply float-right px-2 border bg-slate-50 border-slate-200 disabled:bg-gray-200 hover:border-black disabled:hover:border-slate-200 disabled:text-gray-600
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-zhsearchfilter .ha-zhform select {
|
||||
@apply px-1
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-searchfilter .ha-searchform {
|
||||
@apply py-1 pl-1 pr-2 flex flex-row gap-x-2
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-searchfilter .ha-searchform input {
|
||||
@apply px-1 border grow min-w-0
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-searchfilter .ha-searchform button {
|
||||
@apply float-right px-2 border border-slate-200 hover:border-black disabled:bg-gray-200 disabled:hover:border-slate-200 disabled:text-gray-600
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-personfilter .ha-personlist {
|
||||
@apply max-h-[23rem] overflow-y-auto overflow-x-hidden py-1 pl-1 mr-2
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-personfilter .ha-personlist a {
|
||||
@apply block px-3 !transition-none
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-filterlist .ha-personfilter .ha-personlist a:nth-child(odd) {
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-comment {
|
||||
@apply block mb-9 md:mb-12
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-comment a {
|
||||
@apply underline decoration-dotted hover:decoration-solid
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-comment .ha-headcomment {
|
||||
@apply desktop:relative block
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-comment .ha-subcomment {
|
||||
@apply desktop:relative block ml-8 mt-2
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-comment .ha-commenthead {
|
||||
@apply block
|
||||
}
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-comment .ha-commenthead .ha-lemma {
|
||||
@apply inline font-bold
|
||||
}
|
||||
|
||||
.ha-search
|
||||
.ha-searchbody
|
||||
.ha-forschung
|
||||
.ha-comment
|
||||
.ha-commenthead
|
||||
.ha-lemma {
|
||||
@apply inline font-normal;
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-forschung .ha-comment {
|
||||
@apply mb-4 md:mb-6 -indent-4 pl-4
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-comment .ha-commenthead .ha-letlinks {
|
||||
@apply inline-block font-normal text-xs md:text-sm leading-snug font-sans caps-allpetite ml-2 mt-1
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-comment .ha-commenthead .ha-letlinks::before {
|
||||
@apply absolute mt-1 top-[0.1rem] bottom-[0.1rem] left-0 w-0.5 content-['']
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist
|
||||
.ha-comment
|
||||
.ha-commenthead
|
||||
.ha-letlinks
|
||||
.ha-hkb {
|
||||
@apply inline
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist
|
||||
.ha-headcomment
|
||||
.ha-commenthead
|
||||
.ha-letlinks {
|
||||
@apply desktop:left-[48rem]
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist
|
||||
.ha-subcomment
|
||||
.ha-commenthead
|
||||
.ha-letlinks {
|
||||
@apply desktop:left-[46rem]
|
||||
}
|
||||
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-commenthead .ha-letlinks {
|
||||
@apply desktop:indent-0 desktop:top-0 desktop:w-80 desktop:block desktop:absolute pl-2
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-comment .ha-commenthead .ha-letlinks a {
|
||||
@apply hover:text-slate-900
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-headcomment .ha-btn-collapsed-box {
|
||||
@apply left-[47.6rem]
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-subcomment .ha-btn-collapsed-box {
|
||||
@apply left-[45.6rem]
|
||||
}
|
||||
|
||||
.ha-search .ha-searchbody .ha-commentlist .ha-btn-collapsed-box {
|
||||
@apply hidden desktop:block absolute -top-[0.15rem] cursor-pointer
|
||||
}
|
||||
|
||||
}
|
||||
@@ -52,6 +52,7 @@ const markactive_menu = function (element) {
|
||||
i = 0,
|
||||
len = all_links.length,
|
||||
full_path = location.href.split("#")[0].toLowerCase(); //Ignore hashes
|
||||
full_path = full_path.split("?")[0];
|
||||
|
||||
for (; i < len; i++) {
|
||||
if (all_links[i].parentNode.classList.contains("ha-topnav-dropdown")) {
|
||||
@@ -265,6 +266,7 @@ const showhidebutton = function (
|
||||
const collapseboxes = function () {
|
||||
overlappingcollapsebox(".ha-neuzeit .ha-letlinks", true);
|
||||
overlappingcollapsebox(".ha-forschung .ha-letlinks", true);
|
||||
overlappingcollapsebox(".ha-commentlist .ha-letlinks", true);
|
||||
overlappingcollapsebox(".ha-lettertext .ha-marginalbox", true);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user