Mehrfachnachweise sortieren und Unterdrückung bei gleicher Start- und Zitatseite

Markus S. hinzugefügt 14 Tagen her
unbeantwortet

Hallo liebes Forum,


ich bin gerade dabei, meine Dissertation fertigzustellen und habe hierfür bereits die letzten Tage über meinen selbst erstellten Zitationsstil überarbeitet. Im Moment hänge ich aber noch an folgenden Stellen:


1) Ich muss die Reihenfolge meiner Mehrfachnachweise überarbeiten. Im Moment steht diese noch auf "Reihenfolge der Zitierung", jedoch möchte ich sie wie folgt umstellen:


1.Gerichtsentscheidungen (Hier dann nach folgendem Muster: Gericht aufsteigend=> Datum aufsteigend => Fundstelle aufsteigend)


2.Sonstige Literatur (Hier dann nach folgendem Muster: Autor aufsteigend => Datum aufsteigend => Titel aufsteigend)


Ich habe für mein Unterfangen bereits die Suche bemüht und auch das Citavi Github durchforstet, aber nirgends eine Vorlage für eine solche Programmierung gefunden. Mit der benutzerdefinierten Sortierung schaffe ich das Ganze leider nicht, da ich keinen absoluten Vorrang der Gerichtsentscheidungen festsetzen kann. Ich könnte wohl noch eines der Freitextfelder hierfür verwenden, aber bei über 200 Entscheidungen ist das Bearbeiten eines Freitextfeldes ein Aufwand, den ich gerne vermeiden würde, wenn es auch anders geht.


Ich habe zudem versucht, die Standardsortierung, die beim Aktivieren der "Speziellen Sortierung" erscheint, für meine Zwecke umzubauen, aber leider führt das nicht zu den gewünschten Ergebnissen:


using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using SwissAcademic.Citavi;
using SwissAcademic.Citavi.Citations;
using SwissAcademic.Citavi.Metadata;
using SwissAcademic.Collections;

namespace SwissAcademic.Citavi.Comparers
{
	public class CustomCitationComparer
		:
		ICustomCitationComparerMacro
	{
		public int Compare(Citation x, Citation y)
		{
			/*
				This is an example of a custom sort macro that sorts all references of type 'internet document' on top of the bibliography.
				The internet documents themselves are sorted according to a different logic than the rest of the cited documents.
				Return values:
				0:					x is considered the same as y sorting-wise, so we cannot tell a difference based on the algorithm below
				> 0 (positive):		x should go after y, x is greater than y
				< 0 (negative):		x should go before y, x is less than
			*/

			//First we make sure we are comparing BibliographyCitations only
			var xBibliographyCitation = x as BibliographyCitation;
			var yBibliographyCitation = y as BibliographyCitation;

			if (xBibliographyCitation == null || yBibliographyCitation == null) return 0;
			var xReference = xBibliographyCitation.Reference;
			var yReference = yBibliographyCitation.Reference;
			if (xReference == null || yReference == null) return 0;


			//(1) 	Some comparers are predefined as static members of the CitationComparer class, see IntelliSense
			var defaultCitationComparer = CitationComparer.AuthorYearTitleOrNoAuthorThenTitleYearAscending;

			//(2)	You can also build citation comparers based on arbitrary reference properties ("fields")
			//(2a)	First, define a list of property sort descriptors of the reference type
			var sortDescriptors = new List<PropertySortDescriptor<Reference>>();
			sortDescriptors.Add(new PropertySortDescriptor<Reference>(ReferencePropertyDescriptor.Organizations, ListSortDirection.Ascending));
			sortDescriptors.Add(new PropertySortDescriptor<Reference>(ReferencePropertyDescriptor.Date, ListSortDirection.Ascending));
			sortDescriptors.Add(new PropertySortDescriptor<Reference>(ReferencePropertyDescriptor.Number, ListSortDirection.Ascending));
			//(2b)	Then, construct a new citation comparer using the list of sort descriptors
			var specialCitationComparer = new CitationComparer(sortDescriptors);

			//(3)	Or you can define something altogether NEW
			//e.g. first I want to see all Internet Documents, sorted by AuthorYearTitle, then all other reference types, sorted by year first, then author and title (see specialReferenceComparer above)

			if (xReference.ReferenceType == ReferenceType.CourtDecision && yReference.ReferenceType == ReferenceType.CourtDecision) return specialCitationComparer.Compare(x, y); //YearAuthorTitle
			if (xReference.ReferenceType == ReferenceType.CourtDecision && yReference.ReferenceType != ReferenceType.CourtDecision) return -1;
			if (xReference.ReferenceType != ReferenceType.CourtDecision && yReference.ReferenceType == ReferenceType.CourtDecision) return 1;

			return defaultCitationComparer.Compare(x, y);
		}
	}
}


2) Ich habe mir von Github diese Komponente zum Unterdrücken der ersten Seite bei gleicher Zitatseite besorgt, schaffe es aber nicht, die Suffixe der Ausgabeziele 3 und 4 anzuzeigen. Beispiel:


/445b8d24d2df8cd978a8b8c1fde4ac23


Wenn ich den Filter richtig verstehe, müsste das nun so aussehen: Birk, StuW 1989, 212 f.

Im Dokument selber sieht es aber so aus:

/36c6b9a61ba50ed42653c8e2b853151d


Die Komponente sieht wie folgt aus:


/3f2a2716cddf196aa81459d261022c91


/1632b5d6fc1c18243eec59da2a53ef55


Vielleicht kann mir ja jemand weiterhelfen :)


Beste Grüße

Markus

Kommentare (2)

Foto
2

Hallo Markus,

vielen Dank für Ihre Frage.

1) Sortierung innerhalb von Mehrfachnachweisen

Wenn Sie Ihren Stil mit dem Zitationsstil-Editor öffnen (s. Handbuch), können Sie dort unter Datei > Eigenschaften des Zitationsstils > Mehrfach-Nachweise > Abschnitt: In Fußnoten > Sortierung: Spezielle Sortierung wählen und dann auf "Programmieren" klicken, um ein Sortierskript einzufügen.

Da wir kein fertiges Skript für diesen individuellen Anwendungsfall haben und wir momentan auch für kostenpflichtige Individualprogrammierungen keine Entwicklerressourcen haben, müssten Sie das Skript allerdings selbst erstellen.

Dabei könnten Sie dieses vorhandene Skript nutzen, das die Gerichtsurteile nach Instanz sortieren kann.

Alternativ können Sie auch die folgende Mehrfachnachweis-Sortierung eines findigen Nutzers testen: https://support.citavi.com/forum/viewtopic.php?f=163&t=18610#p69525

2) Unterdrücken der ersten Seite bei gleicher Zitatseite über ein Komponentenskript

Beim COT004-Skript können Sie in Zeile 92 bis 94 bestimmen, von welcher der beiden Elemente innerhalb der kombinierten Komponente die Präfix- und Suffix-Einstellungen übernommen werden:

//Alles unterdrücken ausser QuotationPageRangeFieldElement - wichtig: Eine der beiden TransferSettings-Zeilen muss immer durch vorangestellte //-Schrägstriche auskommentiert sein!
//TransferSettings(quotationPageRangeFieldElement, pageRangeFieldElement);	//diese Reihenfolge verwenden, wenn die Präfixe der Zitatseiten-Komponente angezeigt werden sollen 
TransferSettings(pageRangeFieldElement, quotationPageRangeFieldElement);	//diese Reihenfolge verwenden, wenn die Präfixe der Seitenbereichs-Komponente angezeigt werden sollen
Um das von Ihnen gewünschte Ziel zu erreichen, müssten Sie also die beiden Schrägstriche zu Beginn der Zeile 93 entfernen und dafür zu Beginn der Zeile 94 wieder einfügen.

Viele Grüße

Susanne

Foto
1

Hallo Susanne,

vielen Dank für die Antwort und bitte entschuldigen Sie die verspätete Rückmeldung - warum auch immer wurden mir in der Übersicht die Kommentare angezeigt, aber beim Draufklicken tauchte nur mein Eingangsbeitrag auf ohne die Antworten...


Wie dem auch sei: Für die entsprechende Filterung der Seitenausgabe habe ich die Komponentenfilterung entsprechend angepasst. Besten Dank für den Hinweis - das hatte ich schlicht übersehen.

Hinsichtlich der Nachweissortierung: Kann ich also die Skripten zur Sortierung des Literaturverzeichnisses auch für die Sortierung in einem Mehrfachnachweis verwenden?


Beste Grüße

Markus

Foto
1

Hallo Markus,

vielen Dank für Ihre Rückfrage.

Normalerweise wird für beides (Sortierung des Literaturverzeichnisses sowie die Sortierung innerhalb von Mehrfachnachweisen) jeweils ein eigenes Skript benötigt.

In dem Fall finden Sie aber zu Beginn des BSO005-Skripts folgenden Kommentar:

// Dieses Script kann sowohl zur Sortierung des Literaturverzeichnisses
// als auch von Mehrfachnachweisen im Text und in der Fußnote eingesetzt werden.

Viele Grüße

Susanne

Foto
Foto
2

Ob ich sonderlich findig bin, weiß ich nicht, aber jedenfalls bin ich der besagte Nutzer. Die Sortierung ist relativ einfach, aber ein paar Fragen stellen sich schon.

1. Sind die Gerichtsentscheidungen alle aus Deutschland?

2. Falls nicht, wie kann automatisiert erkannt werden, dass die Entscheidung aus einem Land stammt, dessen Gerichtsentscheidungen nicht in der mit D vergleichbaren Art zitiert werden (etwa Nachweis über Style of Cause statt Gericht+Datum+Az.)?

3. Soll innerhalb der Mehrfachnachweise auch automatisch nach Dokumenttyp sortiert werden?

4. Falls ja, soll jeder Dokumenttyp für sich sortiert werden, oder reicht eine Reihenfolge à la 1. Gesetze, 2. Gerichtsentscheidungen, 3. alles andere

5. Sollen die Gerichte streng alphabetisch sortiert werden, oder soll es hierarchisch sein, etwa 1. BVerfG, 2. RG, 3. BGH, 4. Ob. GH Brit. Z., 5. Bay. Ob. LG, 6. OLGS/KG, etc? Wie soll mit der unordentlichen Gerichtsbarkeit umgegangen werden?

Hier ist beispielhaft meine Hierarchie:

// Oberste Bundesgerichte
			
			else if (court.Equals("Cons. d'État")) return "ca";
			else if (court.Equals("Cass.")) return "cba";
			else if (court.Equals("Cass. ass. plén.")) return "cbb";
			else if (court.Equals("Cass. 1ère")) return "cbb";
			else if (court.Equals("Cass. 2ème")) return "cbb";
			else if (court.Equals("Cass. Com.")) return "cbc";
			
			else if (court.Equals("BVerfG")) return "ca";
			else if (court.Equals("RG")) return "cab";
			else if (court.Equals("BGH")) return "cb";
			else if (court.Equals("BVerwG")) return "cc";
			else if (court.Equals("BAG")) return "cd";
			else if (court.Equals("BFG")) return "ce";
			else if (court.Equals("BSG")) return "cf";
			
			else if (court.Equals("HR")) return "ca";
			else if (court.Equals("PHR")) return "cab";
			
			// Bundesobergerichte
			
			else if (court.Equals("BPatg")) return "da";

			// Landesverfassungsgerichte
			
			else if (court.Contains("LVerfG")) return "dn";
			
			// Bayerisches Oberstes Landesgericht
			
			else if (court.Contains("Bay. Ob. LG")) return "do";
			
			// Landesobergerichte
			
			else if (court.Contains("CA")) return "ea";
			
			else if (court.Contains("OLG") || court.Contains("KG")) return "ea";
			else if (court.Contains("OVG") || court.Contains("VGH")) return "eb";
			else if (court.Contains("LArbG")) return "ec";
			else if (court.Contains("LFG")) return "ed";
			else if (court.Contains("LSG")) return "ee";
			
			else if (court.Contains("Rechtbank")) return "ea";
			
			// Landesgerichte mit allgemeiner Zustaendigkeit
			
			else if (court.Contains("LG")) return "fa";
			else if (court.Contains("VG")) return "fb";
			else if (court.Contains("ArbG")) return "fc";
			else if (court.Contains("FG")) return "fd";
			else if (court.Contains("LSG")) return "fe";
			
			// Amtsgerichte
			
			else if (court.Contains("AG")) return "ge";
			
			return "zz";

5. Dito mit Fundstellen. Alphabetisch, oder gibt es eine andere Hierarchie?

Foto
1

Guten Abend,

auch Ihnen vielen Dank für Ihren Beitrag. Ich habe mir von Github Ihr Sortierskript besorgt, steige aber noch nicht so recht durch. Verstehe ich den dahinterstehenden Ansatz richtig: Im Skript wird eine Rangfolge erstellt ("ca", "aa", etc.), anhand derer die Gerichtsentscheidung sortiert werden?


Zu den Fragen: Ich würde die Mehrfachnachweise gerne wie folgt sortieren:


1.1 Entscheidungen der Bundesgerichte (hier habe ich BFH, BGH, BVerfG, BVerwg)


1.1.1 Zunächst alphabetisch nach dem Gericht

1.1.2 Im Anschluss aufsteigend nach dem Datum der Entscheidung


1.2 Entscheidungen der untergeordneten Gerichte (hier habe ich FG, OLG, OVG, VerfGH)


1.2.1 Zunächst alphabetisch nach dem Gericht


1.2.2 Im Anschluss aufsteigend nach dem Datum der Entscheidung


2. Hier nun die restlichen Dokumententypen

2.1 Zunächst alphabetisch nach Autor

2.2 Danach aufsteigend nach dem Datum des Dokuments

2.3. Und schließlich aufsteigend nach dem Titel


Es handelt sich ausschließlich um Entscheidungen deutscher Gerichte,


Beste Grüße

Markus

Foto
2

Ich hab doch gar kein Sortierskript auf Github hochgeladen?

Foto
2

Frage 3 und 4 sind noch nicht beantwortet. Theoretisch wäre es übrigens auch möglich, dass in einem Mehrfachnachweis die selbe Entscheidung mehrfach zitiert wird (Parallelfundstellen). Das kann Citavi auch machen (ich komme allerdings nicht umhin festzustellen, dass der Verfasser mich entgegen der Ankündigung in der Danksagung seiner Dissertation nicht erwähnt hat, vielleicht ist es also doch nicht so leicht, das einzubauen, wie ich das empfinde). Wenn man das mit den Parallelfundstellen macht, muss man noch als weiteres Kriterium nach den Fundstellen sortieren.

Jedenfalls sollte der folgende Code das gewünschte machen, unter der Voraussetzung, dass für Gerichte die Abkürzungsfelder genutzt werden.

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using SwissAcademic.Citavi;
using SwissAcademic.Citavi.Citations;
using SwissAcademic.Citavi.Metadata;
using SwissAcademic.Collections;

namespace SwissAcademic.Citavi.Comparers
{
	public class CustomCitationComparer
			:
			ICustomCitationComparerMacro
	{
		public int Compare(Citation x, Citation y)
		{
			var defaultCitationComparer = new DefaultCustomCitationComparer();

			return defaultCitationComparer.Compare(x, y);
		}
	}
	class DefaultCustomCitationComparer	: ICustomCitationComparerMacro
	{
		public int Compare(Citation x, Citation y)
		{
			var xReference = x.Reference;
			var yReference = y.Reference;

			if (xReference == null || yReference == null) return 0;

			string xCriterionOne;
			string xCriterionTwo;
			string xCriterionThree;
			string xCriterionFour;
			string xCriterionFive;

			string yCriterionOne;
			string yCriterionTwo;
			string yCriterionThree;
			string yCriterionFour;
			string yCriterionFive;

			GetCriteria(xReference, out xCriterionOne, out xCriterionTwo, out xCriterionThree, out xCriterionFour, out xCriterionFive);
			GetCriteria(yReference, out yCriterionOne, out yCriterionTwo, out yCriterionThree, out yCriterionFour, out yCriterionFive);

			if (xCriterionOne != yCriterionOne)
			{
				return xCriterionOne.CompareTo(yCriterionOne);
			}
			else if (xCriterionTwo != yCriterionTwo)
			{
				return xCriterionTwo.CompareTo(yCriterionTwo);
			}
			else if (xCriterionThree != yCriterionThree)
			{
				return xCriterionThree.CompareTo(yCriterionThree);
			}
			else if (xCriterionFour != yCriterionFour)
			{
				return xCriterionFour.CompareTo(yCriterionFour);
			}
			else if (xCriterionFive != yCriterionFive)
			{
				return xCriterionFive.CompareTo(yCriterionFive);
			}
			else
			{
				return 0;
			}
		}
		private void GetCriteria(Reference reference, out string criterionOne, out string criterionTwo, out string criterionThree, out string criterionFour, out string criterionFive)
		{
			criterionOne = GetCriterionOne(reference);
			criterionTwo = GetCriterionTwo(reference);
			criterionThree = GetCriterionThree(reference);;
			criterionFour = GetCriterionFour(reference);
			criterionFive = GetCriterionFive(reference);
			return;
		}
		private string GetCriterionOne(Reference reference)
		{
			string criterion = "0";
			return criterion;
		}
		private string GetCriterionTwo(Reference reference)
		{
			string criterion = "";

			if (reference.ReferenceType == ReferenceType.StatuteOrRegulation || reference.ReferenceType == ReferenceType.CourtDecision)
			{
			
			}
			else			
			{
				IList<Person> authorsOrEditorsOrOrganizations = reference.AuthorsOrEditorsOrOrganizations as IList<Person>;
				if (authorsOrEditorsOrOrganizations == null) return "0";
				
				foreach (Person authorOrEditorOrOrganization in authorsOrEditorsOrOrganizations)
				{				
					if (!string.IsNullOrEmpty(authorOrEditorOrOrganization.LastNameForSorting))
					{
						criterion += authorOrEditorOrOrganization.LastNameForSorting;
					}
					else
					{
						criterion += authorOrEditorOrOrganization.LastName;
					}
					criterion += authorOrEditorOrOrganization.FirstName;
				}				
			}
			return criterion;
		}
		private string GetCriterionThree(Reference reference)
		{
			string criterion = "";
			if (reference.ReferenceType == ReferenceType.CourtDecision) criterion = GetCriterionThreeCourtDecision(reference);
			return criterion;
		}
		private string GetCriterionThreeCourtDecision(Reference reference)
		{
			if (reference.ReferenceType != ReferenceType.CourtDecision) return "0";
			string criterion = "0";

			IList<Person> courts = reference.Organizations as IList<Person>;
			if (courts == null) return "0";

			Person court = courts.FirstOrDefault();
			if (court == null) return "0";

			string jurisdiction = court.LastNameForSorting;
			if (string.IsNullOrEmpty(jurisdiction)) return "0";

			string theCourt = string.Empty;

			if (!string.IsNullOrEmpty(court.Abbreviation))
			{
				if (!string.IsNullOrEmpty(theCourt)) theCourt += ", ";
				theCourt += court.Abbreviation;
			}
			else if (!string.IsNullOrEmpty(court.LastName))
			{
				if (!string.IsNullOrEmpty(theCourt)) theCourt += ", ";
				theCourt += court.LastName;
			}
			criterion = GetCourtRanking(theCourt);
			
			return criterion;
		}
		private string GetCriterionFour(Reference reference)
		{
			string criterion = "";
			if (!String.IsNullOrEmpty(reference.Date.ToStringSafe())) criterion = reference.Date.ToStringSafe();
			else criterion = reference.YearResolved.ToStringSafe();
			return criterion;
		}
		private string GetCriterionFive(Reference reference)
		{
			string criterion = "";
			if (reference.ReferenceType == ReferenceType.CourtDecision)
			{
				criterion = GetPeriodicalRanking(reference);
			}
			else criterion = reference.Title + reference.Subtitle;
			return criterion;
		}
		private string GetCourtRanking(string court)
		{
			if (string.IsNullOrEmpty(court)) return "zz";

			// Oberste Bundesgerichte		

			else if (court.Equals("BVerfG")) return "a" + court;
			else if (court.Equals("RG")) return "a" + court;
			else if (court.Equals("BGH")) return "a" + court;
			else if (court.Equals("BVerwG")) return "a" + court;
			else if (court.Equals("BAG")) return "a" + court;
			else if (court.Equals("BFG")) return "a" + court;
			else if (court.Equals("BSG")) return "a" + court;

			// Bundesobergerichte

			else if (court.Equals("BPatg")) return "b" + court;

			// Landesverfassungsgerichte

			else if (court.Contains("LVerfG")) return "c" + court;

			// Bayerisches Oberstes Landesgericht

			else if (court.Contains("Bay. Ob. LG")) return "d" + court;

			// der ganze übrige Gedönsrat;
			
			else return "e" + court;

			return "zz";
		}
		private string GetPeriodicalRanking(Reference reference)
		{
			string periodicalString = string.Empty;

			if (reference.Periodical == null) return "0";

			if (!string.IsNullOrEmpty(reference.Periodical.StandardAbbreviation))
			{
				periodicalString = reference.Periodical.StandardAbbreviation;
			}
			else if (!string.IsNullOrEmpty(reference.Periodical.FullName))
			{
				periodicalString = reference.Periodical.FullName;
			}

			if (string.IsNullOrEmpty(periodicalString)) return "zz";
			
			// Offizielle Entscheidungssammlungen vor anderen Fundstellen

			else if (periodicalString.Contains("BGHZ")) return "aa";
			else if (periodicalString.Contains("BVerfGE")) return "aa";

			else return "zz";
		}		
	}
}

Foto
1

@SirPounce Bezüglich Github: Sie sind doch jay-squared aus dem alten Forum, oder?


Bezüglich der Fragen 3 und 4: Wie oben bereits beschrieben, soll innerhalb der Mehrfachnachweise die Gerichtsentscheidung nach dem beschriebenen Muster vorangestellt werden und sodann die restlichen Dokumententypen nach Autor aufsteigend => Dokumententyp aufsteigend => Jahr aufsteigend => Titel aufsteigend sortiert werden. Also zB so:


BVerfGE ...; Autor 1, Beitrag in Gesetzeskommentar; Autor 1, Zeitschriftenaufsatz; Autor 2, Beitrag in Sammelwerk, Jahr 1; Autor 2, Beitrag in Sammelwerk, Jahr 2

Das obige Skript habe ich eingefügt und für meine Bedürfnisse leicht angepasst:

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using SwissAcademic.Citavi;
using SwissAcademic.Citavi.Citations;
using SwissAcademic.Citavi.Metadata;
using SwissAcademic.Collections;

namespace SwissAcademic.Citavi.Comparers
{
	public class CustomCitationComparer
			:
			ICustomCitationComparerMacro
	{
		public int Compare(Citation x, Citation y)
		{
			var defaultCitationComparer = new DefaultCustomCitationComparer();

			return defaultCitationComparer.Compare(x, y);
		}
	}
	class DefaultCustomCitationComparer	: ICustomCitationComparerMacro
	{
		public int Compare(Citation x, Citation y)
		{
			var xReference = x.Reference;
			var yReference = y.Reference;

			if (xReference == null || yReference == null) return 0;

			string xCriterionOne;
			string xCriterionTwo;
			string xCriterionThree;
			string xCriterionFour;
			string xCriterionFive;

			string yCriterionOne;
			string yCriterionTwo;
			string yCriterionThree;
			string yCriterionFour;
			string yCriterionFive;

			GetCriteria(xReference, out xCriterionOne, out xCriterionTwo, out xCriterionThree, out xCriterionFour, out xCriterionFive);
			GetCriteria(yReference, out yCriterionOne, out yCriterionTwo, out yCriterionThree, out yCriterionFour, out yCriterionFive);

			if (xCriterionOne != yCriterionOne)
			{
				return xCriterionOne.CompareTo(yCriterionOne);
			}
			else if (xCriterionTwo != yCriterionTwo)
			{
				return xCriterionTwo.CompareTo(yCriterionTwo);
			}
			else if (xCriterionThree != yCriterionThree)
			{
				return xCriterionThree.CompareTo(yCriterionThree);
			}
			else if (xCriterionFour != yCriterionFour)
			{
				return xCriterionFour.CompareTo(yCriterionFour);
			}
			else if (xCriterionFive != yCriterionFive)
			{
				return xCriterionFive.CompareTo(yCriterionFive);
			}
			else
			{
				return 0;
			}
		}
		private void GetCriteria(Reference reference, out string criterionOne, out string criterionTwo, out string criterionThree, out string criterionFour, out string criterionFive)
		{
			criterionOne = GetCriterionOne(reference);
			criterionTwo = GetCriterionTwo(reference);
			criterionThree = GetCriterionThree(reference);;
			criterionFour = GetCriterionFour(reference);
			criterionFive = GetCriterionFive(reference);
			return;
		}
		private string GetCriterionOne(Reference reference)
		{
			string criterion = "0";
			return criterion;
		}
		private string GetCriterionTwo(Reference reference)
		{
			string criterion = "";

			if (reference.ReferenceType == ReferenceType.StatuteOrRegulation || reference.ReferenceType == ReferenceType.CourtDecision)
			{
			
			}
			else			
			{
				IList<Person> authorsOrEditorsOrOrganizations = reference.AuthorsOrEditorsOrOrganizations as IList<Person>;
				if (authorsOrEditorsOrOrganizations == null) return "0";
				
				foreach (Person authorOrEditorOrOrganization in authorsOrEditorsOrOrganizations)
				{				
					if (!string.IsNullOrEmpty(authorOrEditorOrOrganization.LastNameForSorting))
					{
						criterion += authorOrEditorOrOrganization.LastNameForSorting;
					}
					else
					{
						criterion += authorOrEditorOrOrganization.LastName;
					}
					criterion += authorOrEditorOrOrganization.FirstName;
				}				
			}
			return criterion;
		}
		private string GetCriterionThree(Reference reference)
		{
			string criterion = "";
			if (reference.ReferenceType == ReferenceType.CourtDecision) criterion = GetCriterionThreeCourtDecision(reference);
			return criterion;
		}
		private string GetCriterionThreeCourtDecision(Reference reference)
		{
			if (reference.ReferenceType != ReferenceType.CourtDecision) return "0";
			string criterion = "0";

			IList<Person> courts = reference.Organizations as IList<Person>;
			if (courts == null) return "0";

			Person court = courts.FirstOrDefault();
			if (court == null) return "0";

			string jurisdiction = court.LastNameForSorting;
			if (string.IsNullOrEmpty(jurisdiction)) return "0";

			string theCourt = string.Empty;

			if (!string.IsNullOrEmpty(court.Abbreviation))
			{
				if (!string.IsNullOrEmpty(theCourt)) theCourt += ", ";
				theCourt += court.Abbreviation;
			}
			else if (!string.IsNullOrEmpty(court.LastName))
			{
				if (!string.IsNullOrEmpty(theCourt)) theCourt += ", ";
				theCourt += court.LastName;
			}
			criterion = GetCourtRanking(theCourt);
			
			return criterion;
		}
		private string GetCriterionFour(Reference reference)
		{
			string criterion = "";
			if (!String.IsNullOrEmpty(reference.Date.ToStringSafe())) criterion = reference.Date.ToStringSafe();
			else criterion = reference.YearResolved.ToStringSafe();
			return criterion;
		}
		private string GetCriterionFive(Reference reference)
		{
			string criterion = "";
			if (reference.ReferenceType == ReferenceType.CourtDecision)
			{
				criterion = GetPeriodicalRanking(reference);
			}
			else criterion = reference.Title + reference.Subtitle;
			return criterion;
		}
		private string GetCourtRanking(string court)
		{
			if (string.IsNullOrEmpty(court)) return "zz";

			// Oberste Bundesgerichte		

			else if (court.Equals("BFH")) return "a" + court;
			else if (court.Equals("BGH")) return "a" + court;
			else if (court.Equals("BVerfG")) return "a" + court;
			else if (court.Equals("BVerwG")) return "a" + court;
			

			// Landesverfassungsgerichte und Landesverwaltungsgerichtshöfe

			else if (court.Equals("BayVGH")) return "b" + court;
			else if (court.Equals("OVG Koblenz")) return "b" + court;
			else if (court.Equals("VerfGH NRW")) return "b" + court;
			else if (court.Equals("VerfGH Rheinland-Pfalz")) return "b" + court;

			// Finanzgerichte

			else if (court.Contains("FG Baden-Württemberg")) return "c" + court;
			else if (court.Contains("FG Düsseldorf")) return "c" + court;
			else if (court.Contains("FG Schleswig-Holstein")) return "c" + court;

			// Landgerichte

			else if (court.Contains("LG Köln")) return "d" + court;

			// der ganze übrige Gedönsrat;
			
			else return "e" + court;

			return "zz";
		}
		private string GetPeriodicalRanking(Reference reference)
		{
			string periodicalString = string.Empty;

			if (reference.Periodical == null) return "0";

			if (!string.IsNullOrEmpty(reference.Periodical.StandardAbbreviation))
			{
				periodicalString = reference.Periodical.StandardAbbreviation;
			}
			else if (!string.IsNullOrEmpty(reference.Periodical.FullName))
			{
				periodicalString = reference.Periodical.FullName;
			}

			if (string.IsNullOrEmpty(periodicalString)) return "zz";
			
			// Offizielle Entscheidungssammlungen vor anderen Fundstellen

			else if (periodicalString.Contains("BGHZ")) return "aa";
			else if (periodicalString.Contains("BVerfGE")) return "aa";
			else if (periodicalString.Contains("BFHE")) return "aa";
			else if (periodicalString.Contains("BVerwGE")) return "aa";
			else return "zz";
		}		
	}
}


Zum Testen haben ich eine neue Word-Datei erzeugt und einen Mehrfachnachweis erstellt. Dieser müsste so aussehen:

/eb2ba201effb189aee784e5e149799a6

Mit obigem Skript kommt aber folgende Sortierung raus:


/eeb5d3a30e971ac830a93cc1978d3adb

Es sieht für mich fast so aus, als würde Citavi in die falsche RIchtung sortieren...


PS: Parallelfundestellen spielen für mich keine Rolle.

Foto
2

Stimmt, ich hatte das doch auf Github hochgeladen. Ups. Das Skript funktioniert deshalb nicht, weil es nachguckt, ob für Gerichte die "Jurisdiktion" im Feld "Sortieren nach" eingetragen ist. Das ist mein Missbrauch des Feldes, um Entscheidungen nach Herkunft zu sortieren (nach Bundesland, oder nach Land überhaupt, etc.). Wenn das Feld leer ist, sortiert das Skript Entscheidungen gar nicht. Ich hab das mal rausgenommen und den Code insgesamt vereinfacht (zum Beispiel ist die Sortierung nach Fundstelle ja auch egal, wenn eh keine Parallelfundstellen drin sind) und kommentiert. Ich würde darauf hinweisen, dass es nicht nötig ist, jedes Gericht einzeln in der Gerichtshierarchie aufzuführen, da nur danach geguckt wird, ob "VGH", "FG", etc. in der Abkürzung, oder wenn diese leer ist, im vollen Namen des Gerichts vorkommt (contains), es wird keine volle Identitätsprüfung gemacht (equals).


using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using SwissAcademic.Citavi;
using SwissAcademic.Citavi.Citations;
using SwissAcademic.Citavi.Metadata;
using SwissAcademic.Collections;

namespace SwissAcademic.Citavi.Comparers
{
	public class CustomCitationComparer
			:
			ICustomCitationComparerMacro
	{
		public int Compare(Citation x, Citation y)
		{
			var defaultCitationComparer = new DefaultCustomCitationComparer();

			return defaultCitationComparer.Compare(x, y);
		}
	}
	class DefaultCustomCitationComparer	: ICustomCitationComparerMacro
	{
		public int Compare(Citation x, Citation y)
		{
			var xReference = x.Reference;
			var yReference = y.Reference;

			if (xReference == null || yReference == null) return 0;

			string xCriterionOne;
			string xCriterionTwo;
			string xCriterionThree;
			string xCriterionFour;
			string xCriterionFive;

			string yCriterionOne;
			string yCriterionTwo;
			string yCriterionThree;
			string yCriterionFour;
			string yCriterionFive;

			GetCriteria(xReference, out xCriterionOne, out xCriterionTwo, out xCriterionThree, out xCriterionFour, out xCriterionFive);
			GetCriteria(yReference, out yCriterionOne, out yCriterionTwo, out yCriterionThree, out yCriterionFour, out yCriterionFive);

			if (xCriterionOne != yCriterionOne)
			{
				return xCriterionOne.CompareTo(yCriterionOne);
			}
			else if (xCriterionTwo != yCriterionTwo)
			{
				return xCriterionTwo.CompareTo(yCriterionTwo);
			}
			else if (xCriterionThree != yCriterionThree)
			{
				return xCriterionThree.CompareTo(yCriterionThree);
			}
			else if (xCriterionFour != yCriterionFour)
			{
				return xCriterionFour.CompareTo(yCriterionFour);
			}
			else if (xCriterionFive != yCriterionFive)
			{
				return xCriterionFive.CompareTo(yCriterionFive);
			}
			else
			{
				return 0;
			}
		}
		private void GetCriteria(Reference reference, out string criterionOne, out string criterionTwo, out string criterionThree, out string criterionFour, out string criterionFive)
		{
			criterionOne = GetCriterionOne(reference);
			criterionTwo = GetCriterionTwo(reference);
			criterionThree = GetCriterionThree(reference);;
			criterionFour = GetCriterionFour(reference);
			criterionFive = GetCriterionFive(reference);
			return;
		}
		private string GetCriterionOne(Reference reference)
		{
			// Als erstes werden Gerichtsentscheidungen nach vorne gezogen.
			string criterion = "0";
			if (reference.ReferenceType == ReferenceType.CourtDecision) criterion = "-1";
			return criterion;
		}
		private string GetCriterionTwo(Reference reference)
		{
			string criterion = "";
			
			// Als zweites werden Fundstellen, welche keine Gerichtsentscheidungen sind, nach Autor geordnet.

			if (reference.ReferenceType != ReferenceType.CourtDecision)
			{
				IList<Person> authorsOrEditorsOrOrganizations = reference.AuthorsOrEditorsOrOrganizations as IList<Person>;
				if (authorsOrEditorsOrOrganizations == null) return "0";
				
				foreach (Person authorOrEditorOrOrganization in authorsOrEditorsOrOrganizations)
				{				
					if (!string.IsNullOrEmpty(authorOrEditorOrOrganization.LastNameForSorting))
					{
						criterion += authorOrEditorOrOrganization.LastNameForSorting;
					}
					else
					{
						criterion += authorOrEditorOrOrganization.LastName;
					}
					criterion += authorOrEditorOrOrganization.FirstName;
				}				
			}
			return criterion;
		}
		private string GetCriterionThree(Reference reference)
		{
			// Als drittes werden Gerichtsentscheidungen nach einem speziellen Schema sortiert.
			string criterion = "";
			if (reference.ReferenceType == ReferenceType.CourtDecision) criterion = GetCriterionThreeCourtDecision(reference);
			return criterion;
		}
		private string GetCriterionThreeCourtDecision(Reference reference)
		{
			if (reference.ReferenceType != ReferenceType.CourtDecision) return "0";
			string criterion = "0";

			IList<Person> courts = reference.Organizations as IList<Person>;
			if (courts == null) return "0";

			Person court = courts.FirstOrDefault();
			if (court == null) return "0";

			string theCourt = string.Empty;
			
			// Als drittes Sortierkriterium wird entweder die Abkürzung, oder wenn diese nicht vorhanden, der volle Name eines Gerichts herangezogen.

			if (!string.IsNullOrEmpty(court.Abbreviation))
			{
				if (!string.IsNullOrEmpty(theCourt)) theCourt += ", ";
				theCourt += court.Abbreviation;
			}
			else if (!string.IsNullOrEmpty(court.LastName))
			{
				if (!string.IsNullOrEmpty(theCourt)) theCourt += ", ";
				theCourt += court.LastName;
			}
			// GetCourtRanking ist eine eigene Methode weiter unten um die Gerichtshierarchie abzubilden
			criterion = GetCourtRanking(theCourt);
			
			return criterion;
		}
		private string GetCriterionFour(Reference reference)
		{
			// Als Viertes wird nach Datum sortiert, unabhängig ob nun Gericht oder nicht.
			string criterion = "";
			if (!String.IsNullOrEmpty(reference.Date.ToStringSafe())) criterion = reference.Date.ToStringSafe();
			else criterion = reference.YearResolved.ToStringSafe();
			return criterion;
		}
		private string GetCriterionFive(Reference reference)
		{
			// Als Fünftes wird für nicht-Gerichtsentscheidungen nach Titel sortiert.
			string criterion = "";
			if (reference.ReferenceType != ReferenceType.CourtDecision) criterion = reference.Title + reference.Subtitle;
			return criterion;
		}
		private string GetCourtRanking(string court)
		{
			if (string.IsNullOrEmpty(court)) return "zz";

			// Oberste Bundesgerichte		

			else if (court.Equals("BFH")) return "a" + court;
			else if (court.Equals("BGH")) return "a" + court;
			else if (court.Equals("BVerfG")) return "a" + court;
			else if (court.Equals("BVerwG")) return "a" + court;			

			// Landesverfassungsgerichte und Landesverwaltungsgerichtshöfe
			// Beachte den Unterschied zwischen Contains und Equals.
			// Es ist nicht nötig, jedes einzelne OVG, etc. aufzuführen,
			// da nur geguckt wird, ob das Wort OVG in der Abkürzung/dem vollen Namen des Gerichts vorkommt.

			else if (court.Equals("BayVGH")) return "b" + court;
			else if (court.Contains("OVG")) return "b" + court;
			else if (court.Contains("VGH")) return "b" + court;
			else if (court.Contains("VerfGH")) return "b" + court;

			// Finanzgerichte

			else if (court.Contains("FG")) return "c" + court;

			// Landgerichte

			else if (court.Contains("LG")) return "d" + court;

			// der ganze übrige Gedönsrat;
			
			else return "e" + court;

			return "zz";
		}	
	}
}
/ec3d8b6757f148551a3161b148378488

Foto
1

Danke fürs Überarbeiten! Soweit ich das beurteilen kann, werden die Entscheidungen nun richtig sortiert, aber das vor die Klammer ziehen gegenüber anderen Dokumententypen passt leider noch nicht.


/8c2691d617817a9e9036408c44896ef4

Foto
2

Offenbar ist beim Vergleich "-1" größer als 0. Das war mir voher auch noch nicht bewußt, dass dem so ist. Dann ändern wir einfach Zeile 84 und 85 wie folgt. a ist nämlich jedenfalls kleiner als b.

			string criterion = "b";
			if (reference.ReferenceType == ReferenceType.CourtDecision) criterion = "a";

Foto
1

Super, jetzt kommen die Entscheidungen zuerst. Leider scheint die Sortierung innerhalb aber noch nicht richtig zu klappen, denn manchmal passt sie nicht zur vorgegebenen Reihenfolge im Skript. Kleines Beispiel mit folgenden Entscheidungen:


/b11c9bbee5071830a20855356eb25b93


/8ef14f2b9d3dda02d642ef501730116d


Wenn ich die Kommentierung richtig verstehe, sollte doch der Code in den Zeilen 154-161 dafür sorgen, dass nach Datum sortiert wird. Dann müssten die beiden Entscheidungen doch aber dementsprechend aufeinanderfolgend zitiert werden und nicht so:


/078662247adeb93ef2923678875311cb

Um etwaige Datenfehler ausschließen zu können, habe ich in Citavi selber das Entscheidungsdatum gelöscht und erneut eingegeben, aber geholfen hat dies nicht. An der Reihenfolge änderte sich nur etwas, als ich bei der Entscheidung aus dem Jahr 1984 das Datum entfernte - plötzlich landete diese in der Fußnote ganz vorne. Woran kann das liegen?

Foto
2

Das liegt daran, dass die Sortierlogik das Datum als String vergleicht. Das funktioniert, wenn das Datum im ISO-Formst yyyy-mm-dd eingegeben wird. Wenn gewünscht ist, dass das Datum stattdessen im deutschen Format eingegeben werden kann (Ausgabe ist egal), wovon ich zwar abraten würde, was ich aber verstehen kann, müsste ich die Sortierlogik ändern.

Foto
1

Ah, das macht Sinn. Ich habe nun mit diesem Skript die Datumsangaben der Gerichtsentscheidungen umgestellt und nun klappt auch die Sortierung innerhalb der Entscheidungen nach dem Datum. Vielen vielen Dank! Das erspart mir noch einmal einiges an Zeit für manuelle Sortierungsumstellungen.

Foto