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 */ if (x == null || y == null) { return(0); } Reference xReference = x.Reference; Reference yReference = y.Reference; if (xReference == null || yReference == null) { return(0); } ReferenceType xReferenceType = xReference.ReferenceType; ReferenceType yReferenceType = yReference.ReferenceType; BibliographyCitation xBibliographyCitation = x as BibliographyCitation; BibliographyCitation yBibliographyCitation = y as BibliographyCitation; if (xBibliographyCitation == null || yBibliographyCitation == null) { return(0); } Template xTemplate = x.GetTemplateForCitation(); Template yTemplate = y.GetTemplateForCitation(); if (xTemplate == null || yTemplate == null) { return(0); } PersonFieldElement xPersonFieldElement = xTemplate.StructuralPersonFieldElement; PersonFieldElement yPersonFieldElement = yTemplate.StructuralPersonFieldElement; IEnumerable <Person> xPersons = xPersonFieldElement != null?xPersonFieldElement.GetPersonsCited(x) : Enumerable.Empty <Person>(); IEnumerable <Person> yPersons = yPersonFieldElement != null?yPersonFieldElement.GetPersonsCited(y) : Enumerable.Empty <Person>(); int xPersonsCount = 0; int yPersonsCount = 0; if (xPersons != null) { xPersonsCount = xPersons.Count(); } if (yPersons != null) { yPersonsCount = yPersons.Count(); } string xTitleForSorting = GetTitleForSorting(xReference); string yTitleForSorting = GetTitleForSorting(yReference); string xVolume = xReference.Volume; string yVolume = yReference.Volume; string xSeriesTitleForSorting = GetSeriesTitleForSorting(xReference); string ySeriesTitleForSorting = GetSeriesTitleForSorting(yReference); string xNumber = xReference.Number; string yNumber = yReference.Number; StringComparer defaultStringComparer = StringComparer.Create(_cultureForSorting, true); int personsCompareResult = 0; int personsCountCompareResult = 0; int titleCompareResult = 0; int seriesTitleCompareResult = 0; int volumeCompareResult = 0; int numberCompareResult = 0; int yearCompareResult = 0; int editionCompareResult = 0; if (xPersonsCount == 0 && yPersonsCount == 0) { //compare Titles titleCompareResult = xTitleForSorting.CompareTo(yTitleForSorting); if (titleCompareResult != 0) { return(titleCompareResult); } seriesTitleCompareResult = xSeriesTitleForSorting.CompareTo(ySeriesTitleForSorting); if (seriesTitleCompareResult != 0) { return(seriesTitleCompareResult); } } else if (xPersonsCount == 0 && yPersonsCount > 0) { //compare xTitle with yFirstAuthor titleCompareResult = defaultStringComparer.Compare(xTitleForSorting, yPersons.ElementAt(0).FullName); if (titleCompareResult != 0) { return(titleCompareResult); } } else if (xPersonsCount > 0 && yPersonsCount == 0) { //compare xFirstAuthor with yTitle titleCompareResult = defaultStringComparer.Compare(xPersons.ElementAt(0).FullName, yTitleForSorting); if (titleCompareResult != 0) { return(titleCompareResult); } } else { /* * 1. Single Author Group * 2. Author + Single Co-Author Group * 3. Author + Multiple-Co-Authors Group */ //compare by first author personsCompareResult = ComparePersons(xPersons.ElementAt(0), yPersons.ElementAt(0)); if (personsCompareResult != 0) { return(personsCompareResult); } //still here? then both have same first author if ((xPersonsCount == 1 && yPersonsCount > 1) || (xPersonsCount == 2 && yPersonsCount > 2)) { //x before y return(-1); } if ((xPersonsCount > 1 && yPersonsCount == 1) || (xPersonsCount > 2 && yPersonsCount == 2)) { //x after y return(1); } if (xPersonsCount == 2 && yPersonsCount == 2) { //compare by co-author personsCompareResult = ComparePersons(xPersons.ElementAt(1), yPersons.ElementAt(1)); if (personsCompareResult != 0) { return(personsCompareResult); } } //still here? //both have either exactly one identical author OR //both have exactly two identical authors OR //more than 2 authors with identical first author //we continue with year comparison } #region Year yearCompareResult = YearComparer.Compare(x, y); if (yearCompareResult != 0) { return(yearCompareResult); } #endregion Year #region Title titleCompareResult = defaultStringComparer.Compare(xTitleForSorting, yTitleForSorting); if (titleCompareResult != 0) { return(titleCompareResult); } #endregion Title #region Volume if ( xReferenceType == yReferenceType && xReference.HasCoreField(ReferenceTypeCoreFieldId.Volume) && yReference.HasCoreField(ReferenceTypeCoreFieldId.Volume) && HasFieldElement(xTemplate, ReferencePropertyId.Volume) && HasFieldElement(yTemplate, ReferencePropertyId.Volume) ) { NumberStringComparer volumeComparer = new NumberStringComparer() { CompareMode = NumberStringCompareMode.ByTextAndNumbersSegmentwise, UseAbsoluteNumbersOnly = true }; volumeCompareResult = volumeComparer.Compare(xVolume, yVolume); if (volumeCompareResult != 0) { return(volumeCompareResult); } } #endregion Volume #region Number if ( xReferenceType == yReferenceType && xReference.HasCoreField(ReferenceTypeCoreFieldId.Number) && yReference.HasCoreField(ReferenceTypeCoreFieldId.Number) && HasFieldElement(xTemplate, ReferencePropertyId.Number) && HasFieldElement(yTemplate, ReferencePropertyId.Number) ) { NumberStringComparer numberComparer = new NumberStringComparer() { CompareMode = NumberStringCompareMode.ByTextAndNumbersSegmentwise, UseAbsoluteNumbersOnly = true }; numberCompareResult = numberComparer.Compare(xNumber, yNumber); if (numberCompareResult != 0) { return(numberCompareResult); } } #endregion #region Edition if ( xReference.HasCoreField(ReferenceTypeCoreFieldId.Edition) && yReference.HasCoreField(ReferenceTypeCoreFieldId.Edition) && HasFieldElement(xTemplate, ReferencePropertyId.Edition) && HasFieldElement(yTemplate, ReferencePropertyId.Edition) ) { var xEdition = xReference.EditionNumberResolved; var yEdition = yReference.EditionNumberResolved; bool xHasEdition = !string.IsNullOrEmpty(xEdition); bool yHasEdition = !string.IsNullOrEmpty(yEdition); if (xHasEdition && yHasEdition) { NumberStringComparer editionComparer = new NumberStringComparer() { CompareMode = NumberStringCompareMode.ByTextAndNumbersSegmentwise, UseAbsoluteNumbersOnly = true }; editionCompareResult = editionComparer.Compare(xEdition, yEdition); if (editionCompareResult != 0) { return(editionCompareResult); } } else if (xHasEdition && !yHasEdition) //y before x { return(1); } else if (!xHasEdition && yHasEdition) //x before y { return(-1); } } #endregion return(0); }
//Version 2.6 Fix bug that text before and after abbreviation is changed for all organisations in an authoring group //Version 2.5 If only the abbreviation of an organisation is to be shown, any text before and/or after is suppressed //Version 2.4 If Citavi demands that output is suppressed (e.g. when collapsing multiple citations of same author), this script will terminate //Version 2.3 Uses OnBeforeFormatOrganization to switch organization name output ot abbreviation only //Version 2.2 Uses PersonFormatter of PersonFieldElement //Version 2.1 Confine repetition detection to organizational names only, so that ambiguity of individual persons' names can be handled correctly again by Citavi // Therefore, name of helper method was changed from GetPreviouslyMentionedPersons to GetPreviouslyMentionedOrganizations public IEnumerable <ITextUnit> GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled) { handled = false; if (citation == null || citation.Reference == null) { return(null); } if (componentPart == null || componentPart.Elements == null || !componentPart.Elements.Any()) { return(null); } PlaceholderCitation placeholderCitation = citation as PlaceholderCitation; if (placeholderCitation == null) { return(null); } if (placeholderCitation.YearOnly) { return(null); } PersonFieldElement personFieldElement = componentPart.Elements[0] as PersonFieldElement; if (personFieldElement == null) { return(null); } if (personFieldElement.SuppressOutput) { return(null); } IEnumerable <Person> persons = personFieldElement.GetPersonsCited(citation); if (persons == null || !persons.Any()) { return(null); } if (!persons.Any(p => p.IsOrganization)) { return(null); } IEnumerable <Person> previouslyMentionedOrganizations = GetDistinctPreviouslyMentionedOrganizations(citation); if (previouslyMentionedOrganizations == null || !previouslyMentionedOrganizations.Any()) { return(null); } var textBeforeAbbreviation = personFieldElement.OrganizationTextBeforeAbbreviation.Text; var textAfterAbbreviation = personFieldElement.OrganizationTextAfterAbbreviation.Text; BeforeFormatOrganizationEventArgs b; personFieldElement.PersonFormatter.BeforeFormatOrganization += (sender, e) => { b = (BeforeFormatOrganizationEventArgs)e; if (b.Organization == null) { return; } if (previouslyMentionedOrganizations.Contains(b.Organization)) { b.NameOrder = OrganizationNameOrder.AbbreviationOnly; b.TextBeforeAbbreviation = null; b.TextAfterAbbreviation = null; } else { b.NameOrder = personFieldElement.OrganizationNameOrder; b.TextBeforeAbbreviation = textBeforeAbbreviation; b.TextAfterAbbreviation = textAfterAbbreviation; } }; return(null); }