Ejemplo n.º 1
0
        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);
        }